时间获取和文件属性和权限获取实现 ‘ls -l’ 功能

一,时间获取:

    1.time 

      time_t time(time_t *tloc);
      功能:
        返回1970-1-1到现在的秒数(格林威治时间)
      参数:
        tloc:存放秒数空间首地址
      返回值:
        成功返回秒数(用 time_t 类型的变量接)
        失败返回-1 

    2.localtime  --  参数放入秒数空间的首地址,返回一个结构体时间信息

      struct tm *localtime(const time_t *timep);
      功能:
        将秒数转换为本地时间
      参数:
        timep:存放秒数空间首地址
      返回值:
        成功返回结构体时间(用struct tm 结构体类型的变量来接)
        失败返回NULL

        struct tm {
            int tm_sec;    /* Seconds (0-60) */       //秒
            int tm_min;    /* Minutes (0-59) */        //分
            int tm_hour;   /* Hours (0-23) */          //时
            int tm_mday;   /* Day of the month (1-31) */  //日  tm_mday成员
            int tm_mon;    /* Month (0-11) */          //0-11 代表十二个月
            int tm_year;   /* Year - 1900 */             //获得的年份是当前年份-1900
            int tm_wday;   /* Day of the week (0-6, Sunday = 0) */
            int tm_yday;   /* Day in the year (0-365, 1 Jan = 0) */
            int tm_isdst;  /* Daylight saving time */
        };

    3.mktime

      time_t mktime(struct tm *tm);
      功能:
        将本地时间转换为秒数

获取时间t(秒数),转换为本地时间 ; 用本地时间得出前一天的当前时间:

int main(void)
{
	time_t t;                     //定义一个存放time返回值的空间
	struct tm *ptm = NULL;
    struct tm tmp;      //定义了一个time结构体的变量存放时间

	tmp.tm_year = 2024-1900;     //依次去给每个结构体成员赋值
	tmp.tm_mon = 2-1;
	tmp.tm_mday = 20;
	tmp.tm_hour = 11;
	tmp.tm_min = 22;
	tmp.tm_sec = 30;
	
	t = mktime(&tmp);        //时间换秒
	t -= 86400;

	//time(&t);    //获取当前时间t
	ptm = localtime(&t);   //秒换时间戳

	printf("%04dd-%02d-%02d %02d:%02d:%02d\n",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);

	return 0;
}

二,文件属性和权限的获取:

 1.stat

      int stat(const char *pathname, struct stat *statbuf);
      功能:
        将pathname对应的文件信息放入statbuf中
      参数:
        pathname:文件路径字符串的首地址
        statbuf:存放文件信息空间的首地址
      返回值:
        成功返回0 
        失败返回-1 

    struct stat {
        dev_t     st_dev;         /* ID of device containing file */
        ino_t     st_ino;         /* Inode number */
        mode_t    st_mode;        /* File type and mode */
        nlink_t   st_nlink;       /* Number of hard links */
        uid_t     st_uid;         /* User ID of owner */
        gid_t     st_gid;         /* Group ID of owner */
        dev_t     st_rdev;        /* Device ID (if special file) */
        off_t     st_size;        /* Total size, in bytes */
        blksize_t st_blksize;     /* Block size for filesystem I/O */
        blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */

判断文件的类型通过下列函数判断:
The following mask values are defined for the file type:

           S_IFMT     0170000   bit mask for the file type bit field

           S_IFSOCK   0140000   socket
           S_IFLNK    0120000   symbolic link
           S_IFREG    0100000   regular file
           S_IFBLK    0060000   block device

           S_IFDIR    0040000   directory
           S_IFCHR    0020000   character device
           S_IFIFO    0010000   FIFO
 

        /* Since Linux 2.6, the kernel supports nanosecond
            precision for the following timestamp fields.
            For the details before Linux 2.6, see NOTES. */

        struct timespec st_atim;  /* Time of last access */
        struct timespec st_mtim;  /* Time of last modification */
        struct timespec st_ctim;  /* Time of last status change */

    #define st_atime st_atim.tv_sec      /* Backward compatibility */
    #define st_mtime st_mtim.tv_sec
    #define st_ctime st_ctim.tv_sec
    };

    /etc/passwd   口令文件
    /etc/group    组信息文件

    2.getpwuid 

      struct passwd *getpwuid(uid_t uid);
      功能:
        通过UID获得对应的用户信息
      参数:
        uid:用户的ID号
      返回值:
        成功返回包含用户信息的结构体
        失败返回NULL

    struct passwd {
        char   *pw_name;       /* username */
        char   *pw_passwd;     /* user password */
        uid_t   pw_uid;        /* user ID */
        gid_t   pw_gid;        /* group ID */
        char   *pw_gecos;      /* user information */
        char   *pw_dir;        /* home directory */
        char   *pw_shell;      /* shell program */
    };

    3.getgrgid

      struct group *getgrgid(gid_t gid);
      功能:
        通过组ID获得组信息
      参数:
        gid:组的ID号
      返回值:
        成功返回包含组信息的结构体
        失败返回NULL
    
    struct group {
        char   *gr_name;        /* group name */
        char   *gr_passwd;      /* group password */
        gid_t   gr_gid;         /* group ID */
        char  **gr_mem;         /* NULL-terminated array of pointers
                                    to names of group members */
    };

    4.readlink

      ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);
      功能:
        读取连接文件本身的内容
      参数:
        pathname:链接文件的路径
        buf:存放数据空间首地址
        bufsiz:最大存放数据字节数
      返回值:
        成功返回读到字节个数
        失败返回-1 

