首页 > 代码库 > APUE: 文件和目录相关的系统调用
APUE: 文件和目录相关的系统调用
Tips:下面的总结是参考APUE(unix环境高级编程)这本书,在linux(ubuntu)上的实现。
Linux系统的调用结构:
最上层:应用程序+shell命令(外部命令在coreutils中实现,内部命令在bash中实现)
中间层:linux下的库函数(gnu的c标准库在glibc中实现)
最底层:linux内核(163个linux系统调用接口+内核子系统(驱动))
系统调用是linux内核和外部的唯一接口。
unix的标准主要有两个:
posix标准:可移植操作系统接口,IEEE、ISO/IEC都收纳
IEEE1003:posix标准的别称,有三部分。
X/openSUS标准:X/open单一unix规范,也叫unix95-unix98.
XSI:unix95或unix98提供的接口
/usr/include/asm-i386/unistd.h系统调用的头文件
man 2 syscalls 查看所有系统调用
int access(constchar *pathname, int amode);
posix对系统调用进行了实现,所以做应用开发一般使用posix的接口,而不是系统调用。
现在的unix和linux几乎都遵循posix标准。
#########################################################
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
intopen(constchar *path, int oflags);
intopen(constchar *path, int oflags, mode_t mode);
oflags:
O_RDONLY
O_WRONLY
O_RDWR
--------
O_APPEND(追加)
O_TRUNC(截取,将文件截取为0)
O_CREAT:创建文件
O_EXCL(确保创建新文件成功)
O_NONBLOCK:非阻塞式IO
O_NOCTTY:不将终端指定为该进程的操作终端。
O_SYNC:每次写都要等待物理IO操作完成才返回。
O_DSYNC:同上,不过只针对数据,忽略属性。
O_RSYNC:读要等待同一块的写完成。
O_CREAT| O_EXCL
O_RDONLY| O_NONBLOCK
O_WRONLY| O_NONBLOCK
whenoflags=O_CREAT mode:
S_IRUSR
S_IWUSR
S_IXUSR
S_IRGRP
S_IWGRP
S_IXGRP
S_IROTH
S_IWOTH
S_IXOTH
posix的标准输入、标准输出、标准出错的0,1,2应该写写成:
STDIN_FILENO
STDOUT_FILENO
STDERR_FILENO
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
intcreat(constchar *path, mode_t mode);
和open一样,不过是用来创建新文件的。
#include<unistd.h>
ssize_twrite(intfildes, const void *buf, size_t nbytes);
从buf往filedes写nbytes字节。返回实际写入字节数。
ssize_tpwrite(intfildes, const void *buf, size_t nbytes, off_t offset);
从offset开始写,原子操作。
#include<unistd.h>
ssize_tread(intfildes, void *buf, size_t nbytes);
从fildes往buf读nbytes字节。返回实际读到的字节数。EOF返回0.
ssize_tpread(intfildes, void *buf, size_t nbyte, off_t offset);
从offset开始读,原子操作。
#include<unistd.h>
intclose(intfildes); /*终止描述符建立的连接*/
#include<unistd.h>
#include<sys/types.h>
off_tlseek(intfildes, off_t offset, int whence);
重新定位,从whence开始,偏移offset字节。
whence:
SEEK_SET:文件开头
SEEK_CUR:当前位置
SEEK_END:文件结尾
#include<unistd.h>
intdup(intfildes);
返回新的文件描述符,可用描述符最小值。
intdup2(intfildes, int fides2);
fides2指定返回的文件描述符。
#include<unistd.h>
voidsync(void);
将所有修改过的块缓冲区排入写队列,立即返回。
voidsyncfs(intfildes);
只针对fildes指定的文件。
intfsync(intfildes);
将fildes指定的修改过的块缓冲区排入写队列,等待物理IO操作完成才返回。
intfdatasync(intfildes);
只处理数据部分,不处理属性等其它内容。
#include<sys/ioctl.h>
intioctl(intfildes, int request, /*arg*/);
根据第二个参数获取或设置参数,设置或获取的值放在第三个参数中.
六种操作:
1.文件操作(第三个参数为int*)
2.套接字操作(第三个参数为int*)
3.ARP高速缓存操作(structarpreq *)
4.路由表操作(structrtentry *)
5.接口操作(structifconf *, struct ifreq *)
6.流系统
request:
盘标号:DIO
磁带IO:MTIO
终端io:TIO
文件FIO:
FIONBIO(等效于fcntl的O_NONBLOCK)
FIOASYNC(等效于fcntl的O_ASYNC)
FIONREAD(获取接收缓冲区字节数)
FIOSETOWN(与套接字的SIOCSPGRP等效)
FIOGETOWN(与套接字的SIOCGPGRP等效)
套接字SIO:
SIOCATMARK(是否位于带外标记,等效于sockatmark函数)
SIOCSPGRP(等效于fcntl的F_GETOWN)
SIOCGPGRP(等效于fcntl的F_SETOWN)
ARP:<net/if_arp.h>
SIOCSARP(创建或修改表项)
SIOCGARP(获取表项)
SIOCDARP(删除表项)
路由:<net/route.h>
SIOCADDRT(往路由表增加一项)
SIOCDELRT(往路由表删除一项)
接口:<net/if.h>
SIOCGIFCONF(获取所有接口列表,structifconf结构)
SIOCGIFMTU(获取接口的mtu,structifreq结构)
…
#include<unistd.h>
#include<fcntl.h>
intfcntl(intfildes, int cmd, /*arg*/);
执行各种描述符控制操作。
五种功能:
1.复制一个现有描述符
2.获取/设置文件描述符标记
3.获取/设置文件状态标记
4.获取/设置异步IO所有权
5.获取/设置记录锁
cmd:
文件描述符相关:
F_DUPFS:复制文件描述符
F_GETFD:返回文件描述符标记,arg=0.
F_SETFD:设置文件描述符标记
文件状态相关:
F_GETFL:返回文件状态,arg=0.
F_SETFL:设置文件状态标记
F_SETFL设置文件状态对应的arg:
O_NONBLOCK:非阻塞式IO
O_ASYNC:信号驱动式IO
O_APPEND
O_DIRECT
O_NOATIME
开启非阻塞模式IO:
flags=fcntl(fd,F_GETFL, 0);
flags|= O_NONBLOCK;
flags=fcntl(fd,FSETFL, flags);
关闭非阻塞式IO:
flags&= ~O_NONBLOCK;
fcntl(fd,F_SETFL, flags);
异步IO所有权:
F_GETOWN:返回信号的属主,正数是主ID,负数是组ID。arg=0.
F_SETOWN:指定用于接收SIGIO和SIGURG信号的属主。
用于记录上锁的:
F_SETLK:获取或释放锁,如果无法将该锁授予调用过程就返回错误。
F_SETLKW:获取或释放锁,如果无法将该锁授予调用过程就阻塞。
F_GETLK:检查是否有某个以存在的锁妨碍即将授予新锁,将该锁信息写入flock结构。
记录上锁要求第三个参数为下面结构:
structflock
{
short l_type; //F_RDLCK, F_WRLCK, F_UNLCK
short l_whence; //SEEK_SET, SEEK_CUR, SEEK_END
off_t l_start; //根据l_whence解释从哪里开始偏移
off_t l_len; // 0就是从l_start到长度的最大可能值
pid_t l_pid; // F_GETLK返回的PID
}
#######################################################
文件和目录的属性:
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
intstat(constchar *path, struct stat *buf);
根据文件名获取文件状态信息
intlstat(constchar *path, struct stat *buf);
可以根据符号链接文件名获取符号链接的信息。
intfstat(intfildes, struct stat *buf);
根据文件描述符获取文件状态信息
structstat {
mode_tst_mode;
off_tst_size;
dev_tst_dev;//设备号
dev_tst_rdev;//特殊字符设备或块设备的设备号
ino_tst_ino;//序列号
nlink_tst_nlink;//链接数
blksize_tst_blksize;
blkcnt_tst_blocks;
uid_tst_uid;
gid_tst_gid;
time_tst_atime; //访问时间
time_tst_mtime; //修改时间
time_tst_ctime; //更新时间
};
下面两个宏获取主次设备号:
major(st_dev/st_rdev):主设备号
minor(st_dev/st_rdev):次设备号
可以用下列宏确定文件类型:
S_ISREG(st_mode):普通文件
S_ISDIR(st_mode):目录文件
S_ISCHR(st_mode):字符特殊文件
S_ISBLK(st_mode):块特殊文件
S_ISFIFO(st_mode):管道或FIFO
S_ISLNK(st_mode):符号链接
S_ISSOCK(st_mode):套接字
确定IPC对象的宏:
S_TYPEISMQ(buf):消息队列
S_TYPEISSEM(buf):信号量
S_TYPEISSHM(buf):共享内存
#include<unistd.h>
根据文件名测试文件的权限。
mode:
R_OK:可读
W_OK:可写
X_OK:可执行
F_OK:文件存在
#include<sys/types.h>
#include<sys/stat.h>
mode_tumask(mode_tmask);
为进程设置文件模式创建屏蔽字,返回之前的值。
用在创建文件之前,即使新创建的文件赋予了某个权限,如果被umask屏蔽,那么实际新文件没有该权限。
0400:屏蔽用户读权限
0200:屏蔽用户写权限
0200:屏蔽用户执行权限
0040:屏蔽组读权限
0020:屏蔽组写权限
0010:屏蔽组执行权限
0004:屏蔽其它读权限
0002:屏蔽其它写权限
0001:屏蔽其它执行权限
0000:不屏蔽任何权限
#include<sys/stat.h>
intchmod(constchar *path, mode_t mode);
intfchmod(intfd, mode_t mode);
更改现有文件的访问权限。
Mode:
S_ISUID:执行时设置用户ID
S_ISGID:执行时设置组ID
S_ISVTX:保存正文(粘住位)
S_IRWXU:用户读写执行权限)
S_IRUSR
S_IWUSR
S_IXUSR
S_IRWXG:组读写执行权限
S_IRGRP
S_IWGRP
S_IXGRP
S_IRWXO:其它读写执行权限
S_IROTH
S_IWOTH
S_IXOTH
关闭某个权限位:oldmode&~newmode。
#include<sys/types.h>
#include<unistd.h>
intchown(constcahr *path, uid_t owner, gid_t group);
根据文件名更改用户ID和组ID。
intlchown(constchar *path, uid_t owner, gid_t group);
可以处理符号链接,更改符号链接本身,而不是指向的文件。
intfchown(intfildes, uid_t owner, gid_t group);
根据打开的文件描述符更改用户ID和组ID。
owner或group等于-1表示ID不变。
#include<unistd.h>
#include<sys/types.h>
inttruncate(constchar *path, off_t length);
根据文件名截取文件长度,也就是将文件长度设置为length。
intftruncate(intfildes, off_t length);
根据文件描述符截取文件长度,也就是将文件长度设置为length。
#include<unistd.h>
intlink(constchar *oldpath, const cahr *newpath);
创建一个指向现有文件的链接(硬链接)。
若newpath已经存在返回错误。
#include<unistd.h>
intunlink(constcahr *path);
删除一个文件(也可以删除一个硬链接文件)。
如果是一个符号链接,只删除符号链接本身。
#include<stdio.h>
intrename(constchar *oldpath, const char *newpath);
给文件或目录更名。
如果是符号链接,只针对符号链接本身。
#include<stdio.h>
intremove(constchar *pathname);
重命名一个文件或目录。也可以删除一个硬链接。
如果是符号链接,只针对符号链接本身。
#include<unistd.h>
intsymlink(constchar *oldpath, const char *newpath);
创建一个符号链接(软连接)。
#include<unistd.h>
ssize_treadlink(constchar *path, char *buf, size_t bufsiz);
用来打开一个符号链接并将符号链接的内容读入buf,返回读到的字节数。如果是符号链接,只针对符号链接本身。
#include<sys/types.h>
#include<utime.h>
intutime(constchar *filename, const struct utimbuf *times);
修改一个文件的访问时间和 修改时间。
如果times=NULL,则将访问时间和修改时间都设置为当前时间。
Structutimbuf {
time_tactime; //访问时间
time_tmodtime; //修改时间
};
#include<sys/stat.h>
#include<sys/types.h>
intmkdir(constcahr *path, mode_t mode);
创建一个新的空目录。
#include<unistd.h>
intrmdir(constchar *path);
删除一个空目录。
#include<unistd.h>
intchdir(constchar *path);
intfchdir(intfildes);
更改当前工作目录。
#include<unistd.h>
char*getcwd(char*buf, size_t size);
获取当前工作目录的绝对路径。
未完待续......
APUE: 文件和目录相关的系统调用