linux系统编程之文件与IO:实现ls -l功能

本文利用如下系统调用实现ls -l命令的功能:shell

 

1,lstat:得到文件状态,app

2,getpwuid:ide

#include <pwd.h>ui

struct passwd *getpwuid(uid_t uid);spa

描述:code

The getpwuid() function returns a pointer to a structure containing the broken-out fields of the record in the password database  that  matches the user ID uid.blog

返回值:
The passwd structure is defined in <pwd.h> as follows:get

    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;      /* real name */
        char   *pw_dir;        /* home directory */
        char   *pw_shell;      /* shell program */
    };string

示例:it

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <pwd.h>

#define ERR_EXIT(m) \
    do \
    { \
        perror(m); \
        exit(EXIT_FAILURE); \
    } while(0)

int main(void)
{
    uid_t uid;
    struct passwd *pw;
    uid = getuid();
    printf("current user id :%d\n",uid);
    if((pw = getpwuid(uid)) == NULL)
        ERR_EXIT("getpwuid error");
    printf("username:%s\n",pw->pw_name);
    printf("user passwd:%s\n",pw->pw_passwd);
    printf("user ID:%d\n",pw->pw_uid);
    printf("group ID:%d\n",pw->pw_gid);
    //printf("real name:%s\n",pw->pw_gecos);
    printf("home directory:%s\n",pw->pw_dir);
    printf("shell program:%s\n",pw->pw_shell);
    return 0;
}

运行结果:

QQ20130710185533_thumb

3,getgrgid:

#include <grp.h>

struct group *getgrnam(const char *name);//根据组名得到组信息

struct group *getgrgid(gid_t gid);//根据组ID得到组信息

描述:

The getgrnam() function returns a pointer to a structure containing the broken-out  fields of the record in the group database (e.g., the local group file /etc/group, NIS, and LDAP) that matches the group name name.

The getgrgid() function returns a pointer to a structure containing the broken-out fields of the record in the group database that matches  thegroup ID gid.

返回值:

The group structure is defined in <grp.h> as follows:

    struct group {
        char   *gr_name;       /* group name */
        char   *gr_passwd;     /* group password */
        gid_t   gr_gid;        /* group ID */
        char  **gr_mem;        /* group members */
    };

 

4,readlink:读取软连接文件的内容

#include <unistd.h>

ssize_t readlink(const char *path, char *buf, size_t bufsiz);

描述:

DESCRIPTION
       readlink() places the contents of the symbolic link path in the  buffer
       buf,  which has size bufsiz.  readlink() does not append a null byte to
       buf.  It will truncate the contents (to a length of bufsiz characters),
       in case the buffer is too small to hold all of the contents.

RETURN VALUE
       On  success,  readlink() returns the number of bytes placed in buf.  On
       error, -1 is returned and errno is set to indicate the error.

示例:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#define ERR_EXIT(m) \
    do \
    { \
        perror(m); \
        exit(EXIT_FAILURE); \
    } while(0)
int main(int argc,char **argv)
{
    if(argc != 2){
        fprintf(stderr,"usage:%s linkfile", argv[0]);
        exit(EXIT_FAILURE);
    }

    char buf[1024];
    
    if(readlink(argv[1],buf,1024) ==-1)
        ERR_EXIT("readlink error");
    printf("the content of %s are: %s\n",argv[1],buf);
    return 0;
}

运行结果:

QQ20130710183748_thumb

如今利用相关的系统调用实现ls –l功能:

程序以下:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <time.h>
#include <pwd.h> 
#include <grp.h> 
#include <libgen.h>


#define ERR_EXIT(m) \
    do\
    {\
        perror(m);\
        exit(EXIT_FAILURE);\
    }while(0)\

void lsdir(char *dirname);
void lsfile(char *filename);
void lsfile(char *filename);
char getFileType(struct stat *fstat);
void getFilePerm(struct stat *st, char *perm);

int main(int argc,char **argv)
{

    if(argc != 2){
        fprintf(stderr,"usage:%s [filepath]\n",argv[0]);
        exit(EXIT_FAILURE);
    }
    struct stat fstat;
    if(lstat(argv[1],&fstat) == -1)
        ERR_EXIT("STAT ERROR");

    if(S_ISDIR(fstat.st_mode))
    {
        lsdir(argv[1]);
    }
    else{
        lsfile(argv[1]);
    }
    return 0;
}

void lsdir(char *dirname)
{
    DIR *dir;
    char filename[100] = {0};
    dir =opendir(dirname); 
    if(dir == NULL)
        ERR_EXIT("opendir error");
    struct dirent *dentry;
    while((dentry = readdir(dir)) != NULL)
    {
        
        char *fname;
        fname = dentry->d_name;
        if(strncmp(fname,".",1) == 0)
            continue;
        sprintf(filename,"%s/%s",dirname,fname);
        lsfile(filename);
    }

    closedir(dir);

}

//-rw-r--r--.   1            zxy        zxy        2586        Jul 10 17:00    ls.c
//类型及权限  硬连接数        拥有者    所属组    文件大小    建立时间        文件名
void lsfile(char *filename)
{
    struct stat tmpstat;
    if(lstat(filename,&tmpstat) == -1)
        ERR_EXIT("STAT ERROR");
    char buf[11]= {0};
    strcpy(buf,"----------");
    char type;
    type = getFileType(&tmpstat);
    char *bname = basename(filename);
    buf[0] = type;
    if(type == 'l'){
        char content[1024];
        if(readlink(filename,content,1024) == -1)
            ERR_EXIT("readlink error");
        sprintf(bname,"%s -> %s",bname,content);

    }
    getFilePerm(&tmpstat,buf);
    struct tm *ftime;
    ftime = localtime(&tmpstat.st_mtime);
    
    printf("%s %d %s %s %10ld %02d %02d %02d:%02d %s\n",
        buf,tmpstat.st_nlink,
        getpwuid(tmpstat.st_uid)->pw_name,
        getgrgid(tmpstat.st_gid)->gr_name,
        tmpstat.st_size,
        ftime->tm_mon+1,
        ftime->tm_mday,
        ftime->tm_hour,
        ftime->tm_min,
        bname);

}

//得到文件类型
char getFileType(struct stat *st)
{
    char type = '-';
    switch (st->st_mode  & S_IFMT)
    {
        case S_IFSOCK:
        type = 's';
                break;
        case S_IFLNK:
        type = 'l';
                break;
        case S_IFREG:
        type = '-';
                break;
        case S_IFBLK:
        type = 'b';
                break;
        case S_IFDIR:
        type = 'd';
                break;
        case S_IFCHR:
        type = 'c';
                break;
        case S_IFIFO:
        type = 'p';
                break;
    }
    return type;
}

//得到文件访问权限
void getFilePerm(struct stat *st, char *perm)
{
    mode_t mode = st->st_mode;
    if (mode & S_IRUSR)
        perm[1] = 'r';
    if (mode & S_IWUSR)
        perm[2] = 'w';
    if (mode & S_IXUSR)
        perm[3] = 'x';
    if (mode & S_IRGRP)
        perm[4] = 'r';
    if (mode & S_IWGRP)
        perm[5] = 'w';
    if (mode & S_IXGRP)
        perm[6] = 'x';
    if (mode & S_IROTH)
        perm[7] = 'r';
    if (mode & S_IWOTH)
        perm[8] = 'w';
    if (mode & S_IXOTH)
        perm[9] = 'x';
}

运行结果:

QQ20130710221918_thumb

相关文章
相关标签/搜索