Let's review the my code first.
#include <stdio.h>
#include <grp.h>
#include <pwd.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
int main(int argc, char** argv){
struct group *grp;
struct group *tmpGrp;
struct passwd *pw;
int n;
gid_t gid;
pw=getpwnam(argv[1]);
gid=pw->pw_gid;
printf(“%s”,pw->pw_name);
printf(“\n”);
grp = getgrgid(gid);
char *mainGrp = grp->grame;
printf(“out : %s\t”, mainGrp);
while((tmpGrp=getgrgent())!=NULL){
n=0;
printf(“in : %s\t”,mainGrp);
}
printf(“\n”);
return 0;
}
and it's output is like:
root
out : root in : root in : other in : bin in : sys ....
As you see, when using the getgrnam() and getgrent() at the same time, group name is changed, even though assigned at string.
I want result like
root
out : root in : root in : root in : root ....
Code routine getgrgent() is just after at assigning into string, but why this happen? And how to fix it?
Test Operating System : Solaris 10
Test Compiler : GCC
From this (Linux) manual page for getgrent
:
The return value may point to a static area, and may be overwritten by subsequent calls to
getgrent()
,getgrgid(3)
, orgetgrnam(3)
.
So you get different names even though you use the same pointer, because the data returned by those functions is a single static and shared buffer.
This is also hinted to by the POSIX getgrent
reference specification.
If you want mainGrp
to not change, you need to copy the actual contents. E.g. make mainGrp
an array and use strcpy
.