commit:     5d3237abbe291149540d2b7c14ed1fe5af50b4ff
Author:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
AuthorDate: Sun Feb 22 21:25:04 2026 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Tue Feb 24 03:32:00 2026 +0000
URL:        https://gitweb.gentoo.org/proj/install-xattr.git/commit/?id=5d3237ab

Simplify logic to find the real install binary

Instead of manipulating PATH and guessing, just bake the path to the
real install binary in at build time.

Also add a "REAL_INSTALL" environment variable to override it at
runtime.

Bug: https://bugs.gentoo.org/963699
Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org>

 Makefile        |  8 ++++--
 install-xattr.c | 86 ++++-----------------------------------------------------
 2 files changed, 11 insertions(+), 83 deletions(-)

diff --git a/Makefile b/Makefile
index 0474569..880b25a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,18 @@
 CFLAGS ?= -O2 -pipe -g
 CFLAGS += -Wall
 PWD = $$(pwd)
+PREFIX ?= /usr
+BINDIR = $(PREFIX)/bin
+REAL_INSTALL ?= $(BINDIR)/install
+CPPFLAGS += '-DREAL_INSTALL="$(REAL_INSTALL)"'
 
 all: install-xattr
 
 install-xattr: install-xattr.c
        $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS)
 
-PREFIX = /usr
-BINDIR = $(PREFIX)/bin
 install: install-xattr
-       install -m 755 -D install-xattr $(DESTDIR)$(BINDIR)/$<
+       install -m 755 -D install-xattr "$(DESTDIR)$(BINDIR)"/$<
 
 check: checkcopyattrs.sh install-xattr
        $(PWD)/checkcopyattrs.sh

diff --git a/install-xattr.c b/install-xattr.c
index ede501f..294dfe2 100644
--- a/install-xattr.c
+++ b/install-xattr.c
@@ -36,6 +36,10 @@
 #include <sys/xattr.h>
 #include <unistd.h>
 
+#ifndef REAL_INSTALL
+#define REAL_INSTALL "/usr/bin/install"
+#endif
+
 static char *
 xstrdup(const char *s)
 {
@@ -175,73 +179,6 @@ copyxattr(const char *source, const char *target)
 }
 
 
-static char *
-which(char *mypath, char *portage_helper_path)
-{
-       /* $PATH for system install */
-       char *path = NULL, *env_path = getenv("PATH");
-
-       /* If we don't have $PATH in our environment, then pick a sane path. */
-       if (env_path == NULL) {
-               size_t len = confstr(_CS_PATH, 0, 0);
-               path = xmalloc(len);
-               confstr(_CS_PATH, path, len);
-       } else
-               path = xstrdup(env_path);
-
-       char *dir;       /* one directory in the colon delimited $PATH string */
-       char *canpath;   /* candidate install's canonical path                */
-       char *savedptr;  /* reentrant context for strtok_r()                  */
-
-       dir = strtok_r(path, ":", &savedptr);
-
-       while (dir) {
-               char *canfile = path_join(dir, "install");
-               canpath = realpath(canfile, NULL);
-               free(canfile);
-
-               /* ignore invalid paths that cannot be canonicalized */
-               if (!canpath)
-                       goto skip;
-
-               /* If argv[0]'s canonical path == candidate install's canonical 
path,
-                * then we skip this path otheriwise we get into an infinite 
self-invocation.
-                */
-               if (!strcmp(mypath, canpath))
-                       goto skip;
-
-               /* If portage install's canonical path == candidate install's 
canonical path,
-                * then we skip this path otheriwise we get into an infinite 
self-invocation.
-                */
-               if (portage_helper_path)
-                       if (!strcmp(portage_helper_path, canpath))
-                               goto skip;
-
-               /* If the canpath exists and is either a regular file or sym 
link,
-                * assume we found the system's install.
-                 */
-               struct stat s;
-
-               if (stat(canpath, &s) == 0)
-                       if (S_ISREG(s.st_mode)) {
-                               free(path);
-                               return canpath;
-                       }
-
-
- skip:
-               free(canpath);
-               dir = strtok_r(NULL, ":", &savedptr);
-       }
-
-       if (env_path == NULL)
-               err(1, "failed to find 'install' in standard utilities path");
-       else
-               err(1, "failed to find 'install' in PATH=%s", env_path);
-}
-
-
-
 int
 main(int argc, char* argv[])
 {
@@ -258,8 +195,6 @@ main(int argc, char* argv[])
        char *target = NULL;           /* the target file or directory          
                       */
        char *path;                    /* path to the target file               
                       */
 
-       char *install;                                   /* path to the system 
install                 */
-
        struct stat s;                 /* test if a file is a regular file or a 
directory              */
 
        char *portage_xattr_exclude;   /* strings of excluded xattr names from 
$PORTAGE_XATTR_EXCLUDE  */
@@ -353,7 +288,6 @@ main(int argc, char* argv[])
         */
        char *oldpwd = getenv("OLDPWD");
        char *portage_helper_path = getenv("__PORTAGE_HELPER_PATH");
-       char *portage_helper_canpath = NULL;
        if (portage_helper_path)
                if (!oldpwd || chdir(oldpwd) != 0)
                        err(1, "failed to chdir %s", oldpwd);
@@ -363,16 +297,8 @@ main(int argc, char* argv[])
                        err(1, "fork() failed");
 
                case 0: {
-                       char *mypath = realpath("/proc/self/exe", NULL); /* 
path to argv[0] */
-
-                       /* find system install avoiding mypath and 
portage_helper_path! */
-                       if (portage_helper_path)
-                               portage_helper_canpath = 
realpath(portage_helper_path, NULL);
-                       install = which(mypath, portage_helper_canpath);
-                       free(mypath);
-                       free(portage_helper_canpath);
-                       argv[0] = install;        /* so coreutils' 
lib/program.c behaves  */
-                       execv(install, argv);     /* The kernel will 
free(install).       */
+                       argv[0] = getenv("REAL_INSTALL") ?: REAL_INSTALL;
+                       execv(argv[0], argv);
                        err(1, "execv() failed");
                }
 

Reply via email to