Search code examples
clinuxstatic-variablesgetpwuidgetpwnam

Weird behavior of getpwnam


#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
        printf("%s %s\n", getpwnam("steve")->pw_name, getpwnam("root")->pw_name);
        printf("%d %d\n", getpwnam("steve")->pw_uid, getpwnam("root")->pw_uid);

        return EXIT_SUCCESS;
}
$ gcc main.c && ./a.out
steve steve
1000 0

In line 8, we try to print the user names of steve and root, but it prints steve twice. In line 9, we try to print the UIDs of steve and root, and it successfully prints them.

I wanna ascertain the root cause of that bizarre behavior in line 8.

I know the pointer returned by getpwnam points to a statically allocated memory, and the memory pointed by fields like pw_name/pw_passwd/pw_gecos/pw_dir/pw_shell are also static, which means these values can be overwritten by subsequent calls. But still confused about this strange result.

This is exercise 8-1 of The Linux Programming Interface. Add this so that someone like me could find this through the search engine in the future:). And the question in the book is wrong, go here to see the revised version.


Solution

  • The getpwnam function can return a pointer to static data, so each time it's called it returns the same pointer value. And because you're calling this function multiple times as an argument to printf, you'll only see the result of whichever one of those function calls happens last.

    The key point here is that the evaluation order of the arguments to a function are unsequenced, which means there's no guarantee whether getpwnam("steve") happens first or getpwnam("root") happens first.