diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2002-11-25 23:57:27 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2002-11-25 23:57:27 +0000 |
commit | f66de64a1123670b68233d64cb3c0921bee57f8a (patch) | |
tree | 802d6964addca34903ced8256e0801f9e32ef8d9 /archival/tar.c | |
parent | 393ad1a834071c441abc5ab55bd3651f1903a842 (diff) | |
download | busybox-w32-f66de64a1123670b68233d64cb3c0921bee57f8a.tar.gz busybox-w32-f66de64a1123670b68233d64cb3c0921bee57f8a.tar.bz2 busybox-w32-f66de64a1123670b68233d64cb3c0921bee57f8a.zip |
Use vfork instead of fork, some more cleanup from Vladimir N. Oleynik
Diffstat (limited to 'archival/tar.c')
-rw-r--r-- | archival/tar.c | 62 |
1 files changed, 31 insertions, 31 deletions
diff --git a/archival/tar.c b/archival/tar.c index bafb7033c..379220291 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -138,24 +138,20 @@ enum TarFileType { | |||
138 | typedef enum TarFileType TarFileType; | 138 | typedef enum TarFileType TarFileType; |
139 | 139 | ||
140 | /* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */ | 140 | /* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */ |
141 | static inline void addHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr, dev_t dev, | 141 | static inline void addHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr, |
142 | ino_t ino, short linkCount, | 142 | struct stat *statbuf, |
143 | const char *name) | 143 | const char *name) |
144 | { | 144 | { |
145 | /* Note: hlInfoHeadPtr can never be NULL! */ | 145 | /* Note: hlInfoHeadPtr can never be NULL! */ |
146 | HardLinkInfo *hlInfo; | 146 | HardLinkInfo *hlInfo; |
147 | 147 | ||
148 | hlInfo = | 148 | hlInfo = (HardLinkInfo *) xmalloc(sizeof(HardLinkInfo) + strlen(name)); |
149 | (HardLinkInfo *) xmalloc(sizeof(HardLinkInfo) + strlen(name) + 1); | 149 | hlInfo->next = *hlInfoHeadPtr; |
150 | if (hlInfo) { | 150 | *hlInfoHeadPtr = hlInfo; |
151 | hlInfo->next = *hlInfoHeadPtr; | 151 | hlInfo->dev = statbuf->st_dev; |
152 | *hlInfoHeadPtr = hlInfo; | 152 | hlInfo->ino = statbuf->st_ino; |
153 | hlInfo->dev = dev; | 153 | hlInfo->linkCount = statbuf->st_nlink; |
154 | hlInfo->ino = ino; | 154 | strcpy(hlInfo->name, name); |
155 | hlInfo->linkCount = linkCount; | ||
156 | strcpy(hlInfo->name, name); | ||
157 | } | ||
158 | return; | ||
159 | } | 155 | } |
160 | 156 | ||
161 | static void freeHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr) | 157 | static void freeHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr) |
@@ -176,11 +172,10 @@ static void freeHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr) | |||
176 | } | 172 | } |
177 | 173 | ||
178 | /* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */ | 174 | /* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */ |
179 | static inline HardLinkInfo *findHardLinkInfo(HardLinkInfo * hlInfo, dev_t dev, | 175 | static inline HardLinkInfo *findHardLinkInfo(HardLinkInfo * hlInfo, struct stat *statbuf) |
180 | ino_t ino) | ||
181 | { | 176 | { |
182 | while (hlInfo) { | 177 | while (hlInfo) { |
183 | if ((ino == hlInfo->ino) && (dev == hlInfo->dev)) | 178 | if ((statbuf->st_ino == hlInfo->ino) && (statbuf->st_dev == hlInfo->dev)) |
184 | break; | 179 | break; |
185 | hlInfo = hlInfo->next; | 180 | hlInfo = hlInfo->next; |
186 | } | 181 | } |
@@ -366,11 +361,9 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, | |||
366 | */ | 361 | */ |
367 | tbInfo->hlInfo = NULL; | 362 | tbInfo->hlInfo = NULL; |
368 | if (statbuf->st_nlink > 1) { | 363 | if (statbuf->st_nlink > 1) { |
369 | tbInfo->hlInfo = findHardLinkInfo(tbInfo->hlInfoHead, statbuf->st_dev, | 364 | tbInfo->hlInfo = findHardLinkInfo(tbInfo->hlInfoHead, statbuf); |
370 | statbuf->st_ino); | ||
371 | if (tbInfo->hlInfo == NULL) | 365 | if (tbInfo->hlInfo == NULL) |
372 | addHardLinkInfo(&tbInfo->hlInfoHead, statbuf->st_dev, | 366 | addHardLinkInfo(&tbInfo->hlInfoHead, statbuf, fileName); |
373 | statbuf->st_ino, statbuf->st_nlink, fileName); | ||
374 | } | 367 | } |
375 | 368 | ||
376 | /* It is against the rules to archive a socket */ | 369 | /* It is against the rules to archive a socket */ |
@@ -460,6 +453,7 @@ static inline int writeTarFile(const char *tarName, const int verboseFlag, | |||
460 | int gzipDataPipe[2] = { -1, -1 }; | 453 | int gzipDataPipe[2] = { -1, -1 }; |
461 | int gzipStatusPipe[2] = { -1, -1 }; | 454 | int gzipStatusPipe[2] = { -1, -1 }; |
462 | pid_t gzipPid = 0; | 455 | pid_t gzipPid = 0; |
456 | volatile int vfork_exec_errno = 0; | ||
463 | #endif | 457 | #endif |
464 | 458 | ||
465 | int errorFlag = FALSE; | 459 | int errorFlag = FALSE; |
@@ -495,13 +489,19 @@ static inline int writeTarFile(const char *tarName, const int verboseFlag, | |||
495 | 489 | ||
496 | #ifdef CONFIG_FEATURE_TAR_GZIP | 490 | #ifdef CONFIG_FEATURE_TAR_GZIP |
497 | if (gzip) { | 491 | if (gzip) { |
498 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, gzipDataPipe) < 0 | 492 | if (pipe(gzipDataPipe) < 0 || pipe(gzipStatusPipe) < 0) { |
499 | || pipe(gzipStatusPipe) < 0) | ||
500 | perror_msg_and_die("Failed to create gzip pipe"); | 493 | perror_msg_and_die("Failed to create gzip pipe"); |
494 | } | ||
501 | 495 | ||
502 | signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ | 496 | signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ |
503 | 497 | ||
504 | gzipPid = fork(); | 498 | # if __GNUC__ |
499 | /* Avoid vfork clobbering */ | ||
500 | (void) &include; | ||
501 | (void) &errorFlag; | ||
502 | # endif | ||
503 | |||
504 | gzipPid = vfork(); | ||
505 | 505 | ||
506 | if (gzipPid == 0) { | 506 | if (gzipPid == 0) { |
507 | dup2(gzipDataPipe[0], 0); | 507 | dup2(gzipDataPipe[0], 0); |
@@ -514,10 +514,9 @@ static inline int writeTarFile(const char *tarName, const int verboseFlag, | |||
514 | fcntl(gzipStatusPipe[1], F_SETFD, FD_CLOEXEC); /* close on exec shows sucess */ | 514 | fcntl(gzipStatusPipe[1], F_SETFD, FD_CLOEXEC); /* close on exec shows sucess */ |
515 | 515 | ||
516 | execl("/bin/gzip", "gzip", "-f", 0); | 516 | execl("/bin/gzip", "gzip", "-f", 0); |
517 | vfork_exec_errno = errno; | ||
517 | 518 | ||
518 | write(gzipStatusPipe[1], "", 1); | ||
519 | close(gzipStatusPipe[1]); | 519 | close(gzipStatusPipe[1]); |
520 | |||
521 | exit(-1); | 520 | exit(-1); |
522 | } else if (gzipPid > 0) { | 521 | } else if (gzipPid > 0) { |
523 | close(gzipDataPipe[0]); | 522 | close(gzipDataPipe[0]); |
@@ -528,9 +527,10 @@ static inline int writeTarFile(const char *tarName, const int verboseFlag, | |||
528 | 527 | ||
529 | int n = read(gzipStatusPipe[0], &buf, 1); | 528 | int n = read(gzipStatusPipe[0], &buf, 1); |
530 | 529 | ||
531 | if (n == 1) | 530 | if (n == 0 && vfork_exec_errno != 0) { |
532 | error_msg_and_die("Could not exec gzip process"); /* socket was not closed => error */ | 531 | errno = vfork_exec_errno; |
533 | else if ((n < 0) && (errno == EAGAIN || errno == EINTR)) | 532 | perror_msg_and_die("Could not exec gzip process"); |
533 | } else if ((n < 0) && (errno == EAGAIN || errno == EINTR)) | ||
534 | continue; /* try it again */ | 534 | continue; /* try it again */ |
535 | break; | 535 | break; |
536 | } | 536 | } |
@@ -538,7 +538,7 @@ static inline int writeTarFile(const char *tarName, const int verboseFlag, | |||
538 | 538 | ||
539 | tbInfo.tarFd = gzipDataPipe[1]; | 539 | tbInfo.tarFd = gzipDataPipe[1]; |
540 | } else { | 540 | } else { |
541 | perror_msg_and_die("Failed to fork gzip process"); | 541 | perror_msg_and_die("Failed to vfork gzip process"); |
542 | } | 542 | } |
543 | } | 543 | } |
544 | #endif | 544 | #endif |
@@ -603,7 +603,7 @@ int tar_main(int argc, char **argv) | |||
603 | archive_handle_t *tar_handle; | 603 | archive_handle_t *tar_handle; |
604 | int opt; | 604 | int opt; |
605 | char *base_dir = NULL; | 605 | char *base_dir = NULL; |
606 | char *tar_filename = "-"; | 606 | const char *tar_filename = "-"; |
607 | 607 | ||
608 | #ifdef CONFIG_FEATURE_TAR_CREATE | 608 | #ifdef CONFIG_FEATURE_TAR_CREATE |
609 | unsigned char tar_create = FALSE; | 609 | unsigned char tar_create = FALSE; |