X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=support%2Fpwd.c;h=0e73af22bf9dac7825528da3a77a4f7e34ae4746;hb=ef7a4c06206976de7ef2e974267407347ddb75a4;hp=05357f4f617603cfa866b81f2582240762da9765;hpb=0abc2e6270020edc4a5b4c66f93b4ae582815f20;p=mono.git diff --git a/support/pwd.c b/support/pwd.c index 05357f4f617..0e73af22bf9 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,31 @@ #include #include -#include "mph.h" +#include "mph.h" /* Don't remove or move after map.h! Works around issues with Android SDK unified headers */ +#include "map.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 mph_string_offset_t +passwd_offsets[] = { + MPH_STRING_OFFSET (struct passwd, pw_name, MPH_STRING_OFFSET_PTR), + MPH_STRING_OFFSET (struct passwd, pw_passwd, MPH_STRING_OFFSET_PTR), +#if HAVE_STRUCT_PASSWD_PW_GECOS + MPH_STRING_OFFSET (struct passwd, pw_gecos, MPH_STRING_OFFSET_PTR), +#endif /* def HAVE_STRUCT_PASSWD_PW_GECOS */ + MPH_STRING_OFFSET (struct passwd, pw_dir, MPH_STRING_OFFSET_PTR), + MPH_STRING_OFFSET (struct passwd, pw_shell, MPH_STRING_OFFSET_PTR) +}; + +static const mph_string_offset_t +mph_passwd_offsets[] = { + MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_name, MPH_STRING_OFFSET_PTR), + MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_passwd, MPH_STRING_OFFSET_PTR), +#if HAVE_STRUCT_PASSWD_PW_GECOS + MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_gecos, MPH_STRING_OFFSET_PTR), +#endif /* def HAVE_STRUCT_PASSWD_PW_GECOS */ + MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_dir, MPH_STRING_OFFSET_PTR), + MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_shell, MPH_STRING_OFFSET_PTR) }; /* @@ -37,59 +49,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 +74,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 +113,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 +136,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 +156,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,9 +179,14 @@ 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 && !(*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); @@ -213,6 +195,7 @@ Mono_Posix_Syscall_getpwuid_r (mph_uid_t uid, } #endif /* ndef HAVE_GETPWUID_R */ +#if HAVE_GETPWENT gint32 Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd *pwbuf) { @@ -223,6 +206,7 @@ Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd *pwbuf) return -1; } + errno = 0; pw = getpwent (); if (pw == NULL) return -1; @@ -233,10 +217,11 @@ Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd *pwbuf) } return 0; } +#endif /* def HAVE_GETPWENT */ #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; @@ -257,6 +243,31 @@ Mono_Posix_Syscall_fgetpwent (FILE *stream, struct Mono_Posix_Syscall__Passwd *p } #endif /* ndef HAVE_FGETPWENT */ +#if HAVE_SETPWENT +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; +} +#endif /* def HAVE_SETPWENT */ + +#if HAVE_ENDPWENT +int +Mono_Posix_Syscall_endpwent (void) +{ + errno = 0; + endpwent (); + if (errno == EIO) + return -1; + return 0; +} +#endif /* def HAVE_ENDPWENT */ + G_END_DECLS /*