iis服务器助手广告广告
返回顶部
首页 > 资讯 > 操作系统 >如何实现Linux系统调用
  • 393
分享到

如何实现Linux系统调用

2024-04-02 19:04:59 393人浏览 八月长安
摘要

今天小编给大家分享一下如何实现linux系统调用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下

今天小编给大家分享一下如何实现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 <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>

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               
即无权限进行该操作,我们以普通用户权限是无法修改 /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 中。

还以上面修改 /etc/passwd 文件的属性为例,这次使用 syscall 直接调用:

#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <errno.h>

int main()
{
  int rc;
  rc = syscall(sys_chmod, "/etc/passwd", 0444);

  if (rc == -1)
    fprintf(stderr, "chmod failed, errno = %d\n", errno);
  else
    printf("chmod succeess!\n");
  return 0;
}

在普通用户下编译执行,输出的结果与上例相同。

三、通过 int 指令陷入
如果我们知道系统调用的整个过程的话,应该就能知道用户态程序通过软中断指令int 0x80 来陷入内核态(在intel pentium ii 又引入了sysenter指令),参数的传递是通过寄存器,eax 传递的是系统调用号,ebx、ecx、edx、esi和edi 来依次传递最多五个参数,当系统调用返回时,返回值存放在 eax 中。

仍然以上面的修改文件属性为例,将调用系统调用那段写成内联汇编代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <errno.h>

int main()
{
  long rc;
  char *file_name = "/etc/passwd";
  unsigned short mode = 0444;

  asm(
    "int $0x80"
    : "=a" (rc)
    : "0" (sys_chmod), "b" ((long)file_name), "c" ((long)mode)
  );

  if ((unsigned long)rc >= (unsigned long)-132) {
    errno = -rc;
    rc = -1;
  }

  if (rc == -1)
    fprintf(stderr, "chmode failed, errno = %d\n", errno);
  else
    printf("success!\n");

  return 0;
}

如果 eax 寄存器存放的返回值(存放在变量 rc 中)在 -1~-132 之间,就必须要解释为出错码(在/usr/include/asm-generic/errno.h 文件中定义的最大出错码为 132),这时,将错误码写入 errno 中,置系统调用返回值为 -1;否则返回的是 eax 中的值。上面程序在 32位linux下以普通用户权限编译运行结果与前面两个相同!

以上就是“如何实现Linux系统调用”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网操作系统频道。

--结束END--

本文标题: 如何实现Linux系统调用

