• C++之Linux syscall实例总结(二百四十六)


    简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

    优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀

    人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

    更多原创,欢迎关注:Android系统攻城狮

    欢迎关注Android系统攻城狮

    1.前言

    本篇目的:理解Linux的syscall作用和用法。

    2.Linux syscall介绍

    Linux的系统调用(System Call,简称syscall)是用户态程序与内核态之间进行交互的重要接口。通过系统调用,用户程序可以请求操作系统内核提供的特权功能,例如文件操作、进程管理、网络通信等。

    Linux系统中的系统调用通常采用软中断的方式实现。当用户程序需要使用系统调用时,它会通过指令将处理器从用户态切换到内核态,并触发软中断异常。操作系统内核会根据中断号(系统调用号)来确定需要执行的系统调用函数,进行相应的处理,然后返回结果给用户程序。

    Linux内核提供了丰富的系统调用接口,以满足用户程序的需求。一些常见的系统调用包括:

    1. 文件系统相关的系统调用:用于进行文件的打开、读写、关闭、重命名、删除等操作,如openreadwritecloserenameunlink等。

    2. 进程管理相关的系统调用:用于创建、执行、等待和终止进程,以及进程间通信,如forkexecwaitexitkillpipe等。

    3. 内存管理相关的系统调用:用于分配和释放内存,以及修改内存保护属性,如brkmmapmunmapmprotect等。

    4. 网络通信相关的系统调用:用于创建和管理网络连接,进行数据的发送和接收,如socketbindlistenacceptconnectsendrecv等。

    5. 时间和时钟相关的系统调用:用于获取当前时间、设置定时器等,如timegettimeofdayclock_gettime等。

    6. 设备和驱动程序相关的系统调用:用于访问硬件设备和驱动程序,如ioctl等。

    使用系统调用需要遵循一定的规范和约定,通常包括以下几个步骤:

    1. 选择适当的系统调用:根据程序的需求,选择合适的系统调用来执行所需的操作。

    2. 设置系统调用参数:根据系统调用的要求,设置相应的参数值。系统调用的参数通常是通过寄存器传递的,具体的参数传递方式和数量依赖于架构和具体的系统调用。

    3. 执行系统调用:通过触发软中断或使用特定的指令,将处理器从用户态切换到内核态,并执行相应的系统调用函数。

    4. 处理返回值:系统调用执行完毕后,将结果返回给用户程序。通常,返回值的含义与具体的系统调用有关,返回值可能包含有用的信息或错误码。

    3.syscall实例

    1. 读取文件(read):

    #include 
    #include 
    #include 
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2. 写入文件(write):

    #include 
    #include 
    #include 
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3. 创建目录(mkdir):

    #include 
    #include 
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4. 修改文件权限(chmod):

    #include 
    #include 
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    5. 创建软链接(symlink):

    #include 
    #include 
    #include 
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    6. 删除文件(unlink):

    #include 
    #include 
    #include 
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    7. 获取当前时间戳(time):

    #include 
    #include 
    #include 
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    MATLAB矩阵的行列式、MATLAB逆矩阵
    数据结构和算法(1):开始
    排序算法3:归并排序与计数排序
    前端页面渲染方式CSR、SSR、SSG
    这个锂电池保护方案来自TIDA-010030
    Mysql进阶学习(八)DDL语言+数据类型和DTL语言
    浅析云计算领域的专业名词
    双非渣渣的上岸之路!备战 60 天,三战滴滴侥幸收获 Offer
    Vue3+TS+Vite+NaiveUI搭建一个项目骨架
    windows使用vim编辑文本powershell
  • 原文地址:https://blog.csdn.net/u010164190/article/details/134055763