当给定 UID 的用户不存在时,getpwuid 和 getgrgid 会导致段错误

getpwuid and getgrgid causes segfault when user does not exist for given UID

我是 运行 linux 中的一个 C 程序,它打印文件名及其用户和组所有权。我正在使用 getpwuidgetgrgid.

当文件由不存在的用户拥有时(即,在我的机器上没有针对给定 UID 的 /etc/passwd 条目),我的程序出现 "terminated by signal 11".

段错误

如何让我的程序表现得与 ls 相同,以便在用户不存在时打印数字 UID,而不是出现段错误?

相关代码片段如下:

lstat(filename,&fileStat)

struct group *grp;
struct passwd *pwd;

pwd = getpwuid(fileStat.st_uid);
printf(" %s", pwd->pw_name);

grp = getgrgid(fileStat.st_gid);
printf(" %s", grp->gr_name);

查看手册页GETPWUID(3P)

RETURN VALUE

The getpwuid() function shall return a pointer to a struct passwd with the structure as defined in with a matching entry if found. A null pointer shall be returned if the requested entry is not found, or an error occurs. On error, errno shall be set to indicate the error.

在访问任何内容之前检查空指针,例如

pwd = getpwuid(fileStat.st_uid);
if (pwd) {
    printf(" %s", pwd->pw_name);
} else {
    // handle non-existing user entry
}

getpwuidgetgrgid return 如果在 /etc/passwd 数据库中找不到用户或出现错误,则为 NULL 指针。 在访问它的值以避免段错误之前,您必须检查它不是 NULL

您还必须检查 lstat 的 return 值以确保它在使用 fileStat 之前成功,否则会导致另一个段错误。 lstat returns -1 失败,否则设置 errno 为 0。 lstat(3)

int ret =  lstat(filename,&fileStat)

if(ret == -1){
  fprintf(stderr, "lstat: (%s): %s\n", filename, strerror(errno));
  return 1;
}

struct group *grp;
struct passwd *pwd;

pwd = getpwuid(fileStat.st_uid);

if(pwd != NULL){
   printf(" %s", pwd->pw_name);
}else{
  printf(" %ld", (long)fileStat.st_uid);
}

grp = getgrgid(fileStat.st_gid);
if(grp != NULL){
 printf(" %s", grp->gr_name);}
else{
  printf(" %ld", (long)fileStat.st_gid);
}

getpwuid(3) 有时它可能 return 一个错误的 NULL 指针并将设置 errno。在检查特定错误之前,您必须将 errno 设置为零