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"); }
