第四章 文件与目录:
#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;
}