2010-03-30 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / support / pwd.c
blob13bccef9b559a9392c6787f8dc47c19ab485296b
1 /*
2 * <pwd.h> wrapper functions.
4 * Authors:
5 * Jonathan Pryor (jonpryor@vt.edu)
7 * Copyright (C) 2004-2005 Jonathan Pryor
8 */
10 #include <pwd.h>
11 #include <errno.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <stdlib.h>
16 #include "map.h"
17 #include "mph.h"
19 G_BEGIN_DECLS
21 static const mph_string_offset_t
22 passwd_offsets[] = {
23 MPH_STRING_OFFSET (struct passwd, pw_name, MPH_STRING_OFFSET_PTR),
24 MPH_STRING_OFFSET (struct passwd, pw_passwd, MPH_STRING_OFFSET_PTR),
25 MPH_STRING_OFFSET (struct passwd, pw_gecos, MPH_STRING_OFFSET_PTR),
26 MPH_STRING_OFFSET (struct passwd, pw_dir, MPH_STRING_OFFSET_PTR),
27 MPH_STRING_OFFSET (struct passwd, pw_shell, MPH_STRING_OFFSET_PTR)
30 static const mph_string_offset_t
31 mph_passwd_offsets[] = {
32 MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_name, MPH_STRING_OFFSET_PTR),
33 MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_passwd, MPH_STRING_OFFSET_PTR),
34 MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_gecos, MPH_STRING_OFFSET_PTR),
35 MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_dir, MPH_STRING_OFFSET_PTR),
36 MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_shell, MPH_STRING_OFFSET_PTR)
40 * Copy the native `passwd' structure to it's managed representation.
42 * To minimize separate mallocs, all the strings are allocated within the same
43 * memory block (stored in _pw_buf_).
45 static int
46 copy_passwd (struct Mono_Posix_Syscall__Passwd *to, struct passwd *from)
48 char *buf;
49 buf = _mph_copy_structure_strings (to, mph_passwd_offsets,
50 from, passwd_offsets, sizeof(passwd_offsets)/sizeof(passwd_offsets[0]));
52 to->pw_uid = from->pw_uid;
53 to->pw_gid = from->pw_gid;
55 to->_pw_buf_ = buf;
56 if (buf == NULL) {
57 return -1;
60 return 0;
63 gint32
64 Mono_Posix_Syscall_getpwnam (const char *name, struct Mono_Posix_Syscall__Passwd *pwbuf)
66 struct passwd *pw;
68 if (pwbuf == NULL) {
69 errno = EFAULT;
70 return -1;
73 errno = 0;
74 pw = getpwnam (name);
75 if (pw == NULL)
76 return -1;
78 if (copy_passwd (pwbuf, pw) == -1) {
79 errno = ENOMEM;
80 return -1;
82 return 0;
85 gint32
86 Mono_Posix_Syscall_getpwuid (mph_uid_t uid, struct Mono_Posix_Syscall__Passwd *pwbuf)
88 struct passwd *pw;
90 if (pwbuf == NULL) {
91 errno = EFAULT;
92 return -1;
95 errno = 0;
96 pw = getpwuid (uid);
97 if (pw == NULL) {
98 return -1;
101 if (copy_passwd (pwbuf, pw) == -1) {
102 errno = ENOMEM;
103 return -1;
105 return 0;
108 #ifdef HAVE_GETPWNAM_R
109 gint32
110 Mono_Posix_Syscall_getpwnam_r (const char *name,
111 struct Mono_Posix_Syscall__Passwd *pwbuf,
112 void **pwbufp)
114 char *buf, *buf2;
115 size_t buflen;
116 int r;
117 struct passwd _pwbuf;
119 if (pwbuf == NULL) {
120 errno = EFAULT;
121 return -1;
124 buf = buf2 = NULL;
125 buflen = 2;
127 do {
128 buf2 = realloc (buf, buflen *= 2);
129 if (buf2 == NULL) {
130 free (buf);
131 errno = ENOMEM;
132 return -1;
134 buf = buf2;
135 errno = 0;
136 } while ((r = getpwnam_r (name, &_pwbuf, buf, buflen, (struct passwd**) pwbufp)) &&
137 recheck_range (r));
139 if (r == 0 && !(*pwbufp))
140 /* On solaris, this function returns 0 even if the entry was not found */
141 r = errno = ENOENT;
143 if (r == 0 && copy_passwd (pwbuf, &_pwbuf) == -1)
144 r = errno = ENOMEM;
145 free (buf);
147 return r;
149 #endif /* ndef HAVE_GETPWNAM_R */
151 #ifdef HAVE_GETPWUID_R
152 gint32
153 Mono_Posix_Syscall_getpwuid_r (mph_uid_t uid,
154 struct Mono_Posix_Syscall__Passwd *pwbuf,
155 void **pwbufp)
157 char *buf, *buf2;
158 size_t buflen;
159 int r;
160 struct passwd _pwbuf;
162 if (pwbuf == NULL) {
163 errno = EFAULT;
164 return -1;
167 buf = buf2 = NULL;
168 buflen = 2;
170 do {
171 buf2 = realloc (buf, buflen *= 2);
172 if (buf2 == NULL) {
173 free (buf);
174 errno = ENOMEM;
175 return -1;
177 buf = buf2;
178 errno = 0;
179 } while ((r = getpwuid_r (uid, &_pwbuf, buf, buflen, (struct passwd**) pwbufp)) &&
180 recheck_range (r));
182 if (r == 0 && copy_passwd (pwbuf, &_pwbuf) == -1)
183 r = errno = ENOMEM;
184 free (buf);
186 return r;
188 #endif /* ndef HAVE_GETPWUID_R */
190 gint32
191 Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd *pwbuf)
193 struct passwd *pw;
195 if (pwbuf == NULL) {
196 errno = EFAULT;
197 return -1;
200 errno = 0;
201 pw = getpwent ();
202 if (pw == NULL)
203 return -1;
205 if (copy_passwd (pwbuf, pw) == -1) {
206 errno = ENOMEM;
207 return -1;
209 return 0;
212 #ifdef HAVE_FGETPWENT
213 gint32
214 Mono_Posix_Syscall_fgetpwent (void *stream, struct Mono_Posix_Syscall__Passwd *pwbuf)
216 struct passwd *pw;
218 if (pwbuf == NULL) {
219 errno = EFAULT;
220 return -1;
223 errno = 0;
224 pw = fgetpwent ((FILE*) stream);
225 if (pw == NULL)
226 return -1;
228 if (copy_passwd (pwbuf, pw) == -1) {
229 errno = ENOMEM;
230 return -1;
232 return 0;
234 #endif /* ndef HAVE_FGETPWENT */
237 Mono_Posix_Syscall_setpwent (void)
239 errno = 0;
240 do {
241 setpwent ();
242 } while (errno == EINTR);
243 mph_return_if_val_in_list5(errno, EIO, EMFILE, ENFILE, ENOMEM, ERANGE);
244 return 0;
248 Mono_Posix_Syscall_endpwent (void)
250 errno = 0;
251 endpwent ();
252 if (errno == EIO)
253 return -1;
254 return 0;
257 G_END_DECLS
260 * vim: noexpandtab