1.函数stat,fstat,lstat,fststat
int stat(const char *restrict pathname, struct stat *restrict buf);
int fstat(int fd, struct stat *buf);
2.文件类型:
普通文件,目录文件,块特殊文件,字符特殊文件(系统中的设备属于这两种),FIFO,套接字,符号链接。
代码是查看文件类型。
#include "apue.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)){
err_ret("lstat error");
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_ISSOCK(buf.st_mode))
ptr = "socket";
else if(S_ISLNK(buf.st_mode))
ptr = "symbolic link";
else
ptr = "** unknown mode **";
printf("%s\n", ptr);
}
exit(0);
}
3.access和faccessat(按照实际用户ID和实际组ID进行访问权限设置)
int access(const char* pathname, int mode);
4.umask函数为进程设置文件模式创建屏蔽字
mode_t umask(mode_t cmask)
#include "apue.h"
#include <fcntl.h>
#define RWRWRW (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
int main(void)
{
umask(0);
if(creat("foo", RWRWRW) < 0)
err_sys("creat error foo");
umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if(creat("bar", RWRWRW) < 0)
err_sys("creat error bar");
exit(0);
}
int chmod(const char* pathname, mode_t mode);
#include "apue.h"
int main(void)
{
struct stat statbuf;
if(stat("foo", &statbuf) < 0)
err_sys("stat error foo");
if(chmod("foo", (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0)
err_sys("chmod error foo");
if(chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0)
err_sys("chmod error bar");
exit(0);
}
int chown(const char* pathname, uid_t owner, gid_t group);
7.文件截断。(truncate和ftruncate函数)
int truncate(const char* pathname, off_t length);
将文件长度截断为length,如果长度大于length,则超过的部分就不能被访问;如果长度小于length,则会形成空洞。
8.link,linkat,unlink,unlinkat,remove
创建一个现有文件的链接
int link(const char* existingpath, const char* newpath);
删除一个现有的目录项
int unlink(const char* pathname);
9.rename和renameat函数
对文件或者目录进行重命名操作。
int rename(const char* oldname, const char* newname);
10.创建和读取符号链接
int symlink(const char* actualpath, const char* sympath); //创建了一个指向actualpath的新目录项sympath。
打开符号链接
ssize_t readlink(const char* restrict pathname, char* restrict buf, size_t bufsize);
11.文件时间
ls命令按这3个时间值中的一个排序进行显示。系统默认(-l或-t)是按文件的修改时间的先后排序显示,-u是按访问时间排序,-c是按状态更改时间排序。st_atim最后访问时间,st_mtim最后修改时间,st_ctim表示i节点状态最后更改时间。
12.futimens,utimensat,utimes函数。
用于一个文件的访问和修改时间的更改。
#include "apue.h"
#include <fcntl.h>
int main(int argc, char* argv[])
{
int i, fd;
struct stat statbuf;
struct timespec times[2];
for(i = 1; i < argc; i ++){
if(stat(argv[i], &statbuf) < 0){
err_ret("%s: stat error", argv[i]);
continue;
}
if((fd = open(argv[i], O_RDWR | O_TRUNC)) < 0){
err_ret("%s: open error", argv[i]);
continue;
}
times[0] = statbuf.st_atim;
times[1] = statbuf.st_mtim;
if(futimens(fd, times) < 0)
err_ret("%s: futimens error", argv[i]);
close(fd);
}
exit(0);
}
int mkdir(const char* pathname, mode_t mode);
14.读目录
DIR *opendir(const char* pathname);
DIR *fdopendir(int fd);
struct dirent *readdir(DIR *dp);
void rewinddir(DIR *dp);
int closedir(DIR *dp);
long telldir(DIR *dp);
void seekdir(DIR *dp, long loc);
#include "apue.h"
#include <dirent.h>
#include <limits.h>
typedef int Myfunc(const char*, const struct stat*, int);
static Myfunc myfunc;
static int myftw(char* , Myfunc*);
static int dopath(Myfunc*);
static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;
int main(int argc, char* argv[])
{
int ret;
if(argc != 2)
err_quit("usage: ftw <starting-pathname>");
ret = myftw(argv[1], myfunc);
ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
if(ntot == 0)
ntot = 1;
printf("regular files = %ld\n", nreg);
printf("directories = %ld\n", ndir);
printf("block special = %ld\n", nblk);
printf("char special = %ld\n", nchr);
printf("FIFOs = %ld\n", nfifo);
printf("symbolic links =%ld\n", nslink);
printf("sockets =%ld\n", nsock);
exit(ret);
}
#define FTW_F 1 /* file other than directory */
#define FTW_D 2 /* directory */
#define FTW_DNR 3 /* directory that can't be read */
#define FTW_NS 4 /* file that we can't stat */
static char* fullpath; /* contain full pathname for every file */
static size_t pathlen;
static int myftw(char *pathname, Myfunc *func)
{
fullpath = path_alloc(&pathlen);
if(pathlen <= strlen(pathname)){
pathlen = strlen(pathname) * 2;
if((fullpath = realloc(fullpath, pathlen)) == NULL)
err_sys("realloc failed");
}
strcpy(fullpath, pathname);
return (dopath(func));
}
static int dopath(Myfunc *func)
{
struct stat statbuf;
struct dirent *dirp;
DIR *dp;
int ret, n;
if(lstat(fullpath, &statbuf) < 0)
return (func(fullpath, &statbuf, FTW_NS));
if(S_ISDIR(statbuf.st_mode) == 0) /* not a directory */
return (func(fullpath, &statbuf, FTW_F));
if((ret = func(fullpath, &statbuf, FTW_D)) != 0)
return ret;
n = strlen(fullpath);
if(n + NAME_MAX + 2 > pathlen){
pathlen *= 2;
if((fullpath = realloc(fullpath, pathlen)) == NULL)
err_sys("realloc failed");
}
fullpath[n ++] = '/';
fullpath[n] = 0;
if((dp = opendir(fullpath)) == NULL)
return (func(fullpath, &statbuf, FTW_DNR));
while((dirp = readdir(dp)) != NULL){
if((ret = dopath(func)) != 0)
break;
}
fullpath[n - 1] = 0;
if(closedir(dp) < 0)
err_ret("can't close directory %s", fullpath);
return ret;
}
static 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: err_dump("for S_IFDIR for %s", pathname);
}
break;
case FTW_D:
ndir++;
break;
case FTW_DNR:
err_ret("can't read directory %s", pathname);
break;
case FTW_NS:
err_ret("stat error for %s", pathname);
break;
default:
err_dump("unknown type %d for pathname %s", type, pathname);
}
return 0;
}
15.更改当前工作目录。
chdir,fchdir,getcd。
int chdir(const char* pathname);
int fchdir(int fd);
char* getcwd(char* buf, size_t size);