首页 > 代码库 > APUE: 文件和目录相关的系统调用

APUE: 文件和目录相关的系统调用

Tips:下面的总结是参考APUE(unix环境高级编程)这本书,在linux(ubuntu)上的实现。


Linux系统的调用结构:

最上层:应用程序+shell命令(外部命令在coreutils中实现,内部命令在bash中实现)

中间层:linux下的库函数(gnu的c标准库在glibc中实现)

最底层:linux内核(163linux系统调用接口+内核子系统(驱动))


系统调用是linux内核和外部的唯一接口。

unix的标准主要有两个:

posix标准:可移植操作系统接口,IEEEISO/IEC都收纳

IEEE1003posix标准的别称,有三部分。

X/openSUS标准:X/open单一unix规范,也叫unix95-unix98.

XSIunix95unix98提供的接口


/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);

buffiledesnbytes字节。返回实际写入字节数。

ssize_tpwrite(intfildes, const void *buf, size_t nbytes, off_t offset);

offset开始写,原子操作。


#include<unistd.h>

ssize_tread(intfildes, void *buf, size_t nbytes);

fildesbufnbytes字节。返回实际读到的字节数。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

磁带IOMTIO

终端ioTIO


文件FIO:

FIONBIO(等效于fcntlO_NONBLOCK)

FIOASYNC(等效于fcntlO_ASYNC)

FIONREAD(获取接收缓冲区字节数)

FIOSETOWN(与套接字的SIOCSPGRP等效)

FIOGETOWN(与套接字的SIOCGPGRP等效)


套接字SIO:

SIOCATMARK(是否位于带外标记,等效于sockatmark函数)

SIOCSPGRP(等效于fcntlF_GETOWN)

SIOCGPGRP(等效于fcntlF_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,负数是组IDarg=0.

F_SETOWN:指定用于接收SIGIOSIGURG信号的属主。


用于记录上锁的:

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; //更新时间

};


下面两个宏获取主次设备号:

majorst_dev/st_rdev):主设备号

minorst_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);

可以处理符号链接,更改符号链接本身,而不是指向的文件。

intfchownintfildes, uid_t owner, gid_t group);

根据打开的文件描述符更改用户ID和组ID

ownergroup等于-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: 文件和目录相关的系统调用