APUE函数笔记二: 文件与目录

58 篇文章 0 订阅
49 篇文章 0 订阅

第四章  文件与目录:

#include <sys/stat.h>
int stat(const char * restrict pathname, struct stat * restrict buf);
int fstat(int filedes, struct stat * buf);
int lstat(const char * restrict pathname, struct stat * restrict buf);

#include <sys/stat.h>
S_ISREG(mode), S_ISDIR(mode), S_ISCHR(mode), S_ISBLK(mode),
S_ISFIFO(mode), S_ISLNK(mode), S_ISSOCK(mode)
    #define S_ISXXX(mode)   (((mode) & S_IFMT) == S_IFXXX)

#include <unistd.h>
int access(const char * pathname, int mode);
    mode:
        R_OK, W_OK, X_OK, F_OK

#include <sys/stat.h>
mode_t umask(mode_t cmask);
    cmask:
        S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR
        S_IRWXG, S_IRGRP, S_IWGRP, S_IXGRP
        S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH

#include <sys/stat.h>
int chmod(const char * pathname, mode_t mode);
int fchmod(int filedes, mode_t mode);
    mode:
        S_ISUID, S_ISGID, (S: set)
        S_ISVTX, (SVTX: save text)
        S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR
        S_IRWXG, S_IRGRP, S_IWGRP, S_IXGRP
        S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH

#include <unistd.h>
int chown(const char * pathname, uid_t owner, gid_t group);
int fchown(int filedes, uid_t owner, gid_t group);
int lchown(const char * pathname, uid_t owner, gid_t group);

#include <unistd.h>
int truncate(const char * pathname, off_t length);
int ftruncate(int filedes, off_t length);

#include <unistd.h>
int link(const char * existingpath, const char * newpath);
int unlink(const char * pathname);
    it is hard-link

#include <stdio.h>
int remove(const char * pathname);
    same as: unlink(file) and rmdir(directory)

#include <stdio.h>
int rename(const char * oldname, const char * newname);

#include <unistd.h>
int symlink(const char * actualpath, const char * sympath);
    it is soft-link

#include <unistd.h>
ssize_t readlink(const char * restrict pathname, char * restrict buf, 
                 size_t bufsize);
    it is soft-link, readlink includes open, read, close operations

#include <utime.h>
int utime(const char * pathname, const struct utimbuf * times);

#include <sys/stat.h>
int mkdir(const char * pathname, mode_t mode);

#include <unistd.h>
int rmdir(const char * pathname);

#include <dirent.h>
DIR * opendir(const char * pathname);
struct dirent * readdir(DIR * dp);
void rewinddir(DIR * dp);
int closedir(DIR * dp);
long telldir(DIR * dp);
void seekdir(DIR * dp, long loc);

#include <unistd.h>
int chdir(const char * pathname);
int fchdir(int filedes);

#include <unistd.h>
char * getcwd(char * buf, size_t size);

#include <sys/types.h>      /* BSD */
#include <sys/sysmacros.h>  /* Linux */
#include <sys/mkdev.h>      /* Solaris */
int major(dev_t dev);
int minor(dev_t dev);

示例:

#include <stdio.h>
#include <sys/stat.h>

int
main(int argc, char * argv[])
{
    int         i;
    struct stat buf;
    char      * ptr;

    for (i = 1; i < argc; ++i) {
        printf("%s: ", argv[i]);
        if (lstat(argv[i], &buf) < 0) {
            printf("lstat error\n");
            continue;
        }

        if (S_ISREG(buf.st_mode)) {
            ptr = "regular";
        }
        else if (S_ISDIR(buf.st_mode)) {
            ptr = "directory";
        }
        else if (S_ISCHR(buf.st_mode)) {
            ptr = "character special";
        }
        else if (S_ISBLK(buf.st_mode)) {
            ptr = "block special";
        }
        else if (S_ISFIFO(buf.st_mode)) {
            ptr = "fifo";
        }
        else if (S_ISLNK(buf.st_mode)) {
            ptr = "link";
        }
        else if (S_ISSOCK(buf.st_mode)) {
            ptr = "socket";
        }
        else {
            ptr = "*** unknown mode ***";
        }
        printf("%s\n", ptr);
    }
    
    return 0;
}

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

