aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2015-02-07 21:21:02 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2015-02-07 21:21:02 +0100
commit23cfaab47de7392c1ba7d601a05fb36da3629b28 (patch)
tree228cbefac14b7e60edda2e9314a30bfd43a7e5c5
parent68c048fb23bd8b0831bbd02ec66900b12390cf19 (diff)
downloadbusybox-w32-23cfaab47de7392c1ba7d601a05fb36da3629b28.tar.gz
busybox-w32-23cfaab47de7392c1ba7d601a05fb36da3629b28.tar.bz2
busybox-w32-23cfaab47de7392c1ba7d601a05fb36da3629b28.zip
libpwdgrp: use getpwent() instead of getpwent_r()
function old new delta massage_data_for_non_r_func - 90 +90 bb_internal_getpwent - 69 +69 getXXnam_r 94 162 +68 fill_bounds 131 128 -3 deluser_main 355 310 -45 complete_username 123 78 -45 getXXnam 163 90 -73 massage_data_for_r_func 103 - -103 bb_internal_getpwent_r 121 - -121 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 1/5 up/down: 227/-407) Total: -163 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--include/pwd_.h16
-rw-r--r--libbb/lineedit.c13
-rw-r--r--libpwdgrp/pwd_grp.c58
-rw-r--r--loginutils/deluser.c9
4 files changed, 53 insertions, 43 deletions
diff --git a/include/pwd_.h b/include/pwd_.h
index 32b5b366e..17348298a 100644
--- a/include/pwd_.h
+++ b/include/pwd_.h
@@ -36,7 +36,6 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
36#define getpwent bb_internal_getpwent 36#define getpwent bb_internal_getpwent
37#define getpwuid bb_internal_getpwuid 37#define getpwuid bb_internal_getpwuid
38#define getpwnam bb_internal_getpwnam 38#define getpwnam bb_internal_getpwnam
39#define getpwent_r bb_internal_getpwent_r
40#define getpwnam_r bb_internal_getpwnam_r 39#define getpwnam_r bb_internal_getpwnam_r
41 40
42/* All function names below should be remapped by #defines above 41/* All function names below should be remapped by #defines above
@@ -48,10 +47,8 @@ void FAST_FUNC setpwent(void);
48/* Close the password-file stream. */ 47/* Close the password-file stream. */
49void FAST_FUNC endpwent(void); 48void FAST_FUNC endpwent(void);
50 49
51#ifdef UNUSED_SINCE_WE_AVOID_STATIC_BUFS
52/* Read an entry from the password-file stream, opening it if necessary. */ 50/* Read an entry from the password-file stream, opening it if necessary. */
53struct passwd* FAST_FUNC getpwent(void); 51struct passwd* FAST_FUNC getpwent(void);
54#endif
55 52
56/* Search for an entry with a matching user ID. */ 53/* Search for an entry with a matching user ID. */
57struct passwd* FAST_FUNC getpwuid(uid_t __uid); 54struct passwd* FAST_FUNC getpwuid(uid_t __uid);
@@ -59,18 +56,7 @@ struct passwd* FAST_FUNC getpwuid(uid_t __uid);
59/* Search for an entry with a matching username. */ 56/* Search for an entry with a matching username. */
60struct passwd* FAST_FUNC getpwnam(const char *__name); 57struct passwd* FAST_FUNC getpwnam(const char *__name);
61 58
62/* Reentrant versions of some of the functions above. 59/* Reentrant versions of some of the functions above. */
63
64 PLEASE NOTE: the `getpwent_r' function is not (yet) standardized.
65 The interface may change in later versions of this library. But
66 the interface is designed following the principals used for the
67 other reentrant functions so the chances are good this is what the
68 POSIX people would choose. */
69
70int FAST_FUNC getpwent_r(struct passwd *__restrict __resultbuf,
71 char *__restrict __buffer, size_t __buflen,
72 struct passwd **__restrict __result);
73
74int FAST_FUNC getpwnam_r(const char *__restrict __name, 60int FAST_FUNC getpwnam_r(const char *__restrict __name,
75 struct passwd *__restrict __resultbuf, 61 struct passwd *__restrict __resultbuf,
76 char *__restrict __buffer, size_t __buflen, 62 char *__restrict __buffer, size_t __buflen,
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 720a4951e..249b401b4 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -672,23 +672,20 @@ static char *username_path_completion(char *ud)
672 */ 672 */
673static NOINLINE unsigned complete_username(const char *ud) 673static NOINLINE unsigned complete_username(const char *ud)
674{ 674{
675 /* Using _r function to avoid pulling in static buffers */ 675 struct passwd *pw;
676 char line_buff[256];
677 struct passwd pwd;
678 struct passwd *result;
679 unsigned userlen; 676 unsigned userlen;
680 677
681 ud++; /* skip ~ */ 678 ud++; /* skip ~ */
682 userlen = strlen(ud); 679 userlen = strlen(ud);
683 680
684 setpwent(); 681 setpwent();
685 while (!getpwent_r(&pwd, line_buff, sizeof(line_buff), &result)) { 682 while ((pw = getpwent()) != NULL) {
686 /* Null usernames should result in all users as possible completions. */ 683 /* Null usernames should result in all users as possible completions. */
687 if (/*!userlen || */ strncmp(ud, pwd.pw_name, userlen) == 0) { 684 if (/*!userlen || */ strncmp(ud, pw->pw_name, userlen) == 0) {
688 add_match(xasprintf("~%s/", pwd.pw_name)); 685 add_match(xasprintf("~%s/", pw->pw_name));
689 } 686 }
690 } 687 }
691 endpwent(); 688 endpwent(); /* don't keep password file open */
692 689
693 return 1 + userlen; 690 return 1 + userlen;
694} 691}
diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c
index 90647e9d3..7ec704ee4 100644
--- a/libpwdgrp/pwd_grp.c
+++ b/libpwdgrp/pwd_grp.c
@@ -336,6 +336,22 @@ static int massage_data_for_r_func(struct passdb *db,
336 return errno; 336 return errno;
337} 337}
338 338
339static void* massage_data_for_non_r_func(struct passdb *db, char *buf)
340{
341 if (!buf)
342 return NULL;
343
344 free(db->malloced);
345 /* We enlarge buf and move string data up, freeing space
346 * for struct passwd/group/spwd at the beginning. This way,
347 * entire result of getXXnam is in a single malloced block.
348 * This enables easy creation of xmalloc_getpwnam() API.
349 */
350 db->malloced = buf = xrealloc(buf, db->size_of + S.string_size);
351 memmove(buf + db->size_of, buf, S.string_size);
352 return convert_to_struct(db, buf + db->size_of, buf);
353}
354
339/****** getXXnam/id_r */ 355/****** getXXnam/id_r */
340 356
341static int FAST_FUNC getXXnam_r(const char *name, uintptr_t db_and_field_pos, 357static int FAST_FUNC getXXnam_r(const char *name, uintptr_t db_and_field_pos,
@@ -372,6 +388,7 @@ int FAST_FUNC getspnam_r(const char *name, struct spwd *struct_buf, char *buffer
372} 388}
373#endif 389#endif
374 390
391#ifdef UNUSED
375/****** getXXent_r */ 392/****** getXXent_r */
376 393
377static int FAST_FUNC getXXent_r(uintptr_t db_idx, char *buffer, size_t buflen, 394static int FAST_FUNC getXXent_r(uintptr_t db_idx, char *buffer, size_t buflen,
@@ -400,17 +417,39 @@ int FAST_FUNC getpwent_r(struct passwd *struct_buf, char *buffer, size_t buflen,
400 *result = struct_buf; 417 *result = struct_buf;
401 return getXXent_r(0, buffer, buflen, result); 418 return getXXent_r(0, buffer, buflen, result);
402} 419}
420#endif
421
422/****** getXXent */
423
424static void* FAST_FUNC getXXent(uintptr_t db_idx)
425{
426 char *buf;
427 struct passdb *db = &get_S()->db[db_idx];
428
429 if (!db->fp) {
430 db->fp = fopen_for_read(db->filename);
431 if (!db->fp) {
432 return NULL;
433 }
434 close_on_exec_on(fileno(db->fp));
435 }
436
437 buf = parse_common(db->fp, db, /*no search key:*/ NULL, -1);
438 return massage_data_for_non_r_func(db, buf);
439}
440
441struct passwd* FAST_FUNC getpwent(void)
442{
443 return getXXent(0);
444}
403 445
404/****** getXXnam/id */ 446/****** getXXnam/id */
405 447
406static void* FAST_FUNC getXXnam(const char *name, unsigned db_and_field_pos) 448static void* FAST_FUNC getXXnam(const char *name, unsigned db_and_field_pos)
407{ 449{
408 char *buf; 450 char *buf;
409 void *result;
410 struct passdb *db = &get_S()->db[db_and_field_pos >> 2]; 451 struct passdb *db = &get_S()->db[db_and_field_pos >> 2];
411 452
412 result = NULL;
413
414 if (!db->fp) { 453 if (!db->fp) {
415 db->fp = fopen_for_read(db->filename); 454 db->fp = fopen_for_read(db->filename);
416 if (!db->fp) { 455 if (!db->fp) {
@@ -420,18 +459,7 @@ static void* FAST_FUNC getXXnam(const char *name, unsigned db_and_field_pos)
420 } 459 }
421 460
422 buf = parse_common(db->fp, db, name, db_and_field_pos & 3); 461 buf = parse_common(db->fp, db, name, db_and_field_pos & 3);
423 if (buf) { 462 return massage_data_for_non_r_func(db, buf);
424 free(db->malloced);
425 /* We enlarge buf and move string data up, freeing space
426 * for struct passwd/group/spwd at the beginning. This way,
427 * entire result of getXXnam is in a single malloced block.
428 * This enables easy creation of xmalloc_getpwnam() API.
429 */
430 db->malloced = buf = xrealloc(buf, db->size_of + S.string_size);
431 memmove(buf + db->size_of, buf, S.string_size);
432 result = convert_to_struct(db, buf + db->size_of, buf);
433 }
434 return result;
435} 463}
436 464
437struct passwd* FAST_FUNC getpwnam(const char *name) 465struct passwd* FAST_FUNC getpwnam(const char *name)
diff --git a/loginutils/deluser.c b/loginutils/deluser.c
index 2d98ecc58..01a9386bc 100644
--- a/loginutils/deluser.c
+++ b/loginutils/deluser.c
@@ -91,12 +91,11 @@ int deluser_main(int argc, char **argv)
91 if (!member) { 91 if (!member) {
92 /* "delgroup GROUP" */ 92 /* "delgroup GROUP" */
93 struct passwd *pw; 93 struct passwd *pw;
94 struct passwd pwent;
95 /* Check if the group is in use */ 94 /* Check if the group is in use */
96#define passwd_buf bb_common_bufsiz1 95 while ((pw = getpwent()) != NULL) {
97 while (!getpwent_r(&pwent, passwd_buf, sizeof(passwd_buf), &pw)) { 96 if (pw->pw_gid == gr->gr_gid)
98 if (pwent.pw_gid == gr->gr_gid) 97 bb_error_msg_and_die("'%s' still has '%s' as their primary group!",
99 bb_error_msg_and_die("'%s' still has '%s' as their primary group!", pwent.pw_name, name); 98 pw->pw_name, name);
100 } 99 }
101 //endpwent(); 100 //endpwent();
102 } 101 }