I have a problem which I have narrowed down as much as I can imagine. I want to count the lines in /etc/passwd
two times. One time as a reference and one time to detect any change.
I initialize one passwd
structure and count the number of entries in it. I then call setpwent()
. After I have done that i initialize a second passwd
struct, note that I have added a sleep
call so it is enough time to add another user. Problem is that the new struct is identical to the first one even though I have added a new user and initialized a new struct after it has been added. So no difference.
#include <stdio.h>
#include <pwd.h>
#include <unistd.h>
int main()
{
for(;;)
{
struct passwd *i;
int y = 0;
while((i = getpwent()) != NULL)
y++;
printf("Lines : %d\n", y);
setpwent();
sleep(30);
struct passwd *j;
int x = 0;
while((j = getpwent()) != NULL)
x++;
printf("Lines : %d\n", x);
setpwent();
}
}
You're using getpwent()
, which upon first call reads the /etc/passwd
file and parses it internally, providing you all the entries. After that, when you do setpwent()
, you are merely resetting an internal pointer that keeps track of already parsed entries. When you do getpwent()
again after setpwent()
, the /etc/passwd
file will not be accessed a second time, as the information has already ben parsed.
If you want to force getpwent()
to re-open and parse /etc/passwd
every time, you should call endpwent()
first. Replace the calls to setpwent()
with endpwent()
and you'll be good to go.
From the manual page:
The
setpwent()
function rewinds to the beginning of the password database.The
endpwent()
function is used to close the password database after all processing has been performed.