簡體   English   中英

輸入無效用戶時,getpwnam()使程序崩潰

[英]getpwnam() crashes program when invalid user is entered

getuserinfo()中,如果行struct passwd * theUser = getpwnam(username); 嘗試使用不存在的用戶名,程序將以-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;
}

錯誤檢查應如下所示:

struct passwd *getuserinfo(char *username)
{


//define errno 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(errno != 0)
{
    perror("ERROR: getpwnam() FAIL");
}
//check if we got user data/if the user existed
else if(theUser == NULL)
{
    fprintf(stderr, "ERROR: User does not exist!\n");
    return NULL;
}

    return theUser;
}

需要使用使用stderr的fprintf來確保始終顯示錯誤消息。 它在printf緩沖區中丟失了,keithmo建議使用fflush(NULL)解決了這一問題。

errno用於檢查呼叫是否成功。 然后我們確保theUser!= NULL,因為即使缺少用戶,調用也會成功。 如果為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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM