




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第6章 Linux系统调用,6.1 Linux系统调用概述,系统调用是Linux操作系统内核提供给用户程序的接口; 应用程序通过该接口使用系统资源; 如果没有系统调用,应用程序失去内核的支持,也无法利用内核提供的系统资源。,系统调用主要分为如下几类: 文件系统控制类; 文件系统操作类; 进程控制类; 操作系统控制类; 内存管理类; 网络管理类; Socket控制类; 用户管理类; 进程间通信类。,6.1 Linux系统调用概述,系统调用是一种函数调用,与一般的函数调用相比,在表现方式上和实现效果上有明显不同: 表现方式上的不同:一般函数调用时直接由调用过程转向被调用过程;而系统调用不允许由调用
2、过程直接转向被调用过程,要借助于信号(软中断),先进入系统内核,再转向相应的系统调用。 实现效果上的不同:一般函数调用一直在用户空间上进行,不能进入操作系统内核空间;而系统调用需要从用户空间切换到内核空间,并在内核空间下进行。由于内核空间处于保护模式下,更加安全。因此,通过系统调用方式提供给应用程序使用内核资源不但更加安全,而且优先级高,响应速度快,效率高。,6.1 Linux系统调用概述,6.1 Linux系统调用概述,图6.1 linux调用,在C语言中存在一系列链接库,在链接库中含有一系列函数调用,如链接库stdio.h中含有标准输入、输出操作的fopen、fclose,fread、fw
3、rite、fseek、ftell等,用户应用程序调用这些链接库函数。这些函数位于操作系统之上,需要通过系统调用才能和操作系统内核取得联系。,6.1 Linux系统调用概述,6.2文件系统类系统调用,fcntl:文件控制; flock:文件加/解锁; create:创建新文件; open:打开文件; close:关闭文件; read:读文件; write:写文件; ready:从文件读入数据到缓冲数组中;,writey:将缓冲数组里的数据写入文件; pread:对文件随机读; pwrite:对文件随机写; lseek:移动文件指针; _llseek:在64位地址空间里移动文件指针; dup:复制
4、已打开的文件描述符; dup2:按指定条件复制文件描述符。,1. 文件控制fcntl 文件控制系统调用fcntl针对文件描述符进行控制。该系统调用格式为: int fcntl(int fd,int cmd,arg); 其中:fd是文件描述符;cmd是控制类型;arg为返回值。 如果该系统调用成功,则返回整数cmd;如果该系统调用失败,则返回-1,表示出错。 arg参数总是一个整数,通常在文件fcntl.h中定义。在作为记录锁用时,指向一个结构的指针。,6.2文件系统类系统调用,fcntl函数有5种功能: (1)当cmd=F_DUPFD时,其功能为复制一个现有的文件描述符。fcntl返回值为新的
5、文件描述符, 该描述符的值为: 最小的大于或等于arg的一个可用的描述符; 与原始操作符一样的某对象的引用; 如果对象是文件(file)的话,则返回一个新的描述符,这个描述符与arg 共享相同的偏移量(offset); 相同的访问模式(读,写或读/写); 相同的文件状态标志(如:两个文件描述符共享相同的状态标志); 与新的文件描述符结合在一起的close-on-exec 标志被设置成交叉式访问execve(2)的系统调用。,6.2文件系统类系统调用,(2)当cmd=F_GETFD或F_SETFD时,其功能为获得设置文件描述符标志,fcntl返回值为响应标志。 cmd=F_GETFD时:取得与文
6、件描述符fd联合close-on-exec标志,类似FD_CLOEXEC。如果返回值和FD_CLOEXEC进行与运算结果是0的话,文件保持交叉式访问exec(),否则如果通过exec运行的话,文件将被关闭(arg 被忽略)。 cmd=F_SETFD时:设置close-on-exec 旗标。该旗标以参数arg 的FD_CLOEXEC位决定。,6.2文件系统类系统调用,(3)当cmd=F_GETFL或F_SETFL时,其功能为获得设置文件状态标志,fcntl返回值为一个正的进程ID或负的进程组ID。 cmd=F_GETFL时:取得fd的文件状态标志,如同下面的描述一样(arg被忽略)。 cmd=F
7、_SETFL时:设置给arg描述符状态标志,可以更改的几个标志是:O_APPEND, O_NONBLOCK,O_SYNC和O_ASYNC。 在修改文件描述符标志或文件状态标志时必须谨慎,先要取得现在的标志值,然后按照希望修改它,最后设置新标志值。不能只是执行F_SETFD或F_SETFL命令,这样会关闭以前设置的标志位。,6.2文件系统类系统调用,(4)当cmd=F_GETOWN或F_SETOWN时,其功能为获得设置异步I/O所有权。 cmd=F_GETOWN时:取得当前正在接收SIGIO或者SIGURG信号的进程id或进程组id,进程组id返回成负值(arg被忽略)。 cmd=F_SETOW
8、N时:设置将接收SIGIO和SIGURG信号的进程id或进程组id,进程组id通过提供负值的arg来说明,否则,arg将被认为是进程的标识符(pid)。,6.2文件系统类系统调用,(5)当cmd=F_GETLK,F_SETLK或F_SETLKW时,其功能为获得设置记录锁。 锁操作包括: 测试属于其他进程的锁并立即返回,指明是否发现其他锁。 设置一个锁并进入睡眠直到成功。 设置一个锁,如果不成功,立即返回。 内核关闭文件(用系统调用close)时,自动释放由某个进程设置的锁。 cmd=F_GETFL和F_SETFL的标志分别为O_NONBLOCK、O_APPEN、O_DIRECT和O_ASYNC
9、。,6.2文件系统类系统调用,O_NONBLOCK为非阻塞I/O;如果read(2)调用没有可读取的数据,或者如果write(2)操作将阻塞,read或write调用返回-1和EAGAIN错误; O_APPEN为强制每次写(write)操作都添加在文件大的末尾,相当于open(2)的O_APPEND标志; O_DIRECT为最小化或去掉reading和writing的缓存影响。系统将企图避免缓存读或写的数据。如果不能够避免缓存,那么它将最小化已经被缓存了的数据造成的影响。如果这个标志用的不够好,将大大的降低性能; O_ASYNC为当I/O可用的时候,允许SIGIO信号发送到进程组。例如:当有数
10、据可以读的时候。,6.2文件系统类系统调用,cmd=F_GETL为通过第三个参数arg(一个指向flock的结构体)取得第一个阻塞lock description指向的的锁。取得的信息将覆盖传到fcntl()的flock结构的信息。如果没有发现能够阻止本次锁(flock)生成的锁,这个结构将不被改变,除非锁的类型被设置成F_UNLCK。 cmd=F_SETLK为按照指向结构体flock的指针的第三个参数arg所描述的锁的信息设置或者清除一个文件segment锁。F_SETLK被用来实现共享(或读)锁 (F_RDLCK)或独占(写)锁(F_WRLCK),同样可以去掉这两种锁(F_UNLCK)。如
11、果共享锁或独占锁不能被设置,fcntl()将立即返回EAGAIN。 cmd=F_SETLKW为除了共享锁或独占锁被其他的锁阻塞这种情况外,该命令和F_SETLK是一样的。如果共享锁或独占锁被其他的锁阻塞,进程将等待直到这个请求能够完成。当fcntl()正在等待文件的某个区域的时候捕捉到一个信号,如果这个信号没有被指定SA_RESTART,fcntl将被中断。,6.2文件系统类系统调用,结构体flock的定义: struct flock short 1_type; /* 锁操作类型:F_RDLCK加读锁;F_WRLCK加写锁;F_UNLCK解锁 */ short 1_whence; /* 锁偏移
12、量SEEK_SET从文件头开始(0);锁偏移量SEEK_CUR从当前文件指针开始(1); */ /* 锁偏移量SEEK_END从文件尾开始(2)。 */ long 1_start; /* 按照1_whence进行解释的字节偏移量 */ long 1_len; /* 欲上锁的字节数,若为0,从1_start到文件尾上锁 */ short 1_pid; /* 对文件上锁的进程ID */ F_GETFD的返回值为响应标志,F_GETFL以及F_GETOWN的返回值为一个正的进程ID或负的进程组ID。,6.2文件系统类系统调用,例 在fcntl设置文件状态标志。 #include #include #
13、include #include #include #define MSG_TRY try againn int main(void) char buf10; int n; int flags; flags = fcntl(STDIN_FILENO, F_GETFL); flags |= O_NONBLOCK; if (fcntl(STDIN_FILENO, F_SETFL, flags) = -1) perror(fcntl); exit(1); ,tryagain: n = read(STDIN_FILENO, buf, 10); if (n 0) if (errno = EAGAIN)
14、sleep(1); write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY); goto tryagain; perror(read stdin); exit(1); write(STDOUT_FILENO, buf, n); return 0; ,6.2文件系统类系统调用,2文件加/解锁flock 系统调用flock用于文件的加锁和解锁。系统调用flock源自于 UNIX的BSD版本,在传统的类 UNIX 操作系统中,系统调用flock() 只适用于劝告锁。但是,Linux 2.6内核利用系统调用 flock实现了共享模式下的强制锁。因此,与fcntl不同,
15、flock只能用于对整个文件进行加锁,而不能用于对记录的加锁。,6.2文件系统类系统调用,系统调用flock的格式为: int flock(int fd, int operation); 其中: fd表示文件描述符; operation表示指定要进行的锁操作,其取值和表示的意义如下: LOCK_SH:表示要创建一个共享锁,在任意时间内,一个文件的共享锁可以被多个进程拥有; LOCK_EX:表示创建一个排他锁,在任意时间内,一个文件的排他锁只能被一个进程拥有; LOCK_UN:表示删除该进程创建的锁; LOCK_MAND:主要是用于共享模式强制锁,可以与LOCK_READ或者 LOCK_WRIT
16、E联合起来使用,从而表示是否允许并发的读操作或者并发的写操作。,6.2文件系统类系统调用,通常情况下,如果加锁请求不能被立即满足,那么系统调用 flock() 会阻塞当前进程。比如,进程想要请求一个排他锁,但此时,已经由其他进程获取了这个锁,那么该进程将会被阻塞。如果想要在没有获得这个排他锁的情况下不阻塞该进程,可以将LOCK_NB 和LOCK_SH或者LOCK_EX联合使用,那么系统就不会阻塞该进程。flock() 所加的锁会对整个文件起作用。,6.2文件系统类系统调用,3. 创建新文件create 系统调用creat创建一个新文件或重写一个旧文件,并将文件描述符fd返回给用户程序。用户利用
17、文件描述符对文件进行读写。 系统调用格式为: int creat(path,smode); char *path; int smode; 该系统调用的返回值为文件描述符。,6.2文件系统类系统调用,其中:path为创建的文件名(包含全路径);smode为文件实际的权限。在文件修改模式命令chmod中,用户对文件读、写、执行的访问权mode用3位8进制数mnk表示(详见文件系统一章中的chmod部分),例如mode=751说明文件的所有者有读、写、执行权,同组用户有读、执行权,其他用户只有执行权限。如果用户先用umask xyz命令对文件的权限作了限制,则实际建立的权限smode就是xyz与mn
18、k作“与”运算的结果,例如xyz=177,smode=177 if (fd = creat(/home/ liuxx /file1, smode) = -1) perror(Cant create file /home/ liuxx /file1); else printf(create /home/liuxx/file1 ok!); exit(0); ,例 在用户目录/home/liuxx/下创建文件file1,该文件的所有者有读、写、执行权,同组用户有读、执行权,其他用户只有执行的权限。,4. 打开文件open 文件创建好以后,必须用系统调用open将文件打开之后才能对文件进行读/写操作。
19、 系统调用格式为: int open(path,rwmode); char *path; int rwmode; 该系统调用返回值为打开文件的描述符。如果打开文件成功,则返回文件描述符,否则返回-1。,6.2文件系统类系统调用,其中path为含有全路径的要打开的文件名;rwmode为头文件fcntl.h中定义的对打开文件的访问模式: rwmode = 0表示可读,O_RDONLY。 rwmode = 1表示可写,O_WRONLY。; rwmode = 2表示可读、可写,O_RDWR。,6.2文件系统类系统调用,例 在用户目录/home/liuxx/下已有文件file1,将该文件打开并且可读、可
20、写。 #include #include #define rwmode 2 int main() int fd; if (fd = open(/home/liuxx/file1, rwmode) = -1) perror(Cant open file /home/liuxx/file1); else printf(open /home/liuxx/file1 ok!); exit(0); ,6.2文件系统类系统调用,5. 关闭文件close 当用户在文件使用完之后不再需要时用系统调用close断开用户程序与文件之间的通路,关闭该文件。 系统调用格式为: int close(fd); int f
21、d; 其中fd为文件描述符,根据fd从用户文件描述符表中得到指向文件表项的指针fp,由fp得到文件表项中的f.count,并对f.count作减1操作。操作结果如果不为0,表示还有进程在使用该文件,此时不能收回文件表项;操作结果为0,表示无进程使用该文件,将此文件表项置空。,6.2文件系统类系统调用,6 读文件read 当文件打开后,可以用系统调用read对文件进行读操作。系统调用read的格式为: int read(fd,buffer,count); int fd; char *buffer; unsigned count; 其中:fd是open返回的文件描述符;buffer是一个缓冲区,用
22、于存放所读的数据;count是要读的字节数;如果系统调用成功,则返回实际读取的字节数。在读时,如果读指针已经到达文件末尾但还没有读够指定的字节数count,也立即停止,所以number的值可以小于等于count。如果试图读一个已被加锁的文件,则read进程必须等待直到锁被打开。 在read系统调用中如果未指定需要读的字节数,则通常是1个字节。,6.2文件系统类系统调用,#include #include #define rwmode 0 int main() int fd; char buffer1024; int n; if (fd = open(/etc/passwd, rwmode) =
23、 -1) perror(Cant open file /etc/passwd);,else printf(open /etc/passwd ok!n); n = read(fd,buffer,sizeof(buffer) - 1); buffern = 0; printf(%sn,buffer); close(fd); exit(0); ,例 首先打开文件/etc/passwd,然后将文件中前1 024字节的内容读到缓冲区buffer中。,#include #include #define rwmode 1 main() int fd1,fd2; char buffer2048; if (fd
24、1 = open(/etc/passwd, rwmode) = = -1) error(First cant open file /etc/passwd); else printf(Firat open /etc/passwd ok!);,if (fd2 = open(/etc/passwd, rwmode) = = -1) error(Second cant open file /etc/passwd); else printf(Second open /etc/passwd ok!); read(fd1,buffer,1024); printf(%sn,buffer); close(fd1
25、); read(fd2,buffer,2048); printf(%sn,buffer); close(fd2); ,例对同一个文件用两个文件描述符读。,7. 写文件write 写系统调用是在文件被open系统调用打开后,从缓冲区buffer将指定字节的内容写到由open返回的文件描述符所指定的文件中。write系统调用格式为: int write(fd,buffer,count); int fd; char *buffer; unsigned count; 其中:fd是open返回的文件描述符,该文件存放由write写入的内容;buffer是一个缓冲区,用于存放要写的内容;count是要写的
26、字节数;如果系统调用成功,则返回实际写的字节数。在写时,如果写指针已经到达文件末尾但还没有写够所指定的字节数count,立即停止,所以number的值可以小于等于count。如果试图写一个已被加锁的文件,则write进程必须等待直到锁被打开。 在write系统调用中如果未指定需要写的字节数,则通常是1个字节。,6.2文件系统类系统调用,例 拷贝文件,该拷贝不保护源文件的权限,也不保护与目标文件相同的文件内容。,if (resource_fd = open(argv1, resounce_mode) = -1) perror(Cant open source file); exit(1); if
27、 (destination_fd = creat(argv2, destination_mode ) = -1) perror(Cant create destination file); exit(1); while (readbytes = read(resource_fd,buffer,FILESIZE) p = buffer; if (readbytes = -1) ,#include #include #include #define resounce_mode 0 #define destination_mode 0774 #define FILESIZE 1024 int mai
28、n(int argc,char *argv) int resource_fd,destination_fd; int readbytes,writtenbytes; char bufferFILESIZE, *p; if (argc != 3) printf(Usage: copy from resource file to destination filen %s src_file dest_filen,argv0); exit(1); ,else if (readbytes0) while (writtenbytes = write(destination_fd, p, readbytes
29、) if (writtenbytes = -1) ,else if (writtenbytes 0) p += writtenbytes; readbytes -= writtenbytes; if (writtenbytes = -1) break; close(resource_fd); close(destination_fd); exit(0); ,通常在文件param.h中用参数NOFILE限制一个用户应用程序能同时打开的文件数,一般NOFILE=20(Linux上一般是256)。,8. 移动文件指针lseek 文件系统调用read和write是对文件的顺序访问,每次操作都紧跟在上次
30、操作之后。如果要通过I/O位置指定实现对文件的随机顺序存取,则需要系统调用lseek的配合使用。系统调用lseek的格式为: int lseek(fd,offset,origin); int fd,origin; long offset,pos; 其中:fd为文件描述符;origin是文件读写位置移动的初始值,特殊点为: SEEK_SET = 0,表示文件开始。 SEEK_CUR = 1,表示文件当前位置。 SEEK_END = 2,表示文件尾。 offset是文件读写位置移动的偏移量,是一个长整型值,如偏移量为0,则为0L,如偏移量为1 034,则为1 034L;返回值是文件读写位置移动到的
31、新的绝对值,即随后的读写开始处,如果系统调用出错,则返回-1。 系统调用lseek依靠调整文件表中的字节偏移量值来实现,其处理文件就像处理一个大的数组一样,非常方便,但是访问速度却比read、write慢。,6.2文件系统类系统调用,#include #include #include #define rwmode 1 int main() int fd,n; long pos,offset; char buffer512; if (fd = open(/home/xiexie/file1, rwmode) = -1) perror(Cant open file /home/netstaff/
32、sev1); else printf(open /home/netstaff/sev1 ok!n);,if (lseek(fd,0L,SEEK_END) = -1) printf(lseek cant moving); close(fd); return -1; else strcpy(buffer,append somethingn); write(fd,buffer,strlen(buffer); printf(write completedn); close(fd); exit(0); ,例 在文件/home/netstaff/sev1的末尾添加内容.,8. 复制已打开的文件描述符dup
33、和dup2 系统调用函数dup和dup2系统调用都用来复制文件描述符。 系统调用dup用于复制oldfd所指的文件描述符。但复制成功时返回最小的尚未被使用的文件描述符。若有错误则返回1,错误代码存入errno中。返回的新文件描述符和参数oldfd指向同一个文件,共享所有的锁定,读写指针,和各项权限或标志位。系统调用dup2用参数newfd指定新文件描述符的数值。若newfd已经被程序使用,系统就会将其关闭以释放该文件描述符;若newfd与oldfd相等,dup2将返回newfd,而不关闭他。dup2调用成功返回新的文件描述符,出错则返回1。 系统调用dup的的格式为: int dup(int
34、fd); 系统调用dup2的的格式为: int dup2(int oldfd,int targetfd);,6.2文件系统类系统调用,例 用dup2复制文件描述符。首先打开了一个文件file1,得到文件描述符oldfd。然后用dup2复制该文件描述符,得到新的文件描述符,dup2在复制完文件描述符oldfd后,立即关闭文件描述符oldfd。,#include #include #include int main(int argc, char *argv) int oldfd,newfd; oldfd = open(file1, (O_RDWR | O_CREATE), 0644 ); newf
35、d = dup2( oldfd, 1 ); close(oldfd); ,6.2文件系统类系统调用,6.2.2 文件系统操作类系统调用,access:确定文件的存取权限; chdir(fchdir):改变当前工作目录; chroot:改变根目录; chmod(fchmod):改变文件模式; chown(fchown):改变文件的拥有者或拥有者组; stat(lstat,fstat):取文件状态信息; statfs(fstatfs):取文件系统信息; readdir(getdents):读取目录项;,mkdir:创建目录; rmdir:删除目录; mknod:创建索引节点; rename:文件重
36、命名; link:创建链接; symlink:创建符号链接; unlink:删除链接; readlink:读符号链接的值; mount:安装文件系统; umount:卸下文件系统; utime(utimes):改变文件的访问修改时间; quotactl:控制磁盘配额。,1确定文件的存取权限access 系统调用access用于检查调用进程对文件是否具有读、写、执行权,此处基于的是真正用户标识符,而不是有效用户标识符。该系统调用的格式为: int access(filename,mode); char * filename; int mode; 其中:filename为调用进程要检查的文件路径名
37、;mode为读、写、执行组合模式。,6.2.2 文件系统操作类系统调用,例 用系统调用access检查文件的访问权限。 #include #include #include #include int main(int argc, char *argv) if (argc 2) printf(Usage: ./input filenamen); exit(1); ,if (access(argv1, F_OK) = -1) puts(File not exists!); exit(2); if (access(argv1, R_OK) = -1) puts(Cant read the file!
38、); else if (access(argv1, R_OK | W_OK) != -1) puts(Can read and write the file); else puts(Can read the file); exit(0); ,6.2.2 文件系统操作类系统调用,2改变当前工作目录chdir与fchdir 系统调用chdir用于改变当前工作目录或指定当前目录。该系统调用格式为: char chdir(directory) 其中参数directory为指定需要改变的目录或当前目录。,6.2.2 文件系统操作类系统调用,6.2.2 文件系统操作类系统调用,例 用系统调用chdir改变
39、进程的当前目录为/bin。 同样,系统调用fchdir也是改变进程的当前工作目录。该系统调用的格式为: intfchdir(int fd) 其中参数fd是目录的文件描述符。,#include #include #include #include int main(int argc, char * argv) if(chdir(/bin) 0) 、 then printf(errorn); else printf(current working directory: %sn,getcwd(NULL, NULL); ,6.2.2 文件系统操作类系统调用,例 用系统调用fchdir改变进程的当前目录
40、为/bin。 #include #include #include #include,main() int fd; fd=open(/bin,O_RDONLY); fchdir(fd); printf(Current Dir: %sn,getcwd(NULL,NULL); close(fd); ,3改变根目录chroot 系统调用chroot用于改变进程的根目录。该系统调用的格式为: int chroot(const char * path); 其中参数path 为所指定的根目录。只有超级用户才允许改变根目录,子进程将继承新的根目录。,6.2.2 文件系统操作类系统调用,例 用系统调用chro
41、ot改变进程的根目录为/bin。 #include #include #include #include main() chroot(“/bin”); printf(Current Root Dir: %sn,getcwd(NULL,NULL); ,6.2.2 文件系统操作类系统调用,4改变文件模式chmod与fchmod 系统调用chmod用于修改文件或目录的访问模式(权限),与命令chmod完全对应。该系统调用的格式为: int chmod(filename,mode); char * filename; int mode; 其中:参数filename为文件或目录名;参数mode为访问模式
42、,见第1章chmod命令 系统调用fchmod也用于改变文件模式。与系统调用chmod不同的是,该系统调用通过文件描述符来指定需要修改模式的文件而不是通过文件名来指定需要修改模式的文件,即系统调用fchmod是针对已经打开的文件进行模式修改。该系统调用的格式为: intfchmod(int fd, mode_tmode) 其中:参数fd为文件描述符;参数mode为访问模式。,6.2.2 文件系统操作类系统调用,6.2.2 文件系统操作类系统调用,例 用系统调用fchmod改变文件test.out的模式。 #include #include #include #include,main() in
43、t fd; fd=open(test.out,O_RDONLY); fchmod(fd,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); close(fd) ); ,5改变文件的拥有者或拥有者组chown与fchown 系统调用chown用于改变文件的拥有者或拥有者组,与命令chown完全对应。该系统调用的格式为: int chown(const char *pathname,uid_t owner,gid_t group); 其中:参数pathname为需要修改的文件路径;参数owner为指定的文件的新拥有者ID,见第1章chown命令;参数group为指定新的拥有者组ID
44、。 更改文件的所有者权限从一定程度上保证了文件的安全,并不是所有的用户都可以修改文件的所有者权限,必须是文件的所有者或组拥有者,或者是系统的超级用户。 同样,系统调用fchown也用于改变文件的拥有者或拥有者组。与系统调用chown不同的是,该系统调用是针对已经打开的文件进行拥有者或组拥有者权限的修改。该系统调用的格式为: int fchown(int fd, uid_towner, gid_t group) 其中:参数fd为需要改变拥有者的文件的文件描述符;参数owner为指定的文件的新拥有者ID;参数group为指定新的拥有者组ID 。,6.2.2 文件系统操作类系统调用,6.2.2 文件
45、系统操作类系统调用,例 用系统调用fchown将文件test.out的拥有者ID和拥有者组ID改为0,0。,#include #include #include #include main() int fd; fd=open(test.out,O_RDONLY); fchown(fd,0,0); close(fd) ); ,6取文件状态信息stat、lstat与fstat 系统调用stat、lstat和fstat用于进程查询文件的状态,返回文件类型、文件大小和文件所有者、文件的存取权限、文件的修改时间、链接计数、索引节点号等文件属性。系统调用stat 、lstat和fstat的格式为: int
46、 stat(path,statbuf); char *path; struct stat *statbuf; int lstat(path,statbuf); char *path; struct stat *statbuf; int fstat(fd,statbuf); int fd; struct stat *statbuf; 其中:path是需要获取信息的文件名,fd是需要获取信息的文件描述符;statbuf是数据结构地址,该数据结构用于存放文件信息。,6.2.2 文件系统操作类系统调用,stat函数通过文件名获得文件的有关信息;fstat通过文件描述符获得已经打开文件的有关信息;lst
47、at函数类似于stat,但是当文件是一个符号连接时,lstat返回该符号连接的有关文件信息,而不是由该符号连接引用的文件的信息。 struct stat结构在文件stat.h中定义,内容如下: struct stat mode_t st_mode;/* 文件模式,包括文件类型、访问许可机制等 */ ino_t st_ino; /* 文件inode号 */ dev_t st_dev;/* 文件驻留的逻辑设备ID*/ dev_t st_rdev;/*设备的ID,用于字符文件或块文件*/ nlink_t st_nlink; /*文件的链接数*/ uid_t st_uid;/*文件拥有者的用户ID*/
48、 gid_t st_gid;/*文件拥有者组的ID*/ off_t st_size;/*文件逻辑长度*/ time_t st_atime; /*文件最后一次访问时间*/ time_t st_mtime; /*文件最后一次修改时间*/ time_t st_ctime; /*文件状态信息最后修改时间*/ long st_blksize;/*I/O预取块大小*/ long st_blocks;/*块预留数*/ ,6.2.2 文件系统操作类系统调用,例 查询文件信息。 #include #include #include #include #define rwmode 0 int main(int a
49、rgc,char *argv) int fd; long pos,offset; char buffer1024; struct stat statbuf; if (argc!= 2) fprintf(stderr, Usage: %s filenamen,argv0); exit(1); ,if (stat(argv1, ,6.2.2 文件系统操作类系统调用,7取文件系统信息statfs与fstatfs 系统调用statfs与fstatfs用于获取文件系统相关信息。 系统调用statfs的格式为: int statfs(const char *path, struct statfs *buf
50、); 系统调用fstatfs的格式为: int fstatfs(int fd, struct statfs *buf); 其中:参数path表示需要查询信息的文件系统的路径名;参数fd表示需要查询信息的文件系统的文件描述符;buf表示用于储存文件系统相关的信息的数据结构,其定义如下:,6.2.2 文件系统操作类系统调用,struct statfs long f_type; /* 文件系统类型 */ long f_bsize; /* 经过优化的传输块大小 */ long f_blocks; /* 文件系统数据块总数 */ long f_bfree; /* 可用块数 */ long f_bavai
51、l; /* 非超级用户可获取的块数 */ long f_files; /* 文件结点总数 */ long f_ffree; /* 可用文件结点数 */ fsid_t f_fsid; /* 文件系统标识 */ long f_namelen; /* 文件名的最大长度 */ ; 如果系统调用成功,返回0;否则返回-1,errno被设为以下的某个值: EACCES: (statfs()文件或路径名中包含的目录不可访问 EBADF : (fstatfs() 文件描述符无效 EFAULT: 内存地址无效 EINTR : 操作由信号中断 EIO : 读写出错 ELOOP : (statfs()解释路径名过程
52、中存在太多的符号连接 ENAMETOOLONG:(statfs() 路径名太长 ENOENT:(statfs() 文件不存在 ENOMEM: 核心内存不足 ENOSYS: 文件系统不支持调用 ENOTDIR:(statfs()路径名中当作目录的组件并非目录 EOVERFLOW:信息溢出,6.2.2 文件系统操作类系统调用,6.2.2 文件系统操作类系统调用,例 查询文件系统信息。 #include #include #include #include #include #include #define GB (1024*1024*1024) int main(int argc, char* a
53、rgv) struct statfs buf; long long total; if(argc != 2), printf(usage: input filesystem namen); exit(1); if(statfs(argv1, ,8取目录项readdir与getdents 系统调用readdir用于读取目录,返回目录中的文件名称。 该系统调用的格式为: readdir(dir_stream); 其中参数dir_stream用于指定目录对象。,6.2.2 文件系统操作类系统调用,例 查询根目录信息。 #include #include #include #include #incl
54、ude int main(int argc,char *argv) DIR * dir; struct dirent * ptr; int i;,if(argc=1) dir=opendir(./); else dir=opendir(argv1); while(ptr=readdir(dir)!=NULL) printf(d_name: %sn,ptr-d_name); closedir(dir); return 0; ,9创建目录mkdir与删除目录rmdir 系统调用mkdir用于创建目录。该系统调用的格式为: int mkdir(char * dir, int mode); 其中:参数
55、dir为需要创建目录的路径;mode为文件的访问权限。 系统调用rmdir用于删除一个空目录。该系统调用的格式为: int mkdir(char * dir); 其中参数dir为需要删除目录的路径,6.2.2 文件系统操作类系统调用,例 创建文件拥有者、拥有者组和其他用户都能读写执行的目录/home/stu01,然后再删除该目录。 #include #include #include #include int main() int status; status=mkdir(/home/stu01,0777); if status = = -1 then printf(Unable to cre
56、ate directory); exit(1); ,else printf(Directory created); status=rmdir(/home/stu01); if status = = -1 then printf(Unable to delete directory); exit(1); else printf(Directory deleted); exit(0); ,10创建索引节点mknod 该系统调用用于建立一个目录项和一个特殊文件(设备文件)的对应索引节点。系统调用格式为: int mknod(const char *pathname, mode_t mode, dev
57、_t dev); 其中参数pathname为文件名;mode为文件的访问模式;Dev_t为设备编号,在/linux/types.h文件中定义,目前是一个32位整数,12位表示主设备号,20位表示次设备号,通过设备编号获取主次设备号。,6.2.2 文件系统操作类系统调用,例 创建设备文件/dev/xyz对应的索引节点。 #include #include #include #include int main() int result;,result=mknod(/dev/xyz,S_IFCHR,(dev_t)(4194304000); if(result 1) printf(mknod fail
58、ed n); return result; else printf(mknod success); exit(0); ,11为文件重命名rename 系统调用rename为改变文件的名称或者位置,如果目标已存在,将被自动覆盖。该系统调用的格式为: int rename(const char *oldpath, const char *newpath); 其中参数: oldpath为旧文件名; newpath为新文件名或者新位置。 返回说明: 成功执行时,返回0。失败返回-1。,6.2.2 文件系统操作类系统调用,errno被设为以下的某个值: EACCES:权能不足; EBUSY:参数oldp
59、ath或者newpath代表的是目录,而且一些进程正在使用它们; EFAULT: 内存空间不可访问; EINVAL:参数无效; EISDIR:newpath是一个现存的目录,而oldpath不是目录; ELOOP :路径解析的过程中存在太多的符号连接; EMLINK:目录超出允许的最大连接数; ENAMETOOLONG:路径名超出可允许的长度; ENOENT:路径名部分内容表示的目录不存在; ENOMEM: 核心内存不足; ENOSPC: 磁盘配额限制或空间不足; ENOTDIR:路径名的部分内容不是目录; EPERM : 包含路径名的文件系统不支持建立目录; EROFS:文件系统只读; ENOTEMPTY:newpath是一个非空的目录,除了. 和 .以外,还包含其它
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- DB54-T 0418-2024 传统青稞酒原料 青稞质量要求
- 儿童心理健康与压力管理
- 办写字楼租赁合同书(32篇)
- 安全生产知识考试题库及答案大全
- 班主任与学生交流沟通的方式公开课教学设计课件资料
- 北京市房山区2019-2021年(三年)中考二模英语试卷分类汇编:阅读理解
- 2025届贵州省长顺县民族高级中学高一化学第二学期期末预测试题含解析
- 2025届山东省临沂市沂南县化学高一下期末教学质量检测试题含解析
- 湖北省武汉市常青联合体2024-2025学年度高一下学期期末考试语文试题(含答案)
- 工会全民读书活动方案
- 人教版(2024)七年级下册英语UNIT 5 Here and Now 综合素质评价测试卷(含答案)
- 第7课《谁是最可爱的人》课件-2024-2025学年统编版语文七年级下册
- 接待服务规范手册
- 宫颈癌的早期症状:及时发现早期宫颈癌的线索
- DB11-T 896-2020 苹果生产技术规程
- 福建省厦门市(2024年-2025年小学六年级语文)统编版小升初真题(上学期)试卷及答案
- 叉车蓄电池知识培训课件
- 2024年09月2024秋季中国工商银行湖南分行校园招聘620人笔试历年参考题库附带答案详解
- 台球助教培训流程
- 国家开放大学《社会保障基础》期末考试题库
- 【MOOC】国际经济法学-西南政法大学 中国大学慕课MOOC答案
评论
0/150
提交评论