【Linux】系统调用和库函数汇总整理
Linux系统调用和库函数是操作系统和应用程序之间的重要接口。系统调用允许应用程序与内核进行交互,而库函数则为开发者提供了更高层次的抽象和更友好的接口。下面是对Linux系统调用和库函数的详细汇总整理。
系统调用
系统调用是操作系统提供的一组接口,允许用户空间的应用程序请求内核执行特定的任务。系统调用通常涉及内核态和用户态之间的上下文切换。
文件操作
open():
int open(const char *pathname, int flags[, ...]): 打开或创建文件。参数pathname指定文件路径,flags指定打开模式。 close():
int close(int filedes): 关闭文件描述符。参数filedes是文件描述符。 read():
ssize_t read(int filedes, void *buf, size_t nbyte): 从文件描述符读取数据。参数filedes是文件描述符,buf是缓冲区指针,nbyte是要读取的字节数。 write():
ssize_t write(int filedes, const void *buf, size_t nbyte): 向文件描述符写入数据。参数filedes是文件描述符,buf是缓冲区指针,nbyte是要写入的字节数。 lseek():
off_t lseek(int filedes, off_t offset, int whence): 移动文件位置指示器。参数filedes是文件描述符,offset是偏移量,whence指定计算偏移量的基准。 fstat():
int fstat(int filedes, struct stat *buf): 获取文件的状态。参数filedes是文件描述符,buf是存放状态信息的结构体指针。 fstatfs():
int fstatfs(int filedes, struct statfs *buf): 获取文件系统的状态。参数filedes是文件描述符,buf是存放状态信息的结构体指针。 mkdir():
int mkdir(const char *pathname, mode_t mode): 创建目录。参数pathname指定目录路径,mode指定权限掩码。 rmdir():
int rmdir(const char *pathname): 删除空目录。参数pathname指定目录路径。 rename():
int rename(const char *oldpath, const char *newpath): 重命名文件或目录。参数oldpath和newpath分别指定旧路径和新路径。 unlink():
int unlink(const char *pathname): 删除文件。参数pathname指定文件路径。
进程控制
fork():
pid_t fork(void): 创建子进程。返回值:在父进程中返回子进程的PID,在子进程中返回0。 vfork():
pid_t vfork(void): 类似于fork(),但在子进程中执行完_exit()或longjmp()前,父进程会被阻塞。返回值:同fork()。 execve():
int execve(const char *filename, char *const argv[], char *const envp[]): 执行新的程序。参数filename指定程序路径,argv是参数数组,envp是环境变量数组。 wait():
pid_t wait(int *status): 等待任意一个子进程结束,并获取其状态。参数status可以通过宏如WIFEXITED()、WEXITSTATUS()等解析进程的状态。 waitpid():
pid_t waitpid(pid_t pid, int *status, int options): 等待指定的子进程结束,并获取其状态。参数pid可以指定等待哪个子进程;options可以指定等待的行为,如WNOHANG表示非阻塞等待。 exit():
void _exit(int status): 终止进程。参数status是退出状态。
内存管理
mmap():
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset): 映射文件或设备到进程的地址空间。参数addr是映射起始地址,length是映射长度,prot是保护标志,flags是映射标志,fd是文件描述符,offset是文件偏移量。 munmap():
int munmap(void *addr, size_t length): 取消映射。参数addr是映射起始地址,length是映射长度。
网络通信
socket():
int socket(int domain, int type, int protocol): 创建套接字。参数domain指定地址家族,type指定套接字类型,protocol指定协议。 bind():
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen): 绑定套接字到特定的地址和端口。参数sockfd是套接字描述符,addr是指向地址结构的指针,addrlen是地址结构的长度。 listen():
int listen(int sockfd, int backlog): 将套接字置于监听状态。参数sockfd是套接字描述符,backlog是连接队列的最大长度。 accept():
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen): 接受客户端的连接请求。参数sockfd是监听套接字描述符,addr和addrlen用于返回客户端的地址信息。 connect():
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen): 连接到服务器。参数sockfd是套接字描述符,addr和addrlen指定服务器的地址信息。 send():
ssize_t send(int sockfd, const void *buf, size_t len, int flags): 向套接字发送数据。参数sockfd是套接字描述符,buf是指向数据缓冲区的指针,len是数据长度,flags可以指定一些选项。 recv():
ssize_t recv(int sockfd, void *buf, size_t len, int flags): 从套接字接收数据。参数sockfd是套接字描述符,buf是指向数据缓冲区的指针,len是数据长度,flags可以指定一些选项。
时间和日期
time():
time_t time(time_t *timer): 获取当前时间。参数timer可以指定存放时间的变量,如果为NULL,则返回当前时间。 clock_gettime():
int clock_gettime(clockid_t clk_id, struct timespec *tp): 获取当前时间或进程时间。参数clk_id指定要获取的时间类型,tp是存放时间信息的结构体指针。 nanosleep():
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp): 休眠指定的时间。参数rqtp指定要求的睡眠时间,rmtp用于返回剩余的未完成的睡眠时间。
信号处理
kill():
int kill(pid_t pid, int sig): 发送信号给指定的进程。参数pid指定进程ID,sig指定信号类型。 raise():
int raise(int sig): 发送信号给当前进程。参数sig指定信号类型。 pause():
int pause(void): 暂停当前进程,直到接收到信号。 sigaction():
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact): 设置信号处理函数和信号行为。参数signum指定信号编号,act指定新的信号处理行为,oldact用于返回旧的行为。
示例代码
以下是一个简单的示例,展示如何在 Linux 系统上使用 C 语言的系统调用来创建文件、写入内容、然后读取文件内容:
1#include
2#include
3#include
4#include
5#include
6
7int main() {
8 int filedes;
9 char filename[] = "example.txt";
10 char buffer[] = "Hello, World!";
11 char read_buffer[1024] = {0};
12
13 // 创建或打开文件
14 filedes = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
15 if (filedes == -1) {
16 perror("无法打开文件");
17 exit(EXIT_FAILURE);
18 }
19
20 // 写入文件
21 ssize_t bytes_written = write(filedes, buffer, strlen(buffer));
22 if (bytes_written == -1) {
23 perror("无法写入文件");
24 close(filedes);
25 exit(EXIT_FAILURE);
26 }
27
28 // 移动文件位置指示器到文件开头
29 lseek(filedes, 0, SEEK_SET);
30
31 // 读取文件内容
32 ssize_t bytes_read = read(filedes, read_buffer, sizeof(read_buffer) - 1);
33 if (bytes_read == -1) {
34 perror("无法读取文件");
35 close(filedes);
36 exit(EXIT_FAILURE);
37 }
38 read_buffer[bytes_read] = '\0'; // 确保字符串以空字符结尾
39 printf("文件内容: %s\n", read_buffer);
40
41 // 关闭文件
42 if (close(filedes) == -1) {
43 perror("无法关闭文件");
44 exit(EXIT_FAILURE);
45 }
46
47 return 0;
48}
库函数
库函数是编译器提供的标准库或第三方库中封装好的函数,它们通常是对系统调用的封装,提供更高级别的抽象和更友好的接口。
文件操作
fopen():
FILE *fopen(const char *path, const char *mode): 打开文件。参数path指定文件路径,mode指定打开模式。 fclose():
int fclose(FILE *stream): 关闭文件流。参数stream是文件流指针。 fread():
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream): 从文件读取数据。参数ptr是缓冲区指针,size是每个元素的大小,nitems是元素数量,stream是文件流指针。 fwrite():
size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream): 向文件写入数据。参数ptr是缓冲区指针,size是每个元素的大小,nitems是元素数量,stream是文件流指针。 fseek():
int fseek(FILE *stream, long offset, int whence): 移动文件位置指示器。参数stream是文件流指针,offset是偏移量,whence指定计算偏移量的基准。 ftell():
long ftell(FILE *stream): 获取当前文件位置指示器的位置。参数stream是文件流指针。 ferror():
int ferror(FILE *stream): 检查错误状态。参数stream是文件流指针。 feof():
int feof(FILE *stream): 检查是否到达文件末尾。参数stream是文件流指针。
字符串处理
strlen():
size_t strlen(const char *s): 计算字符串长度。参数s是字符串指针。 strcpy():
char *strcpy(char *dest, const char *src): 复制字符串。参数dest和src分别是目标和源字符串指针。 strcat():
char *strcat(char *dest, const char *src): 连接字符串。参数dest和src分别是目标和源字符串指针。 strcmp():
int strcmp(const char *s1, const char *s2): 比较字符串。参数s1和s2是字符串指针。 sprintf():
size_t sprintf(char *str, const char *format, ...): 格式化输出到字符串。参数str是字符串指针,format是格式字符串。
数学函数
sqrt():
double sqrt(double x): 计算平方根。参数x是双精度浮点数。 sin():
double sin(double x): 计算正弦值。参数x是双精度浮点数。 cos():
double cos(double x): 计算余弦值。参数x是双精度浮点数。 exp():
double exp(double x): 计算指数函数。参数x是双精度浮点数。 log():
double log(double x): 计算自然对数。参数x是双精度浮点数。
内存操作
malloc():
void *malloc(size_t size): 分配内存。参数size是内存大小。 free():
void free(void *ptr): 释放内存。参数ptr是内存指针。 memcpy():
void *memcpy(void *dest, const void *src, size_t n): 复制内存区域。参数dest和src分别是目标和源指针,n是复制的字节数。 memset():
void *memset(void *ptr, int value, size_t num): 设置内存区域的内容。参数ptr是内存指针,value是填充值,num是字节数。 realloc():
void *realloc(void *ptr, size_t size): 重新分配内存。参数ptr是内存指针,size是新内存大小。
注意事项
在进行系统调用或库函数调用时,务必检查函数的返回值以确保操作成功。使用文件后记得及时关闭,以释放系统资源。对于二进制文件,应使用库函数的 "rb" 和 "wb" 模式。在处理大文件时,考虑使用缓冲或分块读取以提高效率。跨平台编程时要注意不同操作系统之间的 API 差异。
系统调用和库函数是编程中的基础组成部分,几乎所有的应用程序都会涉及到它们的使用。理解和熟练掌握这些操作对于编写可靠、高效的程序至关重要。