X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=support%2Fpwd.c;h=809934777e252d920333a2f0350326cb7af9a0cb;hb=f182433f6b375adc8ce84ca36e0a3ca73d1dd846;hp=05357f4f617603cfa866b81f2582240762da9765;hpb=699e59742843044f6efa1726b7cb64f19d909e64;p=mono.git diff --git a/support/pwd.c b/support/pwd.c index 05357f4f617..809934777e2 100644 --- a/support/pwd.c +++ b/support/pwd.c @@ -28,6 +28,24 @@ struct Mono_Posix_Syscall__Passwd { /* string */ char *_pw_buf_; }; +static const size_t +passwd_offsets[] = { + offsetof (struct passwd, pw_name), + offsetof (struct passwd, pw_passwd), + offsetof (struct passwd, pw_gecos), + offsetof (struct passwd, pw_dir), + offsetof (struct passwd, pw_shell) +}; + +static const size_t +mph_passwd_offsets[] = { + offsetof (struct Mono_Posix_Syscall__Passwd, pw_name), + offsetof (struct Mono_Posix_Syscall__Passwd, pw_passwd), + offsetof (struct Mono_Posix_Syscall__Passwd, pw_gecos), + offsetof (struct Mono_Posix_Syscall__Passwd, pw_dir), + offsetof (struct Mono_Posix_Syscall__Passwd, pw_shell) +}; + /* * Copy the native `passwd' structure to it's managed representation. * @@ -37,59 +55,18 @@ struct Mono_Posix_Syscall__Passwd { static int copy_passwd (struct Mono_Posix_Syscall__Passwd *to, struct passwd *from) { - enum {PW_NAME = 0, PW_PASSWD, PW_GECOS, PW_DIR, PW_SHELL, PW_LAST}; - size_t buflen, len[PW_LAST]; - /* bool */ unsigned char copy[PW_LAST] = {0}; - const char *source[PW_LAST]; - char **dest[PW_LAST]; - int i; - char *cur; + char *buf; + buf = _mph_copy_structure_strings (to, mph_passwd_offsets, + from, passwd_offsets, sizeof(passwd_offsets)/sizeof(passwd_offsets[0])); to->pw_uid = from->pw_uid; to->pw_gid = from->pw_gid; - to->pw_name = NULL; - to->pw_passwd = NULL; - to->pw_gecos = NULL; - to->pw_dir = NULL; - to->pw_shell = NULL; - to->_pw_buf_ = NULL; - - source[PW_NAME] = from->pw_name; - source[PW_PASSWD] = from->pw_passwd; - source[PW_GECOS] = from->pw_gecos; - source[PW_DIR] = from->pw_dir; - source[PW_SHELL] = from->pw_shell; - - dest[PW_NAME] = &to->pw_name; - dest[PW_PASSWD] = &to->pw_passwd; - dest[PW_GECOS] = &to->pw_gecos; - dest[PW_DIR] = &to->pw_dir; - dest[PW_SHELL] = &to->pw_shell; - - buflen = PW_LAST; - - /* over-rigorous checking for integer overflow */ - for (i = 0; i != PW_LAST; ++i) { - len[i] = strlen (source[i]); - if (len[i] < INT_MAX - buflen) { - buflen += len[i]; - copy[i] = 1; - } - } - - cur = to->_pw_buf_ = (char*) malloc (buflen); - if (cur == NULL) { + to->_pw_buf_ = buf; + if (buf == NULL) { return -1; } - for (i = 0; i != PW_LAST; ++i) { - if (copy[i]) { - *dest[i] = strcpy (cur, source[i]); - cur += (len[i] + 1); - } - } - return 0; } @@ -103,6 +80,7 @@ Mono_Posix_Syscall_getpwnam (const char *name, struct Mono_Posix_Syscall__Passwd return -1; } + errno = 0; pw = getpwnam (name); if (pw == NULL) return -1; @@ -141,7 +119,7 @@ Mono_Posix_Syscall_getpwuid (mph_uid_t uid, struct Mono_Posix_Syscall__Passwd *p gint32 Mono_Posix_Syscall_getpwnam_r (const char *name, struct Mono_Posix_Syscall__Passwd *pwbuf, - struct passwd **pwbufp) + void **pwbufp) { char *buf, *buf2; size_t buflen; @@ -164,9 +142,14 @@ Mono_Posix_Syscall_getpwnam_r (const char *name, return -1; } buf = buf2; - } while ((r = getpwnam_r (name, &_pwbuf, buf, buflen, pwbufp)) && + errno = 0; + } while ((r = getpwnam_r (name, &_pwbuf, buf, buflen, (struct passwd**) pwbufp)) && recheck_range (r)); + if (r == 0 && !(*pwbufp)) + /* On solaris, this function returns 0 even if the entry was not found */ + r = errno = ENOENT; + if (r == 0 && copy_passwd (pwbuf, &_pwbuf) == -1) r = errno = ENOMEM; free (buf); @@ -179,7 +162,7 @@ Mono_Posix_Syscall_getpwnam_r (const char *name, gint32 Mono_Posix_Syscall_getpwuid_r (mph_uid_t uid, struct Mono_Posix_Syscall__Passwd *pwbuf, - struct passwd **pwbufp) + void **pwbufp) { char *buf, *buf2; size_t buflen; @@ -202,7 +185,8 @@ Mono_Posix_Syscall_getpwuid_r (mph_uid_t uid, return -1; } buf = buf2; - } while ((r = getpwuid_r (uid, &_pwbuf, buf, buflen, pwbufp)) && + errno = 0; + } while ((r = getpwuid_r (uid, &_pwbuf, buf, buflen, (struct passwd**) pwbufp)) && recheck_range (r)); if (r == 0 && copy_passwd (pwbuf, &_pwbuf) == -1) @@ -223,6 +207,7 @@ Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd *pwbuf) return -1; } + errno = 0; pw = getpwent (); if (pw == NULL) return -1; @@ -236,7 +221,7 @@ Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd *pwbuf) #ifdef HAVE_FGETPWENT gint32 -Mono_Posix_Syscall_fgetpwent (FILE *stream, struct Mono_Posix_Syscall__Passwd *pwbuf) +Mono_Posix_Syscall_fgetpwent (void *stream, struct Mono_Posix_Syscall__Passwd *pwbuf) { struct passwd *pw; @@ -245,7 +230,8 @@ Mono_Posix_Syscall_fgetpwent (FILE *stream, struct Mono_Posix_Syscall__Passwd *p return -1; } - pw = fgetpwent (stream); + errno = 0; + pw = fgetpwent ((FILE*) stream); if (pw == NULL) return -1;