int
main(int argc, char * argv[])
{
    if (argc != 2) {
        printf("usage: ./a.out <pathname>\n");
        return -1;
    }

    if (access(argv[1], R_OK) < 0) {
        printf("access error for %s\n", argv[1]);
    }
    else {
        printf("read access ok\n");
    }

    if (open(argv[1], O_RDONLY) < 0) {
        printf("open error for %s\n", argv[1]);
    }
    else {
        printf("open for reading ok\n");
    }

    return 0;
}

#include <stdio.h>
#include <fcntl.h>

#define RWRWRW (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)

int
main(int argc, char * argv[])
{
    umask(0);
    if (creat("foo", RWRWRW) < 0) {
        printf("creat error for foo\n");
    }

    umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    if (creat("bar", RWRWRW) < 0) {
        printf("creat error for bar\n");
    }

    return 0;
}

#include <stdio.h>
#include <sys/stat.h>

int
main(int argc, char * argv[])
{
    struct stat buf;

    if (stat("foo", &buf) < 0) {
        printf("stat foo error\n");
    }
    else {
        if (chmod("foo", (buf.st_mode & ~S_IXGRP) | S_ISGID) < 0) {
            printf("chmod foo error\n");
        }
    }

    if (chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) {
        printf("chmod bar error\n");
    }

    return 0;
}

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

int
main(int argc, char * argv[])
{
    if (creat("tempfile", S_IRWXU) < 0) {
        printf("open error\n");
        return -1;
    }

    if (unlink("tempfile") < 0) {
        printf("unlink error\n");
        return -1;
    }
    printf("file unlinked\n");

    sleep(15);
    printf("done\n");

    return 0;
}

#include <stdio.h>
#include <fcntl.h>
#include <utime.h>

int
main(int argc, char * argv[])
{
    int            i;
    int            fd;
    struct stat    statbuf;
    struct utimbuf timebuf;

    for (i = 1; i < argc; ++i) {
        if (stat(argv[i], &statbuf) < 0) {
            printf("%s: stat error\n", argv[i]);
            continue;
        }
        if ((fd = open(argv[i], O_RDWR | O_TRUNC)) < 0) {
            printf("%s: open error\n", argv[i]);
            continue;
        }
        close(fd);
        timebuf.actime  = statbuf.st_atime;
        timebuf.modtime = statbuf.st_mtime;
        if (utime(argv[i], &timebuf) < 0) {
            printf("%s: utime error\n", argv[i]);
        }
    }

    return 0;
}


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

int
main(int argc, char * argv[])
{
    if (chdir("/tmp") < 0) {
        printf("chdir failed\n");
        return -1;
    }
    printf("chdir to /tmp succeeded\n");
    return 0;
}

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

int
main(int argc, char * argv[])
{
    char buf[PATH_MAX + 1];

    if (chdir("/usr/local/etc") < 0) { /* same result with "/usr/local/etc/" */
        printf("chdir failed\n");
        return -1;
    }

    if (getcwd(buf, PATH_MAX + 1) == NULL) {
        printf("getcwd failed\n");
        return -1;
    }

    printf("cwd = %s\n", buf); /* cwd = /usr/local/etc */
    return 0;
}

#include <stdio.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>

int
main(int argc, char * argv[])
{
    int         i;
    int         isblk;
    struct stat buf;

    for (i = 1; i < argc; ++i) {
        printf("%s: ", argv[i]);
        if (stat(argv[i], &buf) < 0) {
            printf("stat error\n");
            continue;
        }

        printf("dev = %d/%d", major(buf.st_dev), minor(buf.st_dev));
        isblk = 0;
        if (S_ISCHR(buf.st_mode) || (S_ISBLK(buf.st_mode) && (isblk = 1))) {
            printf(" (%s) rdev = %d/%d", isblk ? "block" : "character",
                   major(buf.st_rdev), minor(buf.st_rdev));
        }
        putchar('\n');
    }

    return 0;
}