本文链接: https://www.lsjlt.com/news/95734.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何实现Linux系统调用
    今天小编给大家分享一下如何实现Linux系统调用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下...
    99+
    2024-04-02
  • linux系统调用是如何实现的
    今天就跟大家聊聊有关linux系统调用是如何实现的,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。这张图画了挺久的,主要是想让大家可以从全局角度,看下linux内核中系统调用的实现。在...
    99+
    2023-06-15
  • 如何使用Java调用Linux系统命令
    目录Java调用Linux系统命令java执行Linux命令,支持通配符(*)Java调用Linux系统命令 有时候,我们在使用Java做一些操作时,可能性能上并不能达到我们满意的效...
    99+
    2024-04-02
  • 如何调整Linux系统时区
    小编给大家分享一下如何调整Linux系统时区,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在进行Linux下修改时区的时候总是修改不了修改成 Asia/Shang...
    99+
    2023-06-28
  • Linux系统如何调整时区
    这篇文章主要介绍“Linux系统如何调整时区”,在日常操作中,相信很多人在Linux系统如何调整时区问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux系统如何调整时区”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-28
  • linux系统下如何实现用户管理
    这篇文章将为大家详细讲解有关linux系统下如何实现用户管理,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、用户及用户组存在的意义1)用户存在的意义系统的资源是有限的,如何合理分配系统资源?身份 acc...
    99+
    2023-06-21
  • Linux系统下如何实现用户审计
    这篇文章主要讲解了“Linux系统下如何实现用户审计”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux系统下如何实现用户审计”吧!创建审计日志目录 代码如下:mkdir -p...
    99+
    2023-06-12
  • Linux系统如何实现pam认证
    这期内容当中小编将会给大家带来有关Linux系统如何实现pam认证,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、pam简介:PMA(Pluggable Authentication Module)是一...
    99+
    2023-06-28
  • Linux系统下如何使用GDB调试程序
    本文将为大家详细介绍“Linux系统下如何使用GDB调试程序”,内容步骤清晰详细,细节处理妥当,而小编每天都会更新不同的知识点,希望这篇“Linux系统下如何使用GDB调试程序”能够给你意想不到的收获,请大家跟着小编的思路慢慢深入,具体内容...
    99+
    2023-06-28
  • VB.NET如何调用WMI来实现系统管理和系统信息查询
    这篇文章给大家分享的是有关VB.NET如何调用WMI来实现系统管理和系统信息查询的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。VB.Net调用WMI可以实现系统管理和系统信息查询等。WMI全称为Windows M...
    99+
    2023-06-17
  • 如何实现linux系统软件安装
    小编今天带大家了解如何实现linux系统软件安装,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着小编一起深入学习“如何实现linux系统软件安装”的知识...
    99+
    2023-06-28
  • 如何用bat实现删除系统脚本调试程序
    这篇文章主要介绍“如何用bat实现删除系统脚本调试程序”,在日常操作中,相信很多人在如何用bat实现删除系统脚本调试程序问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何用bat实现删除系统脚本调试程序”的疑...
    99+
    2023-06-09
  • 如何使用 Python 编程实现 Linux 系统管理?
    Linux 系统管理是一个日常工作中不可避免的任务。Python 是一个广泛使用的编程语言,可以用于系统管理,如自动化部署、监控和日志分析等任务。本文将介绍如何使用 Python 编程实现 Linux 系统管理。 一、Python 基础知识...
    99+
    2023-08-07
    编程算法 shell linux
  • 实战:Linux 系统如何禁用 IPV6
    本文档以实战的形式介绍 Linux 系统如何禁用 IPV6, 使用的操纵系统是 RHEL7.3更改/etc/sysctl.conf配置文件...
    99+
    2023-06-05
  • 如何在Linux系统中使用Systemd和Crontab实现系统自启动
    要在Linux系统中使用Systemd和Crontab来实现系统自启动,可以按照以下步骤操作:使用Systemd:1. 创建一个新的...
    99+
    2023-10-09
    Linux
  • python调用linux系统命令
    python3脚本代码如下# !/usr/bin/python# -.- coding: utf-8 -.-__author__ = 'www.py3study.com'import getpassimport osclas...
    99+
    2023-01-30
    命令 系统 python
  • Linux操作文件的底层系统如何调用
    这篇文章主要介绍“Linux操作文件的底层系统如何调用”,在日常操作中,相信很多人在Linux操作文件的底层系统如何调用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux操作文件的底层系统如何调用”的疑...
    99+
    2023-07-06
  • win10系统如何实现窗口自定义调整
    这篇文章主要为大家展示了“win10系统如何实现窗口自定义调整”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“win10系统如何实现窗口自定义调整”这篇文章吧。按win+r打开运行窗口,输入reg...
    99+
    2023-06-28
  • 如何在Linux系统上调试Java程序?
    在Linux系统上调试Java程序是Java开发者经常遇到的问题之一。本文将介绍如何在Linux系统上使用常见的调试工具来诊断和解决Java程序中的错误。 一、使用命令行调试器 1.1 启动调试模式 在Linux系统上调试Java程序的第一...
    99+
    2023-07-29
    linux leetcode windows
  • 如何实现linux系统下安全管理
    这篇文章主要介绍“如何实现linux系统下安全管理”,在日常操作中,相信很多人在如何实现linux系统下安全管理问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何实现linux系统下安全管理”的疑惑有所帮助!...
    99+
    2023-06-10
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作