帮助手册:man 2 stat
包含头文件:#include
#include #include 函数原型:
int stat(const char *pathname, struct stat *statbuf);
| 参数 | 说明 |
|---|---|
| pathname | 文件名 |
| statbuf | 文件状态结构体 |
| return | 成功:0 失败:-1,设置errno |
文件状态结构体
struct stat {
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
off_t st_size;
blksize_t st_blksize;
blkcnt_t st_blocks;
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
#define st_atime st_atim.tv_sec
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
struct timespec {
__kernel_time_t tv_sec;
long tv_nsec;
st_mode 定义了下列数种情况::
| 宏 | 值 | 说明 |
|---|---|---|
| S_IFMT | 0170000 | 文件类型的位遮罩 |
| S_IFSOCK | 0140000 | scoket |
| S_IFLNK | 0120000 | 符号连接 |
| S_IFREG | 0100000 | 一般文件 |
| S_IFBLK | 0060000 | 区块装置 |
| S_IFDIR | 0040000 | 目录 |
| S_IFCHR | 0020000 | 字符装置 |
| S_IFIFO | 0010000 | 先进先出 |
| S_ISUID | 04000 | 文件的(set user-id on execution)位 |
| S_ISGID | 02000 | 文件的(set group-id on execution)位 |
| S_ISVTX | 01000 | 文件的sticky位 |
| S_IRUSR | 00400 | 文件所有者具可读取权限 |
| S_IWUSR | 00200 | 文件所有者具可写入权限 |
| S_IXUSR | 00100 | 文件所有者具可执行权限 |
| S_RWXU | 00700 | 文件所有者具有读,写和执行权限 |
| S_IRGRP | 00040 | 用户组具可读取权限 |
| S_IWGRP | 00020 | 用户组具可写入权限 |
| S_IXGRP | 00010 | 用户组具可执行权限 |
| S_IROTH | 00004 | 其他用户具可读取权限 |
| S_IWOTH | 00002 | 其他用户具可写入权限 |
| S_IXOTH | 00001 | 其他用户具可执行权限 |
上述的文件类型在POSIX中定义了检查这些类型的宏定义:
| 宏 | 说明 |
|---|---|
| S_ISLNK (st_mode) | 判断是否为符号连接 |
| S_ISREG (st_mode) | 是否为一般文件 |
| S_ISDIR (st_mode) | 是否为目录 |
| S_ISCHR (st_mode) | 是否为字符装置文件 |
| S_ISBLK (s3e) | 是否为先进先出 |
| S_ISSOCK (st_mode) | 是否为socket |
struct passwd *getpwuid(uid_t uid);
包含头文件:
#include
#include
struct passwd {
char *pw_name;
char *pw_passwd
char *pw_gecos;
char *pw_dir;
char *pw_sheel;
uid_t pw_uid;
gid_t pw_gid;
};
2.1.1.2 通过gid获取组名getgrgid
struct group *getgrgid(gid_t gid);
包含头文件:
#include
#include
struct group {
char *gr_name;
char *gr_passwd;
char **gr_mem;
git_t gr_gid;
};
2.1.1.3 通过秒数获取本地时间localtime
struct tm *localtime(const time_t *timep);
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
查看文件信息示例代码:
#include#include #include #include #include #include #include #include int main(int argc, char* argv[]) { struct stat sb; stat(argv[1], &sb); char stmode[11] = { 0 }; // 解析st_mode memset(stmode, '-', sizeof(stmode)-1); if(S_ISDIR(sb.st_mode)) stmode[0] = 'd'; if(S_ISCHR(sb.st_mode)) stmode[0] = 'c'; if(S_ISBLK(sb.st_mode)) stmode[0] = 'b'; if(S_ISFIFO(sb.st_mode)) stmode[0] = 'p'; if(S_ISLNK(sb.st_mode)) stmode[0] = 'l'; if(S_ISSOCK(sb.st_mode)) stmode[0] = 's'; if(sb.st_mode & S_IRUSR) stmode[1] = 'r'; if(sb.st_mode & S_IWUSR) stmode[2] = 'w'; if(sb.st_mode & S_IXUSR) stmode[3] = 'x'; if(sb.st_mode & S_IRGRP) stmode[4] = 'r'; if(sb.st_mode & S_IWGRP) stmode[5] = 'w'; if(sb.st_mode & S_IXGRP) stmode[6] = 'x'; if(sb.st_mode & S_IROTH) stmode[7] = 'r'; if(sb.st_mode & S_IWOTH) stmode[8] = 'w'; if(sb.st_mode & S_IXOTH) stmode[9] = 'x'; struct tm *filetm = localtime(&sb.st_atim.tv_sec); char timebuf[20] = { 0 }; sprintf(timebuf, "%d月 %d %02d:%02d", filetm->tm_mon+1,filetm->tm_mday, filetm->tm_hour, filetm->tm_min); printf("%s %ld %s %s %ld %s %sn",stmode, sb.st_nlink, getpwuid(sb.st_uid)->pw_name, getgrgid(sb.st_gid)->gr_name, sb.st_size, timebuf, argv[1]); return 0; }
2.1.2 判断有效用户对一个文件的权限或文件是否存在access()lstata()和stat()的区别:
stat()有穿透效果,当遇到软连接会通过软连接找到硬连接
lstat()没有穿透效果
帮助手册:man 2 access
包含头文件:#include
函数原型:
int access(const char *pathname, int mode);
| 参数 | 说明 |
|---|---|
| pathname | 文件路径 |
| mode | R_OK:读 W_OK:写 X_OK:执行 F_OK:存在 |
| return | 成功:0 失败:-1 |
示例:
#include2.1.3 修改文件权限chmod()#include int main(int argc, char* argv[]) { if(access(argv[1], R_OK) == 0) printf("%s read ok!n", argv[1]); if(access(argv[1], W_OK) == 0) printf("%s write ok!n", argv[1]); if(access(argv[1], X_OK) == 0) printf("%s execute ok!n", argv[1]); if(access(argv[1], F_OK) == 0) printf("%s existence!n", argv[1]); return 0; }
帮助手册:man 2 chmod
包含头文件:#include
函数原型:
int chmod(const char *pathname, mode_t mode);
| 参数 | 说明 |
|---|---|
| pathname | 文件路径 |
| mode | 新的权限 |
| return | 成功:0 失败:-1,并设置errno |
帮助手册:man 2 chown
包含头文件:#include
函数原型:
int chown(const char *pathname, uid_t owner, gid_t group);f
| 参数 | 说明 |
|---|---|
| pathname | 文件路径 |
| owenr | 用户ID(/etc/passwd) |
| group | 组ID(/etc/group) |
| return | 成功:0 失败:-1,并设置errno |
帮助手册:man 2 truncate
包含头文件:#include
#include 函数原型
int truncate(const char *path, off_t length);
| 参数 | 说明 |
|---|---|
| path | 文件路径 |
| length | 截断长度 |
| return | 成功:0 失败:-1,并设置errno |
示例:
#include2.1.6 创建硬连接link()#include #include int main(int argc, char* argv[]) { truncate(argv[1], 1024); return 0; }
帮助手册:man 2 link
包含头文件:#include
函数原型:
int link(const char *oldpath, const char *newpath);
| 参数 | 说明 |
|---|---|
| oldpath | 原路径 |
| newpath | 新路径 |
| return | 成功:0 失败:-1,并设置errno |
示例:
#include2.1.7 创建软连接symlink()#include int main(int argc, char* argv[]) { link(argv[1], argv[2]); return 0; }
帮助手册:man 2 symlink
包含头文件:#include
函数原型:
int symlink(const char *target, const char *linkpath);
| 参数 | 说明 |
|---|---|
| target | 原目标 |
| linkpath | 软连接路径 |
| return | 成功:0 失败:-1,并设置errno |
示例:
#include2.1.8 读一个软连接readlink()#include int main(int argc, char* argv[]) { symlink(argv[1], argv[2]); return 0; }
帮助手册:man 2 readlink
包含头文件:
-#include函数原型:
ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);
| 参数 | 说明 |
|---|---|
| pathname | 软连接路径 |
| buf | 缓冲区 |
| bufsiz | 缓冲区大小 |
| return | 成功:大小 失败:-1,设置errno |
示例:
#include2.1.9 删除一个连接unlink()#include int main(int argc, char* argv[]) { char buf[32] = { 0 }; readlink(argv[1], buf, sizeof(buf)); printf("buf is %sn", buf); # argv[1] return 0; }
帮助手册:man 2 unlink
包含头文件:#include
函数原型:
int unlink(const char *pathname);
| 参数 | 说明 |
|---|---|
| pathname | 路径 |
| return | 成功:0 失败:-1,并设置errno |
#include#include int main(int argc, char* argv[]) { unlink(argv[1]); return 0; }
注:当文件被打开,但是所有硬连接被unlink,当打开这个文件的进程结束后,这个文件才会被删除。
2.1.10 更改一个文件或目录的名字或位置rename()帮助手册:man 2 rename
包含头文件:#include
函数原型:
int rename(const char *oldpath, const char *newpath);
| 参数 | 说明 |
|---|---|
| oldpath | 原路径 |
| newpath | 新路径 |
| return | 成功:0 失败:-1,并设置errno |
示例:
#include2.2 目录 2.2.1 获取当前工作路径getcwd()int main(int argc, char* argv[]) { rename(argv[1], argv[2]); return 0; }
帮助手册:man 2 getcwd
包含头文件:#include
函数原型:
char *getcwd(char *buf, size_t size);
| 参数 | 说明 |
|---|---|
| buf | 传出缓冲区 |
| size | 缓冲区大小 |
| return | 成功:当前工作路径的指针 失败:NULL,并设置errno |
帮助手册:man 2 getcwd
包含头文件:#include
函数原型:
char *chdir(char *path);
| 参数 | 说明 |
|---|---|
| path | 新路径 |
| return | 成功:0 失败:-1,并设置errno |
帮助手册:man 2 mkdir
包含头文件:#include
#include 函数原型:
int mkdir(const char *pathname, mode_t mode);
| 参数 | 说明 |
|---|---|
| pathname | 目录名 |
| mode | 目录权限 |
| return | 成功:0 失败:-1,并设置errno |
示例:
#include2.2.4 删除空目录rmdir()#include int main(int argc, char* argv[]) { char buf[256] = { 0 }; chdir("../"); getcwd(buf, sizeof(buf)); printf("current working path: %sn", buf); mkdir("newdir", 0777); return 0; }
帮助手册:man 2 rmdir
包含头文件:#include
函数原型:
int rmdir(const char *pathname);
| 参数 | 说明 |
|---|---|
| pathname | 目录路径 |
| return | 成功:0 失败:-1并设置errno |
帮助手册:man opendir`
包含头文件:#include
#include 函数原型:
int rmdir(const char *pathname);
| 参数 | 说明 |
|---|---|
| pathname | 目录路径 |
| return | 成功:目录流的指针 失败:NULL,并设置errno |
帮助手册:man 3 readdir
包含头文件:#include
函数原型:
struct dirent *readdir(DIR *dirp);
| 参数 | 说明 |
|---|---|
| dirp | 目录流的指针 |
| return | 成功:下一个目录进入点 失败:NULL,并设置errno 读到目录文件尾:NULL |
struct dirent {
ino_t d_ino;
off_t d_off;
unsigned short d_reclen;
unsigned char d_type;
char d_name[256];
};
d_type值说明:
| 值 | 说明 |
|---|---|
| DT_BLK | 块设备 |
| DT_CHR | 字符设备 |
| DT_DIR | 目录 |
| DT_FIFO | 管道 |
| DT_LNK | 软连接 |
| DT_REG | 普通文件 |
| DT_SOCK | sock |
| DT_UNKNOWN | 未知类型 |
帮助手册:man 3 closedir
包含头文件:#include
#include 函数原型:
int closedir(DIR *dirp);
| 参数 | 说明 |
|---|---|
| dirp | 目录流的指针 |
| return | 成功:0 失败:-1,并设置errno |
示例:
#include2.2.6 重设读取目录的位置为开头位置rewinddir()#include #include #include #include int count = 0; int DirCount(char *dirname) { DIR *dirp = opendir(dirname); if(dirp == NULL) return -1; struct dirent *dentp = NULL; while((dentp = readdir(dirp)) != NULL) { if(dentp->d_type == DT_DIR) { if(strcmp(".", dentp->d_name) == 0 || strcmp("..", dentp->d_name) == 0) continue; char newdirname[1024] = { 0 }; sprintf(newdirname, "%s/%s", dirname, dentp->d_name); DirCount(newdirname); } printf("%s/%sn", dirname, dentp->d_name); count++; } closedir(dirp); return 0; } int main(int argc, char* argv[]) { DirCount(argv[1]); printf("count = %dn", count); return 0; }
帮助手册:man 3 rewinddir
包含头文件:#include
#include 函数原型:
void rewinddir(DIR *dirp);
| 参数 | 说明 |
|---|---|
| dirp | 目录流的指针 |
| return | void |
帮助手册:man 3 telldir
包含头文件:#include
#include 函数原型:
long telldir(DIR *dirp);
| 参数 | 说明 |
|---|---|
| dirp | 目录流的指针 |
| return | 成功:下一个读取位置 失败:-1,并设置errno |
帮助手册:man 3 seekdir
包含头文件:#include
函数原型:
void seekdir(DIR *dirp, long loc);
| 参数 | 说明 |
|---|---|
| dirp | 目录流的指针 |
| loc | 距离目录文件开头的偏移量 |
| return | void |
包含头文件:
/usr/include/asm-generic/errno-base.h/usr/include/asm-generic/errno.h/usr/include/errno.hetc
查找errno头文件
sudo find /usr/ -name "errno*.h"



