Mercurial > hg > octave-nkf > gnulib-hg
comparison lib/idcache.c @ 7673:a37b8b182d49
* lib/idcache.c: Restore most of the 2006-11-06 patch, so as to
continue using the flexible array member (thus, this module performs
half as many malloc calls), with the addition that...
(getgroup, getuser): Consistently record a non-match via an empty
"name" string, and map an empty string match to a NULL return value.
* modules/idcache (Depends-on): Re-add flexmember.
author | Jim Meyering <jim@meyering.net> |
---|---|
date | Mon, 20 Nov 2006 10:54:06 +0000 |
parents | d2c7e0fe0b94 |
children | 476857ef4611 |
comparison
equal
deleted
inserted
replaced
7672:d2c7e0fe0b94 | 7673:a37b8b182d49 |
---|---|
17 along with this program; if not, write to the Free Software Foundation, | 17 along with this program; if not, write to the Free Software Foundation, |
18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | 18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
19 | 19 |
20 #include <config.h> | 20 #include <config.h> |
21 | 21 |
22 #include <stddef.h> | |
22 #include <stdio.h> | 23 #include <stdio.h> |
23 #include <string.h> | 24 #include <string.h> |
24 #include <sys/types.h> | 25 #include <sys/types.h> |
25 #include <pwd.h> | 26 #include <pwd.h> |
26 #include <grp.h> | 27 #include <grp.h> |
38 union | 39 union |
39 { | 40 { |
40 uid_t u; | 41 uid_t u; |
41 gid_t g; | 42 gid_t g; |
42 } id; | 43 } id; |
43 char *name; | |
44 struct userid *next; | 44 struct userid *next; |
45 char name[FLEXIBLE_ARRAY_MEMBER]; | |
45 }; | 46 }; |
46 | 47 |
47 static struct userid *user_alist; | 48 static struct userid *user_alist; |
48 | 49 |
49 /* The members of this list have names not in the local passwd file. */ | 50 /* The members of this list have names not in the local passwd file. */ |
53 | 54 |
54 char * | 55 char * |
55 getuser (uid_t uid) | 56 getuser (uid_t uid) |
56 { | 57 { |
57 struct userid *tail; | 58 struct userid *tail; |
58 struct passwd *pwent; | 59 struct userid *match = NULL; |
59 | 60 |
60 for (tail = user_alist; tail; tail = tail->next) | 61 for (tail = user_alist; tail; tail = tail->next) |
61 if (tail->id.u == uid) | 62 { |
62 return tail->name; | 63 if (tail->id.u == uid) |
63 | 64 { |
64 pwent = getpwuid (uid); | 65 match = tail; |
65 tail = xmalloc (sizeof *tail); | 66 break; |
66 tail->id.u = uid; | 67 } |
67 tail->name = pwent ? xstrdup (pwent->pw_name) : NULL; | 68 } |
68 | 69 |
69 /* Add to the head of the list, so most recently used is first. */ | 70 if (match == NULL) |
70 tail->next = user_alist; | 71 { |
71 user_alist = tail; | 72 struct passwd *pwent = getpwuid (uid); |
72 return tail->name; | 73 char const *name = pwent ? pwent->pw_name : ""; |
74 match = xmalloc (offsetof (struct userid, name) + strlen (name) + 1); | |
75 match->id.u = uid; | |
76 strcpy (match->name, name); | |
77 | |
78 /* Add to the head of the list, so most recently used is first. */ | |
79 match->next = user_alist; | |
80 user_alist = match; | |
81 } | |
82 | |
83 return match->name[0] ? match->name : NULL; | |
73 } | 84 } |
74 | 85 |
75 /* Translate USER to a UID, with cache. | 86 /* Translate USER to a UID, with cache. |
76 Return NULL if there is no such user. | 87 Return NULL if there is no such user. |
77 (We also cache which user names have no passwd entry, | 88 (We also cache which user names have no passwd entry, |
102 setenv ("USER", user, 1); | 113 setenv ("USER", user, 1); |
103 pwent = getpwnam (user); /* now it will succeed */ | 114 pwent = getpwnam (user); /* now it will succeed */ |
104 } | 115 } |
105 #endif | 116 #endif |
106 | 117 |
107 tail = xmalloc (sizeof *tail); | 118 tail = xmalloc (offsetof (struct userid, name) + strlen (user) + 1); |
108 tail->name = xstrdup (user); | 119 strcpy (tail->name, user); |
109 | 120 |
110 /* Add to the head of the list, so most recently used is first. */ | 121 /* Add to the head of the list, so most recently used is first. */ |
111 if (pwent) | 122 if (pwent) |
112 { | 123 { |
113 tail->id.u = pwent->pw_uid; | 124 tail->id.u = pwent->pw_uid; |
129 | 140 |
130 char * | 141 char * |
131 getgroup (gid_t gid) | 142 getgroup (gid_t gid) |
132 { | 143 { |
133 struct userid *tail; | 144 struct userid *tail; |
134 struct group *grent; | 145 struct userid *match = NULL; |
135 | 146 |
136 for (tail = group_alist; tail; tail = tail->next) | 147 for (tail = group_alist; tail; tail = tail->next) |
137 if (tail->id.g == gid) | 148 { |
138 return tail->name; | 149 if (tail->id.g == gid) |
139 | 150 { |
140 grent = getgrgid (gid); | 151 match = tail; |
141 tail = xmalloc (sizeof *tail); | 152 break; |
142 tail->id.g = gid; | 153 } |
143 tail->name = grent ? xstrdup (grent->gr_name) : NULL; | 154 } |
144 | 155 |
145 /* Add to the head of the list, so most recently used is first. */ | 156 if (match == NULL) |
146 tail->next = group_alist; | 157 { |
147 group_alist = tail; | 158 struct group *grent = getgrgid (gid); |
148 return tail->name; | 159 char const *name = grent ? grent->gr_name : ""; |
160 match = xmalloc (offsetof (struct userid, name) + strlen (name) + 1); | |
161 match->id.g = gid; | |
162 strcpy (match->name, name); | |
163 | |
164 /* Add to the head of the list, so most recently used is first. */ | |
165 match->next = group_alist; | |
166 group_alist = match; | |
167 } | |
168 | |
169 return match->name[0] ? match->name : NULL; | |
149 } | 170 } |
150 | 171 |
151 /* Translate GROUP to a GID, with cache. | 172 /* Translate GROUP to a GID, with cache. |
152 Return NULL if there is no such group. | 173 Return NULL if there is no such group. |
153 (We also cache which group names have no group entry, | 174 (We also cache which group names have no group entry, |
170 return NULL; | 191 return NULL; |
171 | 192 |
172 grent = getgrnam (group); | 193 grent = getgrnam (group); |
173 #ifdef __DJGPP__ | 194 #ifdef __DJGPP__ |
174 /* We need to pretend to belong to group GROUP, to make | 195 /* We need to pretend to belong to group GROUP, to make |
175 grp functions know about any arbitrary group name. */ | 196 grp functions know about an arbitrary group name. */ |
176 if (!grent && strspn (group, digits) < strlen (group)) | 197 if (!grent && strspn (group, digits) < strlen (group)) |
177 { | 198 { |
178 setenv ("GROUP", group, 1); | 199 setenv ("GROUP", group, 1); |
179 grent = getgrnam (group); /* now it will succeed */ | 200 grent = getgrnam (group); /* now it will succeed */ |
180 } | 201 } |
181 #endif | 202 #endif |
182 | 203 |
183 tail = xmalloc (sizeof *tail); | 204 tail = xmalloc (offsetof (struct userid, name) + strlen (group) + 1); |
184 tail->name = xstrdup (group); | 205 strcpy (tail->name, group); |
185 | 206 |
186 /* Add to the head of the list, so most recently used is first. */ | 207 /* Add to the head of the list, so most recently used is first. */ |
187 if (grent) | 208 if (grent) |
188 { | 209 { |
189 tail->id.g = grent->gr_gid; | 210 tail->id.g = grent->gr_gid; |