#include <stdio.h>
#include <sys/stat.h>

int
main(int argc, char * argv[])
{
    int         i;
    char      * ptr;
    struct stat bufstat;

    for (i = 1; i < argc; ++i) {
        printf("%s :", argv[i]);
        if (lstat(argv[i], &bufstat) < 0) {
            printf("lstat error\n");
            continue;
        }

        switch (bufstat.st_mode & S_IFMT) {
            case S_IFREG: ptr = "regular"; break;
            case S_IFDIR: ptr = "directory"; break;
            case S_IFCHR: ptr = "character special"; break;
            case S_IFBLK: ptr = "block special"; break;
            case S_IFIFO: ptr = "fifo"; break;
            case S_IFLNK: ptr = "link"; break;
            case S_IFSOCK: ptr = "socket"; break;
            default: ptr = "*** unknown mode ***"; break;
        }
        printf("%s\n", ptr);
    }

    return 0;
}

#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <limits.h>
#include <sys/stat.h>

#define FTW_F   1
#define FTW_D   2
#define FTW_DNR 3
#define FTW_NS  4

static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;
char fullpath[PATH_MAX + 1];

int
myfunc(const char * pathname, const struct stat * statptr, int type)
{
    switch (type) {
        case FTW_F:
            switch (statptr->st_mode & S_IFMT) {
                case S_IFREG: ++nreg; break;
                case S_IFBLK: ++nblk; break;
                case S_IFCHR: ++nchr; break;
                case S_IFIFO: ++nfifo; break;
                case S_IFLNK: ++nslink; break;
                case S_IFSOCK: ++nsock; break;
                case S_IFDIR: printf("for S_IFDIR for %s\n", pathname); break;
                default: break;
            }
            break;
        case FTW_D:
            ++ndir;
            break;
        case FTW_DNR:
            printf("cannot read directory %s\n", pathname);
            break;
        case FTW_NS:
            printf("stat error for %s\n", pathname);
            break;
        default:
            printf("unknown type %d for pathname %s", type, pathname);
            break;
    }

    return 0;
}

int
dopath()
{
    struct stat     statbuf;
    struct dirent * dirp;
    DIR           * dp;
    int             ret;
    char          * ptr;

    if (lstat(fullpath, &statbuf) < 0) {
        return (myfunc(fullpath, &statbuf, FTW_NS));
    }

    if (!S_ISDIR(statbuf.st_mode)) {
        return (myfunc(fullpath, &statbuf, FTW_F));
    }

    if ((ret = myfunc(fullpath, &statbuf, FTW_D)) != 0) {
        return ret;
    }

    ptr = fullpath + strlen(fullpath);
    ptr[0] = '/';
    ptr[1] = '\0';

    if ((dp = opendir(fullpath)) == NULL) {
        return (myfunc(fullpath, & statbuf, FTW_DNR)); 
    }

    while ((dirp = readdir(dp)) != NULL) {
        if (strcmp(dirp->d_name, ".") == 0 ||
            strcmp(dirp->d_name, "..") == 0) {
            continue;
        }
        strcpy(ptr + 1, dirp->d_name);
        if ((ret = dopath()) != 0) {
            break;
        }
    }

    ptr[0] = '\0';

    if (closedir(dp) < 0) {
        printf("cannot close directory %s\n", fullpath);
    }

    return ret;
}

typedef Myfunc(const char *, const struct stat *, int);

int
myftw(char * pathname, Myfunc * func)
{
    strcpy(fullpath, pathname);
    return (dopath(fullpath));
} 

