Use vfork instead of fork, some more cleanup from Vladimir N. Oleynik
This commit is contained in:
parent
393ad1a834
commit
f66de64a11
@ -138,24 +138,20 @@ enum TarFileType {
|
|||||||
typedef enum TarFileType TarFileType;
|
typedef enum TarFileType TarFileType;
|
||||||
|
|
||||||
/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */
|
/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */
|
||||||
static inline void addHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr, dev_t dev,
|
static inline void addHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr,
|
||||||
ino_t ino, short linkCount,
|
struct stat *statbuf,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
/* Note: hlInfoHeadPtr can never be NULL! */
|
/* Note: hlInfoHeadPtr can never be NULL! */
|
||||||
HardLinkInfo *hlInfo;
|
HardLinkInfo *hlInfo;
|
||||||
|
|
||||||
hlInfo =
|
hlInfo = (HardLinkInfo *) xmalloc(sizeof(HardLinkInfo) + strlen(name));
|
||||||
(HardLinkInfo *) xmalloc(sizeof(HardLinkInfo) + strlen(name) + 1);
|
hlInfo->next = *hlInfoHeadPtr;
|
||||||
if (hlInfo) {
|
*hlInfoHeadPtr = hlInfo;
|
||||||
hlInfo->next = *hlInfoHeadPtr;
|
hlInfo->dev = statbuf->st_dev;
|
||||||
*hlInfoHeadPtr = hlInfo;
|
hlInfo->ino = statbuf->st_ino;
|
||||||
hlInfo->dev = dev;
|
hlInfo->linkCount = statbuf->st_nlink;
|
||||||
hlInfo->ino = ino;
|
strcpy(hlInfo->name, name);
|
||||||
hlInfo->linkCount = linkCount;
|
|
||||||
strcpy(hlInfo->name, name);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freeHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr)
|
static void freeHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr)
|
||||||
@ -176,11 +172,10 @@ static void freeHardLinkInfo(HardLinkInfo ** hlInfoHeadPtr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */
|
/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */
|
||||||
static inline HardLinkInfo *findHardLinkInfo(HardLinkInfo * hlInfo, dev_t dev,
|
static inline HardLinkInfo *findHardLinkInfo(HardLinkInfo * hlInfo, struct stat *statbuf)
|
||||||
ino_t ino)
|
|
||||||
{
|
{
|
||||||
while (hlInfo) {
|
while (hlInfo) {
|
||||||
if ((ino == hlInfo->ino) && (dev == hlInfo->dev))
|
if ((statbuf->st_ino == hlInfo->ino) && (statbuf->st_dev == hlInfo->dev))
|
||||||
break;
|
break;
|
||||||
hlInfo = hlInfo->next;
|
hlInfo = hlInfo->next;
|
||||||
}
|
}
|
||||||
@ -366,11 +361,9 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf,
|
|||||||
*/
|
*/
|
||||||
tbInfo->hlInfo = NULL;
|
tbInfo->hlInfo = NULL;
|
||||||
if (statbuf->st_nlink > 1) {
|
if (statbuf->st_nlink > 1) {
|
||||||
tbInfo->hlInfo = findHardLinkInfo(tbInfo->hlInfoHead, statbuf->st_dev,
|
tbInfo->hlInfo = findHardLinkInfo(tbInfo->hlInfoHead, statbuf);
|
||||||
statbuf->st_ino);
|
|
||||||
if (tbInfo->hlInfo == NULL)
|
if (tbInfo->hlInfo == NULL)
|
||||||
addHardLinkInfo(&tbInfo->hlInfoHead, statbuf->st_dev,
|
addHardLinkInfo(&tbInfo->hlInfoHead, statbuf, fileName);
|
||||||
statbuf->st_ino, statbuf->st_nlink, fileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It is against the rules to archive a socket */
|
/* It is against the rules to archive a socket */
|
||||||
@ -460,6 +453,7 @@ static inline int writeTarFile(const char *tarName, const int verboseFlag,
|
|||||||
int gzipDataPipe[2] = { -1, -1 };
|
int gzipDataPipe[2] = { -1, -1 };
|
||||||
int gzipStatusPipe[2] = { -1, -1 };
|
int gzipStatusPipe[2] = { -1, -1 };
|
||||||
pid_t gzipPid = 0;
|
pid_t gzipPid = 0;
|
||||||
|
volatile int vfork_exec_errno = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int errorFlag = FALSE;
|
int errorFlag = FALSE;
|
||||||
@ -495,13 +489,19 @@ static inline int writeTarFile(const char *tarName, const int verboseFlag,
|
|||||||
|
|
||||||
#ifdef CONFIG_FEATURE_TAR_GZIP
|
#ifdef CONFIG_FEATURE_TAR_GZIP
|
||||||
if (gzip) {
|
if (gzip) {
|
||||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, gzipDataPipe) < 0
|
if (pipe(gzipDataPipe) < 0 || pipe(gzipStatusPipe) < 0) {
|
||||||
|| pipe(gzipStatusPipe) < 0)
|
|
||||||
perror_msg_and_die("Failed to create gzip pipe");
|
perror_msg_and_die("Failed to create gzip pipe");
|
||||||
|
}
|
||||||
|
|
||||||
signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */
|
signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */
|
||||||
|
|
||||||
gzipPid = fork();
|
# if __GNUC__
|
||||||
|
/* Avoid vfork clobbering */
|
||||||
|
(void) &include;
|
||||||
|
(void) &errorFlag;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
gzipPid = vfork();
|
||||||
|
|
||||||
if (gzipPid == 0) {
|
if (gzipPid == 0) {
|
||||||
dup2(gzipDataPipe[0], 0);
|
dup2(gzipDataPipe[0], 0);
|
||||||
@ -514,10 +514,9 @@ static inline int writeTarFile(const char *tarName, const int verboseFlag,
|
|||||||
fcntl(gzipStatusPipe[1], F_SETFD, FD_CLOEXEC); /* close on exec shows sucess */
|
fcntl(gzipStatusPipe[1], F_SETFD, FD_CLOEXEC); /* close on exec shows sucess */
|
||||||
|
|
||||||
execl("/bin/gzip", "gzip", "-f", 0);
|
execl("/bin/gzip", "gzip", "-f", 0);
|
||||||
|
vfork_exec_errno = errno;
|
||||||
|
|
||||||
write(gzipStatusPipe[1], "", 1);
|
|
||||||
close(gzipStatusPipe[1]);
|
close(gzipStatusPipe[1]);
|
||||||
|
|
||||||
exit(-1);
|
exit(-1);
|
||||||
} else if (gzipPid > 0) {
|
} else if (gzipPid > 0) {
|
||||||
close(gzipDataPipe[0]);
|
close(gzipDataPipe[0]);
|
||||||
@ -528,9 +527,10 @@ static inline int writeTarFile(const char *tarName, const int verboseFlag,
|
|||||||
|
|
||||||
int n = read(gzipStatusPipe[0], &buf, 1);
|
int n = read(gzipStatusPipe[0], &buf, 1);
|
||||||
|
|
||||||
if (n == 1)
|
if (n == 0 && vfork_exec_errno != 0) {
|
||||||
error_msg_and_die("Could not exec gzip process"); /* socket was not closed => error */
|
errno = vfork_exec_errno;
|
||||||
else if ((n < 0) && (errno == EAGAIN || errno == EINTR))
|
perror_msg_and_die("Could not exec gzip process");
|
||||||
|
} else if ((n < 0) && (errno == EAGAIN || errno == EINTR))
|
||||||
continue; /* try it again */
|
continue; /* try it again */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -538,7 +538,7 @@ static inline int writeTarFile(const char *tarName, const int verboseFlag,
|
|||||||
|
|
||||||
tbInfo.tarFd = gzipDataPipe[1];
|
tbInfo.tarFd = gzipDataPipe[1];
|
||||||
} else {
|
} else {
|
||||||
perror_msg_and_die("Failed to fork gzip process");
|
perror_msg_and_die("Failed to vfork gzip process");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -603,7 +603,7 @@ int tar_main(int argc, char **argv)
|
|||||||
archive_handle_t *tar_handle;
|
archive_handle_t *tar_handle;
|
||||||
int opt;
|
int opt;
|
||||||
char *base_dir = NULL;
|
char *base_dir = NULL;
|
||||||
char *tar_filename = "-";
|
const char *tar_filename = "-";
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_TAR_CREATE
|
#ifdef CONFIG_FEATURE_TAR_CREATE
|
||||||
unsigned char tar_create = FALSE;
|
unsigned char tar_create = FALSE;
|
||||||
|
Loading…
Reference in New Issue
Block a user