我们来学习一下 reboot 这个系统调用。它是一个底层的 Linux 系统调用,用于重启、关闭或挂起你的计算机 。
1. 函数介绍
reboot 系统调用(System Call)提供了直接与 Linux 内核交互以控制机器状态(如重启、关机)的接口 。顾名思义,它的主要作用是重新启动机器,但根据提供的参数,它也能执行关闭电源、挂起系统等操作 。这与用户通常在命令行使用的 reboot 命令不同,后者是一个更高级别的程序,内部可能会调用这个系统调用 。
data-ad-format="fluid" data-ad-layout-key="-7k+ex-4a-9w+4a">reboot系统调用及示例-CSDN博客
https://www.calcguide.tech/2025/08/28/reboot系统调用及示例/
2. 函数原型
1 | #include <unistd.h> |
注意:直接使用 __reboot 系统调用比较复杂且不推荐。通常,标准 C 库(glibc)会提供一个更方便的包装函数 reboot。
更常用的 glibc 包装函数原型:
1 | #include <sys/reboot.h> // glibc 封装函数的头文件 |
3. 功能
这个系统调用的核心功能是根据 cmd 参数的值来执行不同的系统级操作,主要包括重启系统、关闭系统电源、挂起系统或启用/禁用 Ctrl+Alt+Del 组合键的功能 。
4. 参数
对于 glibc 封装的 reboot(int cmd) 函数:
cmd: int 类型。这个参数指定了要执行的具体操作。常见的值定义在 sys/reboot.h 头文件中,例如:
LINUX_REBOOT_CMD_RESTART: 立即重启系统。
LINUX_REBOOT_CMD_HALT: 停止操作系统,但不关闭电源(挂起)。
LINUX_REBOOT_CMD_POWER_OFF: 停止操作系统并关闭电源(如果硬件支持)。
LINUX_REBOOT_CMD_RESTART2: 重启系统,并传递一个可选的命令行参数给内核(通过 arg 参数,但这在 glibc 包装函数中不直接暴露)。
LINUX_REBOOT_CMD_CAD_ON: 允许使用 Ctrl+Alt+Del 组合键重启系统。
LINUX_REBOOT_CMD_CAD_OFF: 禁止使用 Ctrl+Alt+Del 组合键。
对于底层的 __reboot(int magic, int magic2, unsigned int cmd, void *arg) 系统调用:
magic: int 类型。第一个“魔数”,必须是 LINUX_REBOOT_MAGIC1 。这是为了防止意外调用系统调用 。
magic2: int 类型。第二个“魔数”,必须是 LINUX_REBOOT_MAGIC2 或 LINUX_REBOOT_MAGIC2A/B/C 中的一个 。同样是为了防止误操作 。
cmd: unsigned int 类型。指定要执行的操作,与 glibc reboot 的 cmd 参数类似,但可能使用内核空间定义的常量(如 LINUX_REBOOT_CMD_*)。
arg: void * 类型。一个指向缓冲区的指针,用于传递附加参数,例如传递给内核的命令行字符串(当 cmd 为 LINUX_REBOOT_CMD_RESTART2 时)。
5. 返回值
成功: 对于 reboot(int cmd),如果调用成功,通常不会返回,因为系统会立即执行指定的操作(如重启或关机)。
失败: 返回 -1,并设置全局变量 errno 来指示错误原因,最常见的失败原因是权限不足(需要 root 权限)。
6. 相似函数或关联函数
reboot 命令: 用户空间的标准命令行工具,用于重启系统,内部可能调用 reboot() 系统调用 。
shutdown 命令: 更通用的关机/重启命令,允许指定时间、广播消息等,最终也可能调用 reboot() 系统调用。
poweroff 命令: 用于关闭系统电源,通常也是通过系统调用实现。
halt 命令: 停止系统,行为取决于实现和参数,有时与 poweroff 类似。
sync 系统调用: 在执行 reboot 之前,通常会先调用 sync() 将所有未写入磁盘的数据刷新到磁盘,以防数据丢失。
7. 示例代码
注意: 运行此代码需要 root 权限,因为它执行的是特权操作。系统会立即重启,所以请确保保存所有工作。
1 | #include <stdio.h> |
编译和运行:
1 | # 假设代码保存在 reboot_example.c 中 |
再次提醒: 执行此程序会使您的计算机立即重启,请谨慎操作!