syscall(SYS_getuid) 返回与 getuid() 不同的结果

Ite*_*tor 5 c windows system-calls docker windows-subsystem-for-linux

我想使用系统调用来获取当前用户的 id。我尝试过这样的:

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

int main(int argc, char *argv[])
{
    int uid = syscall(SYS_getuid);
    
    printf("%d\n", uid);
    
    return 0;
}

Run Code Online (Sandbox Code Playgroud)

我用 root 执行它,但它打印-1而不是0.

如果我将其替换为int uid = syscall(SYS_getuid);,那么它会正确返回0。我有什么错吗?如何使用 获取当前用户 ID syscall

我在 docker 镜像上运行它i686/ubuntu,因为我必须创建 32 位可执行文件。


最小可重现示例:

Dockerfile

FROM i686/ubuntu

RUN apt-get update
RUN apt-get install --assume-yes --no-install-recommends --quiet \
        gcc libc6-dev
RUN apt-get clean all
Run Code Online (Sandbox Code Playgroud)

主程序

FROM i686/ubuntu

RUN apt-get update
RUN apt-get install --assume-yes --no-install-recommends --quiet \
        gcc libc6-dev
RUN apt-get clean all
Run Code Online (Sandbox Code Playgroud)

运行(在 x64 Windows10 上):

docker build --platform linux/386 -t my-gcc .
docker run --platform linux/386 --rm -v ${pwd}:/usr/local/src/:rw my-gcc gcc -m32 -xc /usr/local/src/main.c -o /usr/local/src/main
docker run --platform linux/386 --rm -v ${pwd}:/usr/local/src/:rw my-gcc /usr/local/src/main
Run Code Online (Sandbox Code Playgroud)

结果是:

Error: Function not implemented
-1
Run Code Online (Sandbox Code Playgroud)

use*_*170 5

根据getuid(2)

最初的 Linux getuid() 和 geteuid() 系统调用仅支持 16 位用户 ID。随后,Linux 2.4添加了getuid32()和geteuid32(),支持32位ID。glibc getuid() 和 geteuid() 包装函数透明地处理跨内核版本的变化。

getuid显然,您正在编译旧系统调用的内核上运行程序,并且仅getuid32在 x86-32 上可用。如果运行fgrep CONFIG_UID16 "/boot/config-$(uname -r)",您将能够查看正在运行的内核是否支持 16 位系统调用。如果此命令打印除 之外的任何内容CONFIG_UID16=y,则意味着旧系统调用不可用。

如果您SYS_getuid32改为调用,它应该可以正常工作。请注意,这SYS_getuid32可能在其他架构上不可用。