所谓系统调用其实是操作系统提供给用户程序的一组“特殊”函数接口,可以直接这么去理解,操作系统是一个很大的“函数库”,它给程序员提供了很多可以调用的函数。
系统调用按照功能逻辑大致可分为:进程控制、进程间通信、文件系统控制、系统控制、内存管理、网络管理、socket控制、用户管理。在Linux的不同版本中,提供了两三百个系统调用,用户程序可以通过这组接口获得操作系统(内核)提供的服务。例如,用户可以通过文件系统相关的系统调用,请求系统打开文件、关闭文件或读写文件。下图是类UNIX系统的软件层次图:
应用程序可以通过系统调用接口陷入内核,内核再通过相应驱动程序去控制底层的硬件。当然应用程序进行系统调用有多种方式,如下图所示:(1)应用程序直接调用系统调用,(2)通过shell命令,(3)通过标准库函数,其实这些库函数也都是系统调用的封装出来的,比如fread()函数就是封装系统调用read()而来的,当然并不是所有的系统调用都被封装成了库函数。
1. 系统调用I/O函数
系统调用中操作I/O的函数,都是针对文件描述符的,通过文件描述符可以直接对相应的文件进行操作,如:open、close、write 、read、ioctl。就像我C语言博文中关于文件操作那篇一样,无非那些是标准库下的函数,是对系统调用中操作I/O的函数封装后的库函数,原理都是一样,C标准库中有关文件的FILE结构体中包含了文件描述符和一些关于流缓冲区的信息。
这里简单解释下文件描述符的概念,文件描述符本质就是一个非负整数,是你在用open系统调用打开现存文件或新建文件时,系统(内核)返回给你的,它用来指定已打开的文件。
#define STDIN_FILENO 0 //标准输入的文件描述符
#define STDOUT_FILENO 1 //标准输出的文件描述符
#define STDERR_FILENO 2 //标准错误的文件描述符
上面这三个是特殊的文件描述符,在程序运行起来后是默认打开的。
1.1 open函数:打开一个文件
当文件存在时使用:int open(const char *pathname, int flags);
当文件不存在时使用:int open(const char *pathname, int flags, mode_t mode);
参数:pathname:文件的路径及文件名。
flags:open函数的行为标志。
mode:文件权限(可读、可写、可执行)的设置。
返回值:成功返回打开的文件描述符,失败返回-1,可以利用perror去查看原因(下同)。
1.2 close函数:关闭一个文件
int close(int fd);
参数:fd是调用open打开文件返回的文件描述符。
返回值:成功返回0,失败返回-1。
1.3 read/write函数:把指定数目的数据读到内存或写到文件
ssize_t read/write(int fd, const void *addr, size_t count);
参数:fd:文件描述符。
addr:内存首地址/数据首地址。
count:写入数据的字节个数。
返回值:成功返回实际读出/写入数据的字节个数,失败返回-1。
1.4 remove函数:删除文件
int remove(const char *pathname);
参数:pathname :文件的路名+文件名。
返回值:成功返回0,失败返回-1。
1.5 例系统调用实现cp命令
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <unistd.h>//write read
#include <sys/types.h> //open
#include <sys/stat.h>
#include <fcntl.h>
#define BUF_SIZE 1024
int main(int argc,char *argv[])
{
int fd_src,fd_dest;
char buf[BUF_SIZE]="";
int ret = 0;
if(argc != 3)
{
printf("miss parameters,please check your
input!\n");
exit(-1);
}
else
{
fd_src = open(argv[1],O_RDONLY);
fd_dest = open(argv[2],O_WRONLY|O_CREAT,0666);
if((fd_src == -1) || (fd_dest == -1))
{
perror("open
file");
exit(-1);
}
//拷贝到目的文件
ret = read(fd_src,buf,BUF_SIZE);
while(ret > 0)
{
ret
= write(fd_dest,buf,ret);
if(ret
== -1)
{
perror("write file");
exit(1);
}
ret
= read(fd_src,buf,BUF_SIZE);
}
close(fd_src);
close(fd_dest);
}
return 0;
}
原文:http://blog.csdn.net/liuhb569620660/article/details/21561997