int
main(int argc, char * argv[])
{
    int ret;

    if (argc != 2) {
        printf("usage: ./a.out <start-pathname>\n");
        return -1;
    }

    ret = myftw(argv[1], myfunc);

    ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
    if (ntot == 0) {
        ntot = 1;
    }
    printf("regular files  = %7ld, %5.2f %%\n", nreg, nreg*100.0/ntot);
    printf("directory      = %7ld, %5.2f %%\n", ndir, ndir*100.0/ntot);
    printf("block special  = %7ld, %5.2f %%\n", nblk, nblk*100.0/ntot);
    printf("char special   = %7ld, %5.2f %%\n", nchr, nchr*100.0/ntot);
    printf("FIFOs          = %7ld, %5.2f %%\n", nfifo, nfifo*100.0/ntot);
    printf("symbolic links = %7ld, %5.2f %%\n", nslink, nslink*100.0/ntot);
    printf("sockets        = %7ld, %5.2f %%\n", nsock, nsock*100.0/ntot);

    return 0;
}

#include <stdio.h>
#include <dirent.h>
#include <limits.h>
#include <sys/stat.h>

#define FTW_F   1
#define FTW_D   2
#define FTW_DNR 3
#define FTW_NS  4

static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;

int
myfunc(const char * pathname, const struct stat * statptr, int type)
{
    switch (type) {
        case FTW_F:
            switch (statptr->st_mode & S_IFMT) {
                case S_IFREG: ++nreg; break;
                case S_IFBLK: ++nblk; break;
                case S_IFCHR: ++nchr; break;
                case S_IFIFO: ++nfifo; break;
                case S_IFLNK: ++nslink; break;
                case S_IFSOCK: ++nsock; break;
                case S_IFDIR: printf("for S_IFDIR for %s\n", pathname); break;
                default: break;
            }
            break;
        case FTW_D:
            ++ndir;
            break;
        case FTW_DNR:
            printf("cannot read directory %s\n", pathname);
            break;
        case FTW_NS:
            printf("stat error for %s\n", pathname);
            break;
        default:
            printf("unknown type %d for pathname %s", type, pathname);
            break;
    }

    return 0;
}

int
dopath(const char * pathname)
{
    struct stat     statbuf;
    struct dirent * dirp;
    DIR           * dp;
    int             ret;
    char          * ptr;
    char            cwd[PATH_MAX + 1];

    if (lstat(pathname, &statbuf) < 0) {
        return (myfunc(pathname, &statbuf, FTW_NS));
    }

    if (!S_ISDIR(statbuf.st_mode)) {
        return (myfunc(pathname, &statbuf, FTW_F));
    }

    if ((ret = myfunc(pathname, &statbuf, FTW_D)) != 0) {
        return ret;
    }

    if ((dp = opendir(pathname)) == NULL) {
        return (myfunc(pathname, & statbuf, FTW_DNR)); 
    }

    while ((dirp = readdir(dp)) != NULL) {
        if (strcmp(dirp->d_name, ".") == 0 ||
            strcmp(dirp->d_name, "..") == 0) {
            continue;
        }
        getcwd(cwd, PATH_MAX + 1);
        chdir(pathname);
        ret = dopath(dirp->d_name);
        chdir(cwd);
        if (ret != 0) {
            break;
        }
    }

    if (closedir(dp) < 0) {
        printf("cannot close directory %s\n", pathname);
    }

    return ret;
}

int
main(int argc, char * argv[])
{
    int ret;

    if (argc != 2) {
        printf("usage: ./a.out <start-pathname>\n");
        return -1;
    }

    ret = dopath(argv[1]);

    ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
    if (ntot == 0) {
        ntot = 1;
    }
    printf("regular files  = %7ld, %5.2f %%\n", nreg, nreg*100.0/ntot);
    printf("directory      = %7ld, %5.2f %%\n", ndir, ndir*100.0/ntot);
    printf("block special  = %7ld, %5.2f %%\n", nblk, nblk*100.0/ntot);
    printf("char special   = %7ld, %5.2f %%\n", nchr, nchr*100.0/ntot);
    printf("FIFOs          = %7ld, %5.2f %%\n", nfifo, nfifo*100.0/ntot);
    printf("symbolic links = %7ld, %5.2f %%\n", nslink, nslink*100.0/ntot);
    printf("sockets        = %7ld, %5.2f %%\n", nsock, nsock*100.0/ntot);

    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值