C 当输入无效用户时,getpwnam()会使程序崩溃

C 当输入无效用户时,getpwnam()会使程序崩溃,c,linux,return,system-calls,C,Linux,Return,System Calls,如果行结构passwd*theUser=getpwnamusername,则在getuserinfo中;尝试使用不存在的用户名。程序将关闭,错误为-1。它永远不会到达函数的错误处理部分。它没有返回到main,我不知道为什么 它应该返回NULL并打印出错误消息,然后让程序的其余部分尝试运行 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <ctype.h> #in

如果行结构passwd*theUser=getpwnamusername,则在getuserinfo中;尝试使用不存在的用户名。程序将关闭,错误为-1。它永远不会到达函数的错误处理部分。它没有返回到main,我不知道为什么

它应该返回NULL并打印出错误消息,然后让程序的其余部分尝试运行

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <errno.h>


//awk 'BEGIN { FS=":"; print "User\t\tUID\n--------------------"; } { print $1,"\t\t",$3;} END { print "--------------------\nAll Users and UIDs Printed!" }' /etc/passwd
#define SHELLSCRIPT "\
#/bin/bash \n\
awk 'BEGIN { FS=\":\"; print \"User\t\tUID\n--------------------\"; } { print $1,\"\t\t\",$3;} END { print \"--------------------\nAll Users and UIDs Printed!\" }' /etc/passwd \n\
    "



struct passwd *getuserinfo(char *username)
{
    //Set errno to 0 so we can use it
    errno = 0;

    //create a variable to store the user info in
    struct passwd *theUser = getpwnam(username);

    //error check getpwnam()
    if(theUser == NULL)
    {
        printf("getpwnam() ERROR, errno = %d", errno);
        return NULL;
    }

    return theUser;
}

struct group *getgroupinfo(long int groupid)
{
    //Set errno to 0 so we can use it
    errno = 0;

    //create a variable to store the group info in
    struct group *theGroup = getgrgid(groupid);

    //error check getgrgid()
    if(theGroup == NULL)
    {
        printf("getgrgid() ERROR, errno = %d", errno);
        return NULL;
    }

    return theGroup;
}

void displayusers()
{
    system(SHELLSCRIPT);
}

/*
 *
 *  4. A main function which will
 * Call getuserinfo passing a hard-coded username, and using the return object, display the user id. (10 points)
 * Call getgroupinfo passing the return object from getuserinfo, and using the return object, display the user’s group name. (10 points)
 * Call displayusers. (10 points)
 *
 * My main function does those things but I don't pass objects since the function prototypes you gave us
 * don't accept that input, they want ints and strings
 */

int main(int argc, char **argv)
{
    //Take in the username we want to look up
    char username[50];
    printf("Enter username: ");
    scanf("%s", username);


    //look up the user and get their info
    struct passwd *theUser = getuserinfo(username);
    //use the user's gid and look up its info
    struct group *theGroup = getgroupinfo(theUser->pw_gid);

    printf("User: %s\nUser ID: %d\nGroup Name: %s\n\n\n", theUser->pw_name, theUser->pw_uid, theGroup->gr_name);

    displayusers();


    return 0;
}
错误检查应如下所示: 需要使用使用stderr的fprintf来确保始终显示错误消息。它在printf缓冲区中丢失了,keithmo建议使用fflushNULL解决了这个问题

errno用于检查调用是否成功。然后,我们确保用户!=NULL,因为即使缺少用户,调用也会成功。如果为空,我们将向用户打印一条错误消息,以便他们知道

根据t0mm13b,在调用主函数中的getgroupinfo之前,我们还进行了错误检查

//look up the user and get their info
    struct passwd *theUser = getuserinfo(username);
    //use the user's gid and look up its info
    struct group *theGroup;
    if(theUser != NULL)
    {
        //get the user's group id
        theGroup = getgroupinfo(theUser->pw_gid);
        //print the user and group info
        printf("User: %s\nUser ID: %d\nGroup Name: %s\n\n\n", theUser->pw_name, theUser->pw_uid, theGroup->gr_name);
    }
    else
    {
        fprintf(stderr, "ERROR: No group info, missing user!\n");
    }


    displayusers();

代码是否具有setuid权限,或者您是以root用户身份运行它?我只是在eclipseforc/C++控制台中运行它。我猜代码将作为我的管理员用户运行,但不使用sudo;然后愉快地转到下一行以获取该用户的组id,在调用函数getgroupinfo之前,您是否在那里检查了NULL?在getuserinfo中的printf之后添加一个fflush,您将看到错误消息。注意:errno将为0,表示找不到用户。我怀疑使用stdout而不是stderr不是问题所在-我怀疑这实际上是因为最初没有包含换行符,这会延迟刷新。你只是碰巧在你的新版本中加入了一个新行。
//look up the user and get their info
    struct passwd *theUser = getuserinfo(username);
    //use the user's gid and look up its info
    struct group *theGroup;
    if(theUser != NULL)
    {
        //get the user's group id
        theGroup = getgroupinfo(theUser->pw_gid);
        //print the user and group info
        printf("User: %s\nUser ID: %d\nGroup Name: %s\n\n\n", theUser->pw_name, theUser->pw_uid, theGroup->gr_name);
    }
    else
    {
        fprintf(stderr, "ERROR: No group info, missing user!\n");
    }


    displayusers();