uses a temp file to pass big file lists to cpio
authorewt <devnull@localhost>
Tue, 7 May 1996 03:21:44 +0000 (03:21 +0000)
committerewt <devnull@localhost>
Tue, 7 May 1996 03:21:44 +0000 (03:21 +0000)
CVS patchset: 559
CVS date: 1996/05/07 03:21:44

lib/install.c

index 2fc9f00..2bd0f3c 100644 (file)
@@ -461,6 +461,8 @@ static int installArchive(char * prefix, int fd, struct fileToInstall * files,
     struct fileToInstall * file;
     char * chptr;
     char ** args;
+    char filelist[40] = { '\0' };
+    FILE * f;
     int len;
     int childDead = 0;
 
@@ -492,11 +494,46 @@ static int installArchive(char * prefix, int fd, struct fileToInstall * files,
        args[i++] = "--verbose";
 
     /* note - if fileCount == 0, all files get installed */
+    /* if fileCount > 500, we use a temporary file to pass the file
+       list to cpio rather then args because we're in danger of passing
+       too much argv/env stuff */
+
+    if (fileCount > 500) {
+       message(MESS_DEBUG, "using a /tmp filelist\n");
+       sprintf(filelist, "/tmp/rpm-cpiofilelist.%d.tmp", getpid());
+       f = fopen(filelist, "w");
+       if (!f) {
+           error(RPMERR_CREATE, "failed to create %s: %s", filelist,
+                 strerror(errno));
+           return 1;
+       }
+       
+       for (j = 0; j < fileCount; j++) {
+           if ((fputs(files[j].fileName, f) == EOF) || 
+               (fputs("\n", f) == EOF)) {
+               if (errno == ENOSPC) {
+                   error(RPMERR_NOSPACE, "out of space on device");
+               } else {
+                   error(RPMERR_CREATE, "failed to create %s: %s", filelist,
+                         strerror(errno));
+               }
+
+               fclose(f);
+               unlink(filelist);
+               return 1;
+           }
+       }
+
+       fclose(f);
 
-    for (j = 0; j < fileCount; j++)
-       args[i++] = files[j].fileName;
+       args[i++] = "--pattern-file";
+       args[i++] = filelist;
+    } else {
+       for (j = 0; j < fileCount; j++)
+           args[i++] = files[j].fileName;
 
-    args[i++] = NULL;
+       args[i++] = NULL;
+    }
     
     stream = gzdopen(fd, "r");
     pipe(p);
@@ -551,6 +588,14 @@ static int installArchive(char * prefix, int fd, struct fileToInstall * files,
            bytes = read(statusPipe[0], line, sizeof(line));
 
            while (bytes > 0) {
+               /* the sooner we erase this, the better. less chance
+                  of leaving it sitting around after a SIGINT
+                  (or SIGSEGV!) */
+               if (filelist[0]) {
+                   unlink(filelist);
+                   filelist[0] = '\0';
+               }
+
                fileInstalled.fileName = line;
 
                while ((chptr = (strchr(fileInstalled.fileName, '\n')))) {
@@ -596,6 +641,10 @@ static int installArchive(char * prefix, int fd, struct fileToInstall * files,
     signal(SIGPIPE, oldhandler);
     waitpid(child, &status, 0);
 
+    if (filelist[0]) {
+       unlink(filelist);
+    }
+
     if (cpioFailed || !WIFEXITED(status) || WEXITSTATUS(status)) {
        /* this would probably be a good place to check if disk space
           was used up - if so, we should return a different error */