5.实现ls -l 目录 的功能:

int main(int argc,const char *argv[])      //ls -l 功能相同的函数
{
	struct stat buf;                   //定义struct stat buf结构体,将lstat的文件信息放进
	int ret = 0;
	struct passwd *pwd = NULL;         //接收用户结构体信息
	struct group *grp = NULL;       //接收组名的结构体信息
	struct tm *ptm = NULL;           //接收文件结构体信息中的 文件创建时间(buf.) 的差值 秒
	char *mon[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
	                                   //定义一个指针数组存放每月份对应的英文名字
	char tmpbuff[1024]={0};     //若识别为链接文件,将其中的内容放进,方便打印出需要的格式

	if(argc!=2)
	{
		fprintf(stderr,"Usage:./a.out filename\n");
		return -1;
	}

	ret = lstat (argv[1],&buf);    //l+stat 可以添加识别功能-链接文件  
	if(ret == -1)
	{
		perror("fail to stat");
		return -1;
	}

	switch(buf.st_mode & S_IFMT)          //打印文件类型
	{
	 case S_IFDIR:putchar('d');break;
	 case S_IFSOCK:putchar('s');break;
	 case S_IFLNK:putchar('l');break;
	 case S_IFREG:putchar('-');break;
	 case S_IFBLK:putchar('b');break;
	 case S_IFCHR:putchar('c');break;
	 case S_IFIFO:putchar('p');break;
	}

	buf.st_mode & S_IRUSR? putchar('r'):putchar('-');   //打印权限
	buf.st_mode & S_IWUSR? putchar('w'):putchar('-');
	buf.st_mode & S_IXUSR? putchar('x'):putchar('-');
	
	buf.st_mode & S_IRGRP? putchar('r'):putchar('-');
	buf.st_mode & S_IWGRP? putchar('w'):putchar('-');
	buf.st_mode & S_IXGRP? putchar('x'):putchar('-');
	
	buf.st_mode & S_IROTH? putchar('r'):putchar('-');
	buf.st_mode & S_IWOTH? putchar('w'):putchar('-');
	buf.st_mode & S_IXOTH? putchar('x'):putchar('-');

	printf(" %ld",buf.st_nlink);     //打印硬链接的个数

	pwd = getpwuid(buf.st_uid);    //打印用户名。//buf.st_uid 返回的是一个id,用getpwuid通过id接收一个用户信息的结构体
	if(pwd == NULL)
	{
		printf(" %d",buf.st_uid);  //如果接受不到打印id
	}else
	{
		printf(" %s",pwd->pw_name);//接收到打印pwd指向的结构体中的name成员的内容(用户名字)
	}


	grp = getgrgid(buf.st_gid);    //打印组名。//buf.st_gid 返回的是一个id,用getgrgid通过id接收一个组员的结构体
	if(grp == NULL)
	{
		printf(" %d",buf.st_gid);  //如果接收不到打印id
	}else
	{
		printf(" %s",grp->gr_name);//接收到打印grp指向的结构体中的name成员的内容(组员名字)
	}

	printf(" %ld", buf.st_size); //打印文件的大小

	ptm = localtime(&buf.st_mtime);//接收文件创建的时间(差值 秒)  整型需要取地址
	printf(" %s %d %d:%d", mon[ptm->tm_mon], ptm->tm_mday, ptm->tm_hour, ptm->tm_min);
	                                 //打印文件的月份,文件的天,时,分
	
	printf(" %s", argv[1]);    //打印文件名

	if (S_ISLNK(buf.st_mode))       //判断文件是否为链接文件
	{
		readlink(argv[1], tmpbuff, sizeof(tmpbuff));  //d读取链接文件本身的内容,存放到tmpbuff
		printf(" -> %s", tmpbuff);
	}

	putchar('\n');

	return 0;

}

三,软连接和硬链接:

   1.软连接(符号链接)

       通过文件名链接,所有能够看到的连接文件均为软连接文件

        ln -s file.txt a.txt 

    2.硬链接

       通过文件对应的inode节点链接     
        ln file.txt b.txt 

  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值