commit:     4c222cb0c8945ed2ddcc152584170c16dce1060b
Author:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
AuthorDate: Tue Feb 24 17:25:48 2026 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Tue Feb 24 17:25:48 2026 +0000
URL:        https://gitweb.gentoo.org/proj/install-xattr.git/commit/?id=4c222cb0

Spawn install before processing argv

This avoids the need to copy argv, and allows us to perform argument
processing concurrently with install.

Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org>

 install-xattr.c | 48 ++++++++++++++++++------------------------------
 1 file changed, 18 insertions(+), 30 deletions(-)

diff --git a/install-xattr.c b/install-xattr.c
index d785815..7f9fd31 100644
--- a/install-xattr.c
+++ b/install-xattr.c
@@ -201,8 +201,6 @@ main(int argc, char* argv[])
        int i;
        int status;                    /* exit status of child "install" 
process                       */
 
-       char** argv_copy;              /* copy argv to avoid mangling by 
getopt_long()                 */
-
        int opts_directory = 0;        /* if -d was given, then all arguments 
are directories          */
        int opts_target_directory = 0; /* if -t was given, then we're 
installing to a target directory */
        int target_is_directory = 0;   /* is the target a directory?            
                       */
@@ -215,6 +213,17 @@ main(int argc, char* argv[])
 
        char *portage_xattr_exclude;   /* strings of excluded xattr names from 
$PORTAGE_XATTR_EXCLUDE  */
 
+       /* If this is set it means Portage has switched the working directory
+        * and expects us to switch back. */
+       char *portage_helper_cwd = getenv("__PORTAGE_HELPER_CWD");
+       if (portage_helper_cwd && chdir(portage_helper_cwd))
+               err(1, "failed to chdir %s", portage_helper_cwd);
+
+       argv[0] = getenv("REAL_INSTALL") ?: REAL_INSTALL;
+
+       if (spawn(argv[0], argv) < 0)
+               err(1, "failed to spawn install");
+
        portage_xattr_exclude = getenv("PORTAGE_XATTR_EXCLUDE");
        if (portage_xattr_exclude == NULL)
                exclude = xstrdup("btrfs.* security.* trusted.* 
system.nfs4_acl");
@@ -249,19 +258,9 @@ main(int argc, char* argv[])
                {                     0,                 0, 0,  0 }
        };
 
-       /* We copy argv[] because getopts_long() mangles the order of the 
arguments.
-        * We pass the original argv[] to install in the fork() while we use
-        * argv_copy[] for the copying of the xattrs since optind assumes a 
reorder
-        * parameter list.
-        */
-       argv_copy = (char **)malloc(argc*sizeof(char *));
-
-       for (i = 0; i < argc; i++)
-               argv_copy[i] = strdup(argv[i]);
-
        while (1) {
                int option_index;
-               int c = getopt_long(argc, argv_copy, "dt:g:m:o:S:Zb", 
long_options, &option_index);
+               int c = getopt_long(argc, argv, "dt:g:m:o:S:Zb", long_options, 
&option_index);
 
                if (c == -1)
                        break;
@@ -295,17 +294,6 @@ main(int argc, char* argv[])
        first = optind;
        last = argc - 1;
 
-       /* If this is set it means Portage has switched the working directory
-        * and expects us to switch back. */
-       char *portage_helper_cwd = getenv("__PORTAGE_HELPER_CWD");
-       if (portage_helper_cwd && chdir(portage_helper_cwd))
-               err(1, "failed to chdir %s", portage_helper_cwd);
-
-       argv[0] = getenv("REAL_INSTALL") ?: REAL_INSTALL;
-
-       if (spawn(argv[0], argv) < 0)
-               err(1, "failed to spawn install");
-
        wait(&status);
 
        /* Are there enough files/directories on the cmd line to
@@ -321,7 +309,7 @@ main(int argc, char* argv[])
                goto done;
 
        if (!opts_target_directory) {
-               target = argv_copy[last];
+               target = argv[last];
                if (stat(target, &s) != 0) {
                        err(1, "failed to stat %s", target);
                        return EXIT_FAILURE;
@@ -340,8 +328,8 @@ main(int argc, char* argv[])
                        last++;
 
                for (i = first; i < last; i++) {
-                       if (stat(argv_copy[i], &s) != 0) {
-                               err(1, "failed to stat %s", argv_copy[i]);
+                       if (stat(argv[i], &s) != 0) {
+                               err(1, "failed to stat %s", argv[i]);
                                return EXIT_FAILURE;
                        }
                        /* We reproduce install's behavior and skip
@@ -351,12 +339,12 @@ main(int argc, char* argv[])
                        if (S_ISDIR(s.st_mode))
                                continue;
 
-                       path = path_join(target, basename(argv_copy[i]));
-                       copyxattr(argv_copy[i], path);
+                       path = path_join(target, basename(argv[i]));
+                       copyxattr(argv[i], path);
                        free(path);
                }
        } else
-               copyxattr(argv_copy[first], target);
+               copyxattr(argv[first], target);
 
 
  done:

Reply via email to