Prepare Mono for Android NDK with unified headers (#5680)
[mono.git] / support / pwd.c
index 38859e0d7c61bb3522adf62da87ec0bba2fe3b0c..0e73af22bf9dac7825528da3a77a4f7e34ae4746 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 
-#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 size_t
+static const mph_string_offset_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)
+       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 size_t
+static const mph_string_offset_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)
+       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)
 };
 
 /*
@@ -189,6 +183,10 @@ Mono_Posix_Syscall_getpwuid_r (mph_uid_t uid,
        } 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);
@@ -197,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)
 {
@@ -218,6 +217,7 @@ Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd *pwbuf)
        }
        return 0;
 }
+#endif  /* def HAVE_GETPWENT */
 
 #ifdef HAVE_FGETPWENT
 gint32
@@ -243,21 +243,30 @@ Mono_Posix_Syscall_fgetpwent (void *stream, struct Mono_Posix_Syscall__Passwd *p
 }
 #endif /* ndef HAVE_FGETPWENT */
 
+#if HAVE_SETPWENT
 int
 Mono_Posix_Syscall_setpwent (void)
 {
        errno = 0;
-       setpwent ();
-       return errno == 0 ? 0 : -1;
+       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 ();
-       return errno == 0 ? 0 : -1;
+       if (errno == EIO)
+               return -1;
+       return 0;
 }
+#endif  /* def HAVE_ENDPWENT */
 
 G_END_DECLS