On 12/25/2016 05:12 PM, Wietse Venema wrote: > John Fawcett: >> for an inexistent user for strings up to 31 chars. From 32 chars onwards >> instead of returning not found it retuns EINVAL (invalid argument). >> >> ./test AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA >> Not found >> ./test AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA >> getpwnam_r: Invalid argument > Perhaps they want programs to call sysconf(_SC_LOGIN_NAME_MAX) > (note that the result includes the null terminator). > > Wietse > > #include <pwd.h> > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > #include <unistd.h> > #include <errno.h> > > int main(int argc, char *argv[]) > { > struct passwd pwd; > struct passwd *result; > char *buf; > size_t bufsize; > int s; > > if (argc != 2) { > fprintf(stderr, "Usage: %s username\n", argv[0]); > exit(EXIT_FAILURE); > } > bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); > if (bufsize == -1) /* Value was indeterminate */ > bufsize = 16384; /* Should be more than enough > */ > > buf = malloc(bufsize); > if (buf == NULL) { > perror("malloc"); > exit(EXIT_FAILURE); > } > /* _SC_LOGIN_NAME_MAX includes the null terminator */ > if (strlen(argv[1]) >= sysconf(_SC_LOGIN_NAME_MAX)) { > fprintf(stderr, "warning: name exceeds _SC_LOGIN_NAME_MAX\n"); > result = 0; > s = 0; > } else { > s = getpwnam_r(argv[1], &pwd, buf, bufsize, &result); > } > if (result == NULL) { > if (s == 0) > printf("Not found\n"); > else { > errno = s; > perror("getpwnam_r"); > } > exit(EXIT_FAILURE); > } > printf("Name: %s; UID: %ld\n", pwd.pw_gecos, (long) pwd.pw_uid); > free(buf); > exit(EXIT_SUCCESS); > }
I tried that on archlinux. The above program still produces EINVAL for login names between 32 and 255 inclusive. _SC_LOGIN_NAME_MAX is 256 on that platform. John