X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=support%2Fpwd.c;h=e622027458dfa806dbdaf0525b27ce10484a3473;hb=feca28835d4e3cb2be67bdcbd4f54fee62c3797a;hp=05357f4f617603cfa866b81f2582240762da9765;hpb=0abc2e6270020edc4a5b4c66f93b4ae582815f20;p=mono.git diff --git a/support/pwd.c b/support/pwd.c index 05357f4f617..e622027458d 100644 --- a/support/pwd.c +++ b/support/pwd.c @@ -4,7 +4,7 @@ * Authors: * Jonathan Pryor (jonpryor@vt.edu) * - * Copyright (C) 2004 Jonathan Pryor + * Copyright (C) 2004-2005 Jonathan Pryor */ #include @@ -13,19 +13,27 @@ #include #include +#include "map.h" #include "mph.h" G_BEGIN_DECLS -struct Mono_Posix_Syscall__Passwd { - /* string */ char *pw_name; - /* string */ char *pw_passwd; - /* uid_t */ mph_uid_t pw_uid; - /* gid_t */ mph_gid_t pw_gid; - /* string */ char *pw_gecos; - /* string */ char *pw_dir; - /* string */ char *pw_shell; - /* 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) }; /* @@ -37,59 +45,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 +70,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 +109,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 +132,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 +152,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 +175,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 +197,7 @@ Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd *pwbuf) return -1; } + errno = 0; pw = getpwent (); if (pw == NULL) return -1; @@ -236,7 +211,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 +220,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; @@ -257,6 +233,27 @@ Mono_Posix_Syscall_fgetpwent (FILE *stream, struct Mono_Posix_Syscall__Passwd *p } #endif /* ndef HAVE_FGETPWENT */ +int +Mono_Posix_Syscall_setpwent (void) +{ + errno = 0; + do { + setpwent (); + } while (errno == EINTR); + mph_return_if_val_in_list5(errno, EIO, EMFILE, ENFILE, ENOMEM, ERANGE); + return 0; +} + +int +Mono_Posix_Syscall_endpwent (void) +{ + errno = 0; + endpwent (); + if (errno == EIO) + return -1; + return 0; +} + G_END_DECLS /*