c - 调用 open 时如何调用 sys_open 而不是 sys_openat

标签 c linux gcc linux-kernel system-calls

我写了一个代码来生成系统调用

void open_test(int fd, const char *filepath) {
    if (fd == -1) {
        printf("Open \"%s\" Failed!\n", filepath);
    } else {
        printf("Successfully Open \"%s\"!\n", filepath);
        write(fd, "successfully open!", sizeof("successfully open!") - 1);
        close(fd);
    }
    fflush(stdout);
}

int main(int argc, char const *argv[]) {
    const char fp1[] = "whatever.txt", fp2[] = "./not-exist.txt";
    int fd1 = open(fp1, O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
    int fd2 = open(fp2, O_WRONLY | O_TRUNC, S_IRWXU);
    open_test(fd1, fp1);
    open_test(fd2, fp2);
    return 0;
}
和另一个程序(细节省略)来捕捉系统调用,但后来我发现所有open()原来是调用 sys_openat 而不是 sys_open。
以下文本是程序的输出:
Detect system call open, %rax is 257, Addr is 0x00007fefef78aec8, Pathname is /etc/ld.so.cache
Detect system call open, %rax is 257, Addr is 0x00007fefef78aec8, Pathname is /etc/ld.so.cache
Detect system call open, %rax is 257, Addr is 0x00007fefef993dd0, Pathname is /lib/x86_64-linux-gnu/libc.so.6
Detect system call open, %rax is 257, Addr is 0x00007fefef993dd0, Pathname is /lib/x86_64-linux-gnu/libc.so.6
Detect system call open, %rax is 257, Addr is 0x00007fffd44e38e3, Pathname is whatever.txt
Detect system call open, %rax is 257, Addr is 0x00007fffd44e38e3, Pathname is whatever.txt
Detect system call open, %rax is 257, Addr is 0x00007fffd44e38f0, Pathname is ./not-exist.txt
Detect system call open, %rax is 257, Addr is 0x00007fffd44e38f0, Pathname is ./not-exist.txt
Successfully Open "whatever.txt"!
Open "./not-exist.txt" Failed!
这里 rax=257 表示调用了 sys_openat(对于 sys_open,rax=2)

最佳答案

您调用syscall(2)包装:syscall(SYS_open, ...) :

#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#include <sys/syscall.h>

int main(void){
        char *path = "whatever.txt";
        int fd = syscall(SYS_open, path, O_RDONLY, 0);
        if(fd == -1) err(1, "SYS_open %s", path);
}
但是为什么要打扰呢? SYS_openat现在是规范的系统调用,open(2)只是一个 API,而 SYS_open系统调用条目仅出于向后二进制兼容性而保留。
在较新的架构上,可能没有实际的 SYS_open系统调用。

关于c - 调用 open 时如何调用 sys_open 而不是 sys_openat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64407019/

相关文章:

c - 运行 lwIP 1.3.2 的 stellaris 板上的 Websockets

linux - 如何将包含路径的变量插入sed

c - 让 gcc 以 "int 0x80"方式编译系统调用?

linux - 无法在 Linux 中打印长度超过 8 个字符的用户名( "w")

xcode - dyld:库未加载:/usr/local/lib/libmpfr.4.dylib

c++ - Gcc 4.8.3 没有发现丢失的 'return' 关键字

c - 为什么最大堆栈深度不断变化?

c - 关闭标准输出后调用 printf 会发生什么?

c - 我正在制作一个必须交换其顺序的链表

mysql - netcat 用于 MySQL 连接转发