今天分享三种方法实现Linux系统调用,感兴趣的朋友可以参考一下
系统调用(System Call)是操作系统为在用户态运行的进程与硬件设备(如CPU、磁盘、打印机等)进行交互提供的一组接口。当用户进程需要发生系统调用时,CPU 通过软中断切换到内核态开始执行内核系统调用函数。下面介绍Linux 下三种发生系统调用的方法:
一、通过 glibc 提供的库函数
glibc 是 Linux 下使用的开源的标准 C 库,它是 GNU 发布的 libc 库,即运行时库。glibc 为程序员提供丰富的 API(Application Programming Interface),除了例如字符串处理、数学运算等用户态服务之外,最重要的是封装了操作系统提供的系统服务,即系统调用的封装。那么glibc提供的系统调用API与内核特定的系统调用之间的关系是什么呢?
通常情况,每个特定的系统调用对应了至少一个 glibc 封装的库函数,如系统提供的打开文件系统调用 sys_open 对应的是 glibc 中的 open 函数; 其次,glibc 一个单独的 API 可能调用多个系统调用,如 glibc 提供的 printf 函数就会调用如 sys_open、sys_mmap、sys_write、sys_close 等等系统调用; 另外,多个 API 也可能只对应同一个系统调用,如glibc 下实现的 malloc、calloc、free 等函数用来分配和释放内存,都利用了内核的 sys_brk 的系统调用。
举例来说,我们通过 glibc 提供的chmod 函数来改变文件 etc/passwd 的属性为 444:
#include #include #include #include int main(){ int rc; rc = chmod("/etc/passwd", 0444); if (rc == -1) fprintf(stderr, "chmod failed, errno = %d\n", errno); else printf("chmod success!\n"); return 0;}
在普通用户下编译运用,输出结果为:
chmod failed, errno = 1
上面系统调用返回的值为-1,说明系统调用失败,错误码为1,在 /usr/include/asm-generic/errno-base.h 文件中有如下错误代码说明:
#define EPERM 1 /* Operation not permitted */(http://www.xichangnk.com)
即无权限进行该操作,我们以普通用户权限是无法修改 /etc/passwd 文件的属性的,结果正确。
二、使用 syscall 直接调用
使用上面的方法有很多好处,首先你无须知道更多的细节,如 chmod 系统调用号,你只需了解 glibc 提供的 API 的原型;其次,该方法具有更好的移植性,你可以很轻松将该程序移植到其他平台,或者将 glibc 库换成其它库,程序只需做少量改动。
但有点不足是,如果 glibc 没有封装某个内核提供的系统调用时,我就没办法通过上面的方法来调用该系统调用。如我自己通过编译内核增加了一个系统调用,这时 glibc 不可能有你新增系统调用的封装 API,此时我们可以利用 glibc 提供的syscall 函数直接调用。该函数定义在 unistd.h 头文件中,函数原型如下:
long int syscall (long int sysno, ...)
sysno 是系统调用号,每个系统调用都有唯一的系统调用号来标识。在 sys/syscall.h 中有所有可能的系统调用号的宏定义。 ... 为剩余可变长的参数,为系统调用所带的参数,根据系统调用的不同,可带0~5个不等的参数,如果超过特定系统调用能带的参数,多余的参数被忽略。 返回值 该函数返回值为特定系统调用的返回值,在系统调用成功之后你可以将该返回值转化为特定的类型,如果系统调用失败则返回 -1,错误代码存放在 errno 中。
今天分享三种方法实现Linux系统调用,感兴趣的朋友可以参考一下的更多相关文章
- Java实现ping功能的三种方法及Linux的区分
前大半部份转自:https://blog.csdn.net/futudeniaodan/article/details/52317650 检测设备的运行状态,有的是使用ping的方式来检测的.所以需要 ...
- 【转】三种方法让你在I2C通信中同时和多个从机通信
ref:http://tieba.baidu.com/p/3769008030 对于不同地址的模块就不用多说了,直接分别对其地址进行通信即可.那么若拿到相同地址的模块,或者直接是相同的多个模块怎么办呢 ...
- Linux下查看磁盘挂载的三种方法
Linux下查看磁盘挂载的三种方法 2009-06-05 23:17 好久没有更新日志了,呵呵.不是没有要写的东东.实在抽不出时间来写,要准备公司的考试呢,C++考试.已经有七个月没有写C++代码了, ...
- linux 环境变量PATH路径的三种方法
转:http://www.jb51.net/LINUXjishu/150167.html 总结:修改1.#PATH=$PATH:/etc/apache/bin 或者#vi /etc/profile ...
- Linux系统下修改环境变量PATH路径的三种方法
这里介绍Linux的知识,比如把/etc/apache/bin目录添加到PATH中有三种方法,看完之后你将学会Linux系统下如何修改环境变量PATH路径,需要的朋友可以参考下 电脑中必不可少的就是操 ...
- linux动态库默认搜索路径设置的三种方法
众所周知, Linux 动态库的默认搜索路径是 /lib 和 /usr/lib .动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两 ...
- linux清空文件内容的三种方法
linux系统中清空文件内容的三种方法 1.使用vi/vim命令打开文件后,输入"%d"清空,后保存即可.但当文件内容较大时,处理较慢,命令如下:vim file_name:%d: ...
- Ubuntu Linux系统三种方法添加本地软件库
闲着没事教教大家以Ubuntu Linux系统三种方法添加本地软件库,ubuntu Linux使用本地软件包作为安装源——转2007-04-26 19:47新手重新系统的概率很高,每次重装系统后都要经 ...
- Linux 添加开机启动项的三种方法
linux 添加开机启动项的三种方法. (1)编辑文件 /etc/rc.local 输入命令:vim /etc/rc.local 将出现类似如下的文本片段: #!/bin/sh## This scri ...
随机推荐
- IIS8的SNI功能实现同一服务器多HTTPS站点
名词解释: SNI指是一项用于改善SSL/TLS的技术,在SSLv3/TLSv1中被启用.它允许客户端在发起SSL握手请求时(具体说来,是客户端发出SSL请求中的ClientHello阶段),就提交请 ...
- 2018-2019-2 网络对抗技术 20165232 Exp4 恶意代码分析
2018-2019-2 网络对抗技术 20165232 Exp4 恶意代码分析 1.实践目标 监控你自己系统的运行状态,看有没有可疑的程序在运行. 分析一个恶意软件,就分析Exp2或Exp3中生成后门 ...
- Java IO系列之二:NIO基本操作
核心部分 NIO( New Input/ Output) , 引入了一种基于通道和缓冲区的 I/O 方式,NIO 是一种同步非阻塞的 IO 模型.同步是指线程不断轮询 IO 事件是否就绪,非阻塞是指 ...
- Eclipse - 安装lombok后注解无效
安装 lombok lombok 的安装过程挺简单的,网上已经有很多相关的博客,这里就不在多说了,可以参考这篇:eclipse集成lombok注解不起作用 但是我按照网上的方式安装之后,注解一直不起作 ...
- Aras 发布Web Services
https://blog.csdn.net/plm888/article/details/10890173
- JS数组(JSON)整合篇-方法整理
遍历:arr_Param.forEach(function (item, i) {}); 反序排序:arr_Param.reverse(); 合并数组:arr_Param.push.apply(arr ...
- Python的一些高级特性以及反序列化漏洞
0x01 简述 文章主要记录一下python高级特性以及安全相关的问题 python作为脚本语言,其作为高级语言是由c语言开发的,关于python的编译和链接可以看向这里https://github. ...
- 全排列递归算法(元素有重复与无重复,C++实现)
元素无重复: 如:2,5,8,9. 思路:用递归的方法解决,对于2589,先输出所有以2开头的排列,然后输出5开头的排列.....(此处称为递归操作A).以2开头的排列中,第一位是2,后面的是589, ...
- DC综合简单总结(2)
DC综合简单总结(2) 建立时间和保持时间和数据输出延时时间 一.概念 建立时间和保持时间都是针对触发器的特性说的. 建立时间(Tsu:set up time) 是指在触发器的时钟信号上升沿到来以前, ...
- git上传到版本库报错:Pull is not possible because you have unmerged files(已解决)
问题所在:操作次数太多,第一次报错之删掉了.git并没有删除下面两个文件 才报了题述错误. 解决办法: 将这三个文件都删除在重新运行所有指令.