stat函数执行成功后,buf得到pathname指定文件有关的信息结构,stat结构定义见P75stat结构成员st_size表示以字节为单位的文件长度
#include <sys/stat.h>
int stat(const char *pathname, struct stat *buf);
int fstat(int fd, struct stat *buf); // 用fd指定文件
int lstat(const char *pathname, struct stat *buf);
// 当pathname对应文件为一个符号链接时,得到链接有关信息而不是该链接所引用文件的信息
// all return: 0 on success, -1 on error| Macro | Type of file |
|---|---|
S_ISERG() |
regular file |
S_ISDIR() |
directory file |
S_ISLNK() |
symbolic link |
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) // pre defined in <sys/stat.h>
Usage:if (S_ISREG(buf.st_mode)) { // do something if the ralated file is regular file}
st_mode值包含了对文件的访问权限位,每个文件有9个访问权限位
st_mode mask |
Meaning |
|---|---|
S_IRUSR |
user-read |
S_IWGRP |
group-write |
S_IXOTH |
other-execute |
access函数按进程的 real user ID 和 real group ID进行访问权限测试
#include <unistd.h>
int access(const char *pathname, int mode); // mode: F_OK, R_OK, W_OK, X_OK
int faccessat(int fd, const char *pathname, int mode, int flag); // both return: 0 if OK, -1 on error| mode | 说明 | mode | 说明 |
|---|---|---|---|
F_OK |
测试文件是否存在 | R_OK |
测试读权限 |
W_OK |
测试写权限 | X_OK |
测试执行权限 |
umask函数为进程设置文件创建屏蔽字为cmask,并返回之前的值chmod函数更改现有文件的访问权限为modechown函数更改文件的用户ID和组ID,新ID为-1则表示对应ID不变
#include <sys/stat.h>
mode_t umask(mode_t cmask); // returns: previous file mode creation mask
int chmod(const char *pathname, mode_t mode); // returns: 0 if OK, −1 on error
int chown(const char *pathname, uid_t owner, git_t group);// returns: 0 if OK, −1 on errortruncate函数将pathname指定的文件的长度截短为length- 若该文件的长度大于
length,则超过length以外的数据不再能访问 - 若该文件的长度小于
length,则新旧尾端之间的数据将读作0
#include <unistd.h>
int truncate(const char *pathname, off_t length); // returns: 0 if OK, -1 on errorlink函数创建一个新目录项newpath,它引用现有文件existingpathunlink函数删除目录项pathname,并将其所引用文件的链接计数减1- 对于文件,
remove函数的功能与unlink相同,对于目录,与rmdir相同 symlink函数创建一个指向actualpath的符号链接,并不要求actualpath已经存在,不要求同一文件系统
#include <unistd.h>
int link(const char *existingpath, const char *newpath);
int unlink(const char *pathname);
int remove(const char *pathname);
int symlink(const char *actualpath, const char *sympath); // P99
// all return: 0 if ok, -1 on errorrename函数将oldname指向的文件或目录重命名为newnameP96
#include <stdio.h>
int rename(char *oldname, char *newname); // returns: 0 if OK, -1 on errorstat结构对每个文件维护3个时间字段,字段类型为struct timespec(旧版标准为struct time_t st_atime, st_mtime, st_ctime)
| 字段 | 说明 | 例子 | ls选项 |
|---|---|---|---|
| st_atim | 文件数据的最后访问时间 | read | -u |
| st_mtim | 文件数据的最后修改时间 | write | 默认 |
| st_ctim | i节点状态的最后更改时间 | chmod,chown | -c |
futimens,utimensat和utimes函数可以更改文件的访问和修改时间(旧版time_t格式则使用utime函数),times[0]为访问时间,times[1]为修改时间
#include <sys/stat.h>
int futimens(int fd, struct timespec times[2]);
int utimensat(int fd, char *path, struct timespec times[2], int flag);
#include <sys/time.h>
int utimes(char *pathname, struct timeval times[2]);
#include <utime.h>
int utime(char *pathname, struct utimbuf *times); // times->actime, times->modtime
// all return: 0 if OK, −1 on errormkdir函数用来创建路径名为pathname的目录,mode指定访问权限opendir函数打开一个目录,返回指向pathname的目录指针readdir函数读目录,返回目录中第一个目录项到dirent结构中chdir函数切换进程的当前工作目录,即相对路径名的起点getcwd函数执行成功后,buf得到当前工作目录的绝对路径名
#include <sys/stat.h>
int mkdir(char *pathname, mode_t mode);
#include <stdlib.h>
int rmdir(char *pathname); // both return: 0 if OK, −1 on error
#include <dirent.h>
DIR *opendir(const char *pathname); // returns: pointer if OK, NULL on error
struct dirent *readdir(DIR *dp);
#include <unistd.h>
int chdir(const char *pathname); // returns: 0 if OK, −1 on error
char *getcwd(char *buf, size_t size); // returns: buf if OK, NULL on error获取一个文件的权限
$ ./myls
usage: myls somefile
$ ./myls a.txt
rwx
$ ./myls b.txt
r-x
My solution:
#include <stdio.h>
#include <unistd.h> // for access
#include <stdlib.h> // for exit, EXIT_FAILURE
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}
char *filename = argv[1];
if (access(filename, F_OK))
{
fprintf(stderr, "File not exists\n");
exit(EXIT_FAILURE);
}
char output[] = "---";
if (!access(filename, R_OK)) output[0] = 'r';
if (!access(filename, W_OK)) output[1] = 'w';
if (!access(filename, X_OK)) output[2] = 'x';
printf("%s\n", output);
return 0;
}