简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
1.前言
本篇目的:理解Linux的syscall作用和用法。
2.Linux syscall介绍
Linux的系统调用(System Call,简称syscall)是用户态程序与内核态之间进行交互的重要接口。通过系统调用,用户程序可以请求操作系统内核提供的特权功能,例如文件操作、进程管理、网络通信等。
Linux系统中的系统调用通常采用软中断的方式实现。当用户程序需要使用系统调用时,它会通过指令将处理器从用户态切换到内核态,并触发软中断异常。操作系统内核会根据中断号(系统调用号)来确定需要执行的系统调用函数,进行相应的处理,然后返回结果给用户程序。
Linux内核提供了丰富的系统调用接口,以满足用户程序的需求。一些常见的系统调用包括:
-
文件系统相关的系统调用:用于进行文件的打开、读写、关闭、重命名、删除等操作,如
open
、read
、write
、close
、rename
、unlink
等。 -
进程管理相关的系统调用:用于创建、执行、等待和终止进程,以及进程间通信,如
fork
、exec
、wait
、exit
、kill
、pipe
等。 -
内存管理相关的系统调用:用于分配和释放内存,以及修改内存保护属性,如
brk
、mmap
、munmap
、mprotect
等。 -
网络通信相关的系统调用:用于创建和管理网络连接,进行数据的发送和接收,如
socket
、bind
、listen
、accept
、connect
、send
、recv
等。 -
时间和时钟相关的系统调用:用于获取当前时间、设置定时器等,如
time
、gettimeofday
、clock_gettime
等。 -
设备和驱动程序相关的系统调用:用于访问硬件设备和驱动程序,如
ioctl
等。
使用系统调用需要遵循一定的规范和约定,通常包括以下几个步骤:
-
选择适当的系统调用:根据程序的需求,选择合适的系统调用来执行所需的操作。
-
设置系统调用参数:根据系统调用的要求,设置相应的参数值。系统调用的参数通常是通过寄存器传递的,具体的参数传递方式和数量依赖于架构和具体的系统调用。
-
执行系统调用:通过触发软中断或使用特定的指令,将处理器从用户态切换到内核态,并执行相应的系统调用函数。
-
处理返回值:系统调用执行完毕后,将结果返回给用户程序。通常,返回值的含义与具体的系统调用有关,返回值可能包含有用的信息或错误码。
3.syscall实例
1. 读取文件(read
):
#include <iostream>
#include <unistd.h>
#include <sys/syscall.h>
int main() {
int fd = 0; // 标准输入文件描述符
char buffer[100];
ssize_t num_bytes;
num_bytes = syscall(SYS_read, fd, buffer, sizeof(buffer));
if (num_bytes > 0) {
std::cout << "读取到的内容:" << std::string(buffer, num_bytes) << std::endl;
} else {
std::cout << "读取文件失败" << std::endl;
}
return 0;
}
2. 写入文件(write
):
#include <iostream>
#include <unistd.h>
#include <sys/syscall.h>
int main() {
int fd = 1; // 标准输出文件描述符
char buffer[] = "Hello, syscall!";
ssize_t num_bytes;
num_bytes = syscall(SYS_write, fd, buffer, sizeof(buffer) - 1);
if (num_bytes > 0) {
std::cout << "成功写入 " << num_bytes << " 字节" << std::endl;
} else {
std::cout << "写入文件失败" << std::endl;
}
return 0;
}
3. 创建目录(mkdir
):
#include <iostream>
#include <sys/syscall.h>
int main() {
const char* path = "my_directory";
int result;
result = syscall(SYS_mkdir, path, 0777);
if (result == 0) {
std::cout << "成功创建目录:" << path << std::endl;
} else {
std::cout << "创建目录失败" << std::endl;
}
return 0;
}
4. 修改文件权限(chmod
):
#include <iostream>
#include <sys/syscall.h>
int main() {
const char* path = "file.txt";
mode_t mode = S_IRUSR | S_IWUSR; // 设置用户读写权限
int result;
result = syscall(SYS_chmod, path, mode);
if (result == 0) {
std::cout << "成功修改文件权限" << std::endl;
} else {
std::cout << "修改文件权限失败" << std::endl;
}
return 0;
}
5. 创建软链接(symlink
):
#include <iostream>
#include <unistd.h>
#include <sys/syscall.h>
int main() {
const char* target = "file.txt";
const char* linkpath = "mylink";
int result;
result = syscall(SYS_symlink, target, linkpath);
if (result == 0) {
std::cout << "成功创建软链接" << std::endl;
} else {
std::cout << "创建软链接失败" << std::endl;
}
return 0;
}
6. 删除文件(unlink
):
#include <iostream>
#include <unistd.h>
#include <sys/syscall.h>
int main() {
const char* path = "file.txt";
int result;
result = syscall(SYS_unlink, path);
if (result == 0) {
std::cout << "成功删除文件:" << path << std::endl;
} else {
std::cout << "删除文件失败" << std::endl;
}
return 0;
}
7. 获取当前时间戳(time
):
#include <iostream>
#include <sys/time.h>
#include <sys/syscall.h>
int main() {
struct timeval tv;
int result;
result = syscall(SYS_time, &tv, NULL);
if (result == 0) {
std::cout << "当前时间戳:" << tv.tv_sec << std::endl;
} else {
std::cout << "获取时间戳失败" << std::endl;
}
return 0;
}