summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorewt <devnull@localhost>1996-05-07 03:21:44 +0000
committerewt <devnull@localhost>1996-05-07 03:21:44 +0000
commitc1b755b88174a2e441e8309a209532143ed29a44 (patch)
tree9ad4fe7da9a31c8e974431330c81494f08f80c5f /lib
parentfc92f872116bd0abe4d4844207d0570742e36d6c (diff)
downloadrpm-c1b755b88174a2e441e8309a209532143ed29a44.tar.gz
rpm-c1b755b88174a2e441e8309a209532143ed29a44.tar.bz2
rpm-c1b755b88174a2e441e8309a209532143ed29a44.zip
uses a temp file to pass big file lists to cpio
CVS patchset: 559 CVS date: 1996/05/07 03:21:44
Diffstat (limited to 'lib')
-rw-r--r--lib/install.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/lib/install.c b/lib/install.c
index 2fc9f001c..2bd0f3c94 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 */