gpt4 book ai didi

c - 尽管参数正确,Linux 重启系统调用仍会返回错误

转载 作者:行者123 更新时间:2023-12-03 09:47:50 29 4
gpt4 key购买 nike

我正在尝试使用原始 reboot 关闭我的机器电源系统调用。这是我的代码:

#include <unistd.h>
#include <linux/reboot.h>
#include <stdio.h>
#include <errno.h>

int main(void) {
int ret = reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_POWER_OFF, NULL);
if (ret == -1) {
printf("error: %d\n", errno);
}
return 0;
}
根据手册页,“只有 super 用户可以调用reboot()”。所以我以 root 身份运行程序并得到以下输出:
alex@laptop:~/code$ sudo ./a.out 
[sudo] password for alex:
error: 22
什么是错误 #22?那将是 EINVAL ,根据重启手册页表示“错误的魔数(Magic Number)或 cmd”。因为我正在使用 #include <linux/reboot.h> 提供的定义,我无法想象这些值是不正确的,但为了以防万一,我还尝试对手册页中提供的魔数(Magic Number)值进行硬编码,但无济于事(同样的错误)。
但是,如果我尝试 glibc 的包装函数 reboot(LINUX_REBOOT_CMD_POWER_OFF)<sys/reboot.h> 提供,它工作正常(立即关闭机器)。
我想这样做没有任何实际原因,只是玩弄系统调用并尝试使其工作。如果有帮助,以下是有关我正在运行它的系统的一些详细信息:
操作系统: Ubuntu 20.04
内核: Linux 版本 5.4.0-53-generic
编译器: gcc 版本 9.3.0
如果任何其他信息可能有用,请告诉我!

最佳答案

我从这个链接得到了这个代码:Reboot with and without glibc

#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#ifdef NO_GLIBC
#include <linux/reboot.h>
#else
#include <sys/reboot.h>
#endif

#ifdef NO_GLIBC
#ifndef LINUX_REBOOT_MAGIC1
#define LINUX_REBOOT_MAGIC1 0xfee1dead
#endif

#ifndef LINUX_REBOOT_MAGIC2
#define LINUX_REBOOT_MAGIC2 0x28121969
#endif

#ifndef LINUX_REBOOT_MAGIC2A
#define LINUX_REBOOT_MAGIC2A 0x05121996
#endif

#ifndef LINUX_REBOOT_MAGIC2B
#define LINUX_REBOOT_MAGIC2B 0x16041998
#endif

#ifndef LINUX_REBOOT_MAGIC2C
#define LINUX_REBOOT_MAGIC2C 0x20112000
#endif
#endif /* NO_GLIBC */

#ifndef LINUX_REBOOT_CMD_RESTART
#define LINUX_REBOOT_CMD_RESTART 0x1234567
#endif

#ifndef LINUX_REBOOT_CMD_HALT
#define LINUX_REBOOT_CMD_HALT 0xcdef0123
#endif

#ifndef LINUX_REBOOT_CMD_POWER_OFF
#define LINUX_REBOOT_CMD_POWER_OFF 0x4321fedc
#endif

#ifndef LINUX_REBOOT_CMD_RESTART2
#define LINUX_REBOOT_CMD_RESTART2 0xa1b3c3d4
#endif

#ifndef LINUX_REBOOT_CMD_CAD_ON
#define LINUX_REBOOT_CMD_CAD_ON 0x89abcdef
#endif

#ifndef LINUX_REBOOT_CMD_CAD_OFF
#define LINUX_REBOOT_CMD_CAD_OFF 0x00000000
#endif

static void do_reboot(int command);

int
main(int argc, char *argv[]) {
int reboot_command;

if(argc == 1) {
fprintf(stderr, "No command given.\n");
fprintf(stderr, "Commands: RESTART, HALT, POWER_OFF, CAD_ON,
CAD_OFF.\n");
return(2);
} else if(strcasecmp(argv[1], "RESTART") == 0) {
reboot_command = LINUX_REBOOT_CMD_RESTART;
} else if(strcasecmp(argv[1], "HALT") == 0) {
reboot_command = LINUX_REBOOT_CMD_HALT;
} else if(strcasecmp(argv[1], "POWER_OFF") == 0) {
reboot_command = LINUX_REBOOT_CMD_POWER_OFF;
} else if(strcasecmp(argv[1], "RESTART2") == 0) {
fprintf(stderr, "RESTART2 not supported. Try RESTART.\n");
return(1);
} else if(strcasecmp(argv[1], "CAD_ON") == 0) {
reboot_command = LINUX_REBOOT_CMD_CAD_ON;
} else if(strcasecmp(argv[1], "CAD_OFF") == 0) {
reboot_command = LINUX_REBOOT_CMD_CAD_OFF;
} else {
fprintf(stderr, "%s not supported.\n", argv[1]);
fprintf(stderr, "Commands: RESTART, HALT, POWER_OFF, CAD_ON,
CAD_OFF.\n");
return(2);
}

do_reboot(reboot_command);

// Not reached, unless command was CAD_ON or CAD_OFF.
return(0);
}

static void
do_reboot(int cmd) {
int reboot_status = 0;

// Flush filesystem buffers before rebooting.
sync();

#ifdef NO_GLIBC
// Old libc.
reboot_status = reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd,
NULL);
#else
// glibc uses a wrapper around the system call.
reboot_status = reboot(cmd);
#endif

if(reboot_status == -1) {
if(errno == EPERM) {
fprintf(stderr, "Permission denied. Are you root?\n");
}
}
}
从这段代码我们可以了解到 rebootoldlibc的格式为: int reboot(int magic, int magic2, unsigned int cmd, void *arg); rebootglibc 的格式为: int reboot(int cmd); 错误 22 的原因 :此错误暗示“无效参数”(EINVAL)。 glibcreboot(int cmd) 函数调用中需要单个参数(glibc 使用系统调用的包装器),但我们提供了多个参数。这就是错误的原因。
请看上面代码中的函数调用:
#ifdef NO_GLIBC
// Old libc.
reboot_status = reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd,
NULL);
#else
// glibc uses a wrapper around the system call.
reboot_status = reboot(cmd);
#endif

关于c - 尽管参数正确,Linux 重启系统调用仍会返回错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65030962/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com