blob: 0c87ab05d2700fdbe3ec727d824718f84ba8ba93 [file] [log] [blame]
Rich Felker0b44a032011-02-12 00:22:29 -05001#include "pwf.h"
Rich Felker4948a242012-02-01 23:51:19 -05002#include <pthread.h>
Rich Felker0b44a032011-02-12 00:22:29 -05003
4#define FIX(x) (pw->pw_##x = pw->pw_##x-line+buf)
5
6static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
7{
Rich Felker0b44a032011-02-12 00:22:29 -05008 char *line = 0;
9 size_t len = 0;
10 int rv = 0;
Rich Felker4948a242012-02-01 23:51:19 -050011 int cs;
12
13 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
Rich Felker0b44a032011-02-12 00:22:29 -050014
Josiah Worcester700e0892015-02-10 18:32:55 -060015 rv = __getpw_a(name, uid, pw, &line, &len, res);
Rich Felkerfc5a96c2015-02-23 00:35:47 -050016 if (*res && size < len) {
Josiah Worcester700e0892015-02-10 18:32:55 -060017 *res = 0;
18 rv = ERANGE;
Rich Felker4948a242012-02-01 23:51:19 -050019 }
Rich Felkerfc5a96c2015-02-23 00:35:47 -050020 if (*res) {
Josiah Worcester700e0892015-02-10 18:32:55 -060021 memcpy(buf, line, len);
22 FIX(name);
23 FIX(passwd);
24 FIX(gecos);
25 FIX(dir);
26 FIX(shell);
Rich Felker0b44a032011-02-12 00:22:29 -050027 }
28 free(line);
Rich Felker4948a242012-02-01 23:51:19 -050029 pthread_setcancelstate(cs, 0);
Rich Felker2d7d05f2017-06-15 13:01:34 -040030 if (rv) errno = rv;
Rich Felker0b44a032011-02-12 00:22:29 -050031 return rv;
32}
33
34int getpwnam_r(const char *name, struct passwd *pw, char *buf, size_t size, struct passwd **res)
35{
36 return getpw_r(name, 0, pw, buf, size, res);
37}
38
39int getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
40{
41 return getpw_r(0, uid, pw, buf, size, res);
42}