文件&设备操作

检查对某个文件的操作权限

检查对相对某个目录下的某文件的操作权限,man faccessat

#include <fcntl.h> /* Definition of AT_* constants */
#include <unistd.h>

int faccessat(int dirfd, const char *pathname, int mode, int flags);

获取文件状态

man 2 stat

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);

struct stat/usr/include/bits/stat.h中定义,原始定义中使用很多宏不方便阅读,可以用以下定义代替:

struct stat {
    dev_t     st_dev;     /* ID of device containing file */
    ino_t     st_ino;     /* inode number */
    mode_t    st_mode;    /* protection */
    nlink_t   st_nlink;   /* number of hard links */
    uid_t     st_uid;     /* user ID of owner */
    gid_t     st_gid;     /* group ID of owner */
    dev_t     st_rdev;    /* device ID (if special file) */
    off_t     st_size;    /* total size, in bytes */
    blksize_t st_blksize; /* blocksize for file system I/O */
    blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
    time_t    st_atime;   /* time of last access */
    time_t    st_mtime;   /* time of last modification */
    time_t    st_ctime;   /* time of last status change */
};

可以用下面的宏定义判断文件类型,传入参数是stat中的st_mode

S_ISREG(m)  is it a regular file?
S_ISDIR(m)  directory?
S_ISCHR(m)  character device?
S_ISBLK(m)  block device?
S_ISFIFO(m) FIFO (named pipe)?
S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)
S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)

st_mode中每个bit含义如下:

S_IFMT     0170000   bit mask for the file type bit fields
S_IFSOCK   0140000   socket
S_IFLNK    0120000   symbolic link
S_IFREG    0100000   regular file
S_IFBLK    0060000   block device
S_IFDIR    0040000   directory
S_IFCHR    0020000   character device
S_IFIFO    0010000   FIFO
S_ISUID    0004000   set-user-ID bit
S_ISGID    0002000   set-group-ID bit (see below)
S_ISVTX    0001000   sticky bit (see below)
S_IRWXU    00700     mask for file owner permissions
S_IRUSR    00400     owner has read permission
S_IWUSR    00200     owner has write permission
S_IXUSR    00100     owner has execute permission
S_IRWXG    00070     mask for group permissions
S_IRGRP    00040     group has read permission
S_IWGRP    00020     group has write permission
S_IXGRP    00010     group has execute permission
S_IRWXO    00007     mask for permissions for others (not in group)
S_IROTH    00004     others have read permission
S_IWOTH    00002     others have write permission
S_IXOTH    00001     others have execute permission

打开、创建文件

man open

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

int creat(const char *pathname, mode_t mode);

openat()是相对指定的目录描述符打开文件:

#include <fcntl.h>

int openat(int dirfd, const char *pathname, int flags);
int openat(int dirfd, const char *pathname, int flags, mode_t mode);

关闭文件

man close

#include <unistd.h>

int close(int fildes);

文件描述符

man fcntl

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

int fcntl(int fd, int cmd, ... /* arg */ );

对已经打开的文件描述符进行操作。可以进行的操作比较多,而且用途三言两语难以说清楚,这里只列出个目录,详情到man手册中查看。

文件描述符复制(Duplicating a file descriptor):

 F_DUPFD (int)、F_DUPFD_CLOEXEC (int; since Linux 2.6.24)

文件描述符标记(File descriptor flags):

 F_GETFD (void)、F_SETFD (int)

文件状态标记(File status flags):

F_GETFL (void)、F_SETFL (int)

文件软锁(Advisory locking):

F_SETLK (struct flock *)、F_SETLKW (struct flock *)、F_GETLK (struct flock *)

文件信号响应管理(Managing signals):

F_GETOWN (void)、F_SETOWN (int)、F_GETOWN_EX (struct f_owner_ex *) (since Linux 2.6.32)
F_SETOWN_EX (struct f_owner_ex *) (since Linux 2.6.32)、F_GETSIG (void)、F_SETSIG (int)

文件描述符租约(Leases):

 F_SETLEASE (int)、 F_GETLEASE (void)

文件和路径变化通知(File and directory change notification (dnotify)):

 F_NOTIFY (int)

Pipe容量设置(Changing the capacity of a pipe):

F_SETPIPE_SZ (int; since Linux 2.6.35)、F_GETPIPE_SZ (void; since Linux 2.6.35)

文件内容截断到指定长度

man truncate

#include <unistd.h>
#include <sys/types.h>

int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);

逐行读取文件内容

#include <stdio.h>

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);

*lineptr是存放一行文本的内存地址,*n*lineptr指向的内存空间的大小。

注意:如果*lineptr是null,getline和getdelim会让*lineptr指定自动分配的一块内存,要主动释放*lineptr指向的内存,这种情况下*n被忽略。

注意:如果*lineptr指定的内存空间不足以存放整行数据,getline和getdelim会调用realloc重新分配内存,更改*lineptr指向新分配的内存,并同步更新*n

向文件中写入内容

man 3 write

#include <unistd.h>

ssize_t pwrite(int fildes, const void *buf, size_t nbyte,
       off_t offset);
ssize_t write(int fildes, const void *buf, size_t nbyte);