0

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

当文件由不存在的用户拥有时(即,/etc/passwd我的机器上没有给定 UID 的条目),我的程序会出现“由信号 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);
4

2 回答 2

2

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

您还必须lstat在使用之前检查返回值以确保它成功,fileStat否则会导致另一个段错误。lstat失败时返回 -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) 有时它可能会在错误时返回 NULL 指针并设置errno. 在检查特定错误之前,您必须将 errno 设置为零

于 2017-04-02T20:38:56.070 回答
1

查看手册页GETPWUID(3P)

返回值

getpwuid() 函数应返回一个指向结构体 passwd 的指针,该结构体具有如中定义的结构以及匹配的条目(如果找到)。如果未找到请求的条目或发生错误,则应返回空指针。出错时,应设置 errno 以指示错误。

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

pwd = getpwuid(fileStat.st_uid);
if (pwd) {
    printf(" %s", pwd->pw_name);
} else {
    // handle non-existing user entry
}
于 2017-04-02T20:27:03.327 回答