aboutsummaryrefslogtreecommitdiff
path: root/coreutils/test.c
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils/test.c')
-rw-r--r--coreutils/test.c33
1 files changed, 7 insertions, 26 deletions
diff --git a/coreutils/test.c b/coreutils/test.c
index c949a3cc9..d4f93312a 100644
--- a/coreutils/test.c
+++ b/coreutils/test.c
@@ -563,26 +563,11 @@ static int binop(void)
563 /*return 1; - NOTREACHED */ 563 /*return 1; - NOTREACHED */
564} 564}
565 565
566
567static void initialize_group_array(void) 566static void initialize_group_array(void)
568{ 567{
569 int n; 568 group_array = bb_getgroups(&ngroups, NULL);
570
571 /* getgroups may be expensive, try to use it only once */
572 ngroups = 32;
573 do {
574 /* FIXME: ash tries so hard to not die on OOM,
575 * and we spoil it with just one xrealloc here */
576 /* We realloc, because test_main can be entered repeatedly by shell.
577 * Testcase (ash): 'while true; do test -x some_file; done'
578 * and watch top. (some_file must have owner != you) */
579 n = ngroups;
580 group_array = xrealloc(group_array, n * sizeof(gid_t));
581 ngroups = getgroups(n, group_array);
582 } while (ngroups > n);
583} 569}
584 570
585
586/* Return non-zero if GID is one that we have in our groups list. */ 571/* Return non-zero if GID is one that we have in our groups list. */
587//XXX: FIXME: duplicate of existing libbb function? 572//XXX: FIXME: duplicate of existing libbb function?
588// see toplevel TODO file: 573// see toplevel TODO file:
@@ -610,14 +595,10 @@ static int is_a_group_member(gid_t gid)
610/* Do the same thing access(2) does, but use the effective uid and gid, 595/* Do the same thing access(2) does, but use the effective uid and gid,
611 and don't make the mistake of telling root that any file is 596 and don't make the mistake of telling root that any file is
612 executable. */ 597 executable. */
613static int test_eaccess(char *path, int mode) 598static int test_eaccess(struct stat *st, int mode)
614{ 599{
615 struct stat st;
616 unsigned int euid = geteuid(); 600 unsigned int euid = geteuid();
617 601
618 if (stat(path, &st) < 0)
619 return -1;
620
621 if (euid == 0) { 602 if (euid == 0) {
622 /* Root can read or write any file. */ 603 /* Root can read or write any file. */
623 if (mode != X_OK) 604 if (mode != X_OK)
@@ -625,16 +606,16 @@ static int test_eaccess(char *path, int mode)
625 606
626 /* Root can execute any file that has any one of the execute 607 /* Root can execute any file that has any one of the execute
627 * bits set. */ 608 * bits set. */
628 if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) 609 if (st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
629 return 0; 610 return 0;
630 } 611 }
631 612
632 if (st.st_uid == euid) /* owner */ 613 if (st->st_uid == euid) /* owner */
633 mode <<= 6; 614 mode <<= 6;
634 else if (is_a_group_member(st.st_gid)) 615 else if (is_a_group_member(st->st_gid))
635 mode <<= 3; 616 mode <<= 3;
636 617
637 if (st.st_mode & mode) 618 if (st->st_mode & mode)
638 return 0; 619 return 0;
639 620
640 return -1; 621 return -1;
@@ -682,7 +663,7 @@ static int filstat(char *nm, enum token mode)
682 i = W_OK; 663 i = W_OK;
683 if (mode == FILEX) 664 if (mode == FILEX)
684 i = X_OK; 665 i = X_OK;
685 return test_eaccess(nm, i) == 0; 666 return test_eaccess(&s, i) == 0;
686 } 667 }
687 if (is_file_type(mode)) { 668 if (is_file_type(mode)) {
688 if (mode == FILREG) 669 if (mode == FILREG)