From: ewt Date: Tue, 7 May 1996 03:21:44 +0000 (+0000) Subject: uses a temp file to pass big file lists to cpio X-Git-Tag: rpm-4.4-release~5176 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c1b755b88174a2e441e8309a209532143ed29a44;p=platform%2Fupstream%2Frpm.git uses a temp file to pass big file lists to cpio CVS patchset: 559 CVS date: 1996/05/07 03:21:44 --- diff --git a/lib/install.c b/lib/install.c index 2fc9f00..2bd0f3c 100644 --- a/lib/install.c +++ b/lib/install.c @@ -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 */