When in compress mode, don't overwrite the destination file directly,

write a temp file and use rename when it is done. (From James Mathiesen
<james@deshaw.com>)
This commit is contained in:
christos 1997-07-15 18:15:55 +00:00
parent 6937751466
commit 7d52497961
2 changed files with 61 additions and 15 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: run.c,v 1.6 1997/06/17 18:56:30 christos Exp $ */
/* $NetBSD: run.c,v 1.7 1997/07/15 18:15:55 christos Exp $ */
/*
* Copyright (c) 1991 Carnegie Mellon University
@ -257,7 +257,39 @@ runio(argv, infile, outfile, errfile)
if (fd != 2)
(void) dup2(fd, 2);
}
execvp(argv[0], argv);
exit(1);
/*NOTREACHED*/
return 0;
default:
if (waitpid(pid, &status, 0) == -1)
return -1;
return status;
}
}
/*
* Like runio, but works with filedescriptors instead of filenames
*/
int
runiofd(argv, infile, outfile, errfile)
char *const argv[];
const int infile;
const int outfile;
const int errfile;
{
pid_t pid;
int status;
switch ((pid = fork())) {
case -1:
return -1;
case 0:
if (infile != 0) dup2(infile, 0);
if (outfile != 1) dup2(outfile,1);
if (errfile != 2) dup2(errfile,2);
execvp(argv[0], argv);
exit(1);
/*NOTREACHED*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: supcmeat.c,v 1.12 1997/07/08 05:01:16 mikel Exp $ */
/* $NetBSD: supcmeat.c,v 1.13 1997/07/15 18:15:56 christos Exp $ */
/*
* Copyright (c) 1992 Carnegie Mellon University
@ -1225,26 +1225,40 @@ char *from; /* 0 if reading from network */
lockout (FALSE);
return (FALSE);
}
/* uncompress it first */
/*
** If the file is compressed, uncompress it in place. We open the
** temp file for reading, unlink the file, and then open the same
** file again for writing. Then we pipe through gzip. When
** finished the temp file contains the uncompressed version and we
** can continue as before.
**
** Since sup prefers to write close to the original file the
** benefits of atomic updates probably outweigh the cost of the
** extra filecopy which occurs when the temp file is on a different
** filesystem from the original.
*/
if (docompress) {
char *av[4];
int ac = 0;
int infd = -1;
int outfd = -1;
av[ac++] = "gzip";
av[ac++] = "-d";
av[ac++] = NULL;
if (runio(av, tname, to, NULL) != 0) {
/* Uncompress it onto the destination */
notify ("SUP: Error in uncompressing file %s\n",
to);
if ( (infd = open(tname, O_RDONLY)) == -1 ||
unlink(tname) == -1 ||
(outfd = open(tname, O_WRONLY|O_CREAT|O_TRUNC)) == -1 ||
runiofd( av, infd, outfd, 2 ) != 0 ) {
notify("SUP: Error in uncompressing file %s (%s)\n",
to, tname );
(void) unlink (tname);
/* Just in case */
(void) unlink (to);
lockout (FALSE);
return (TRUE);
if ( infd != -1 ) (void) close (infd);
if ( outfd != -1 ) (void) close (outfd);
lockout(FALSE);
return(TRUE);
}
(void) unlink (tname);
lockout (FALSE);
return (FALSE);
(void) close(infd);
(void) close(outfd);
}
/* move to destination */
if (rename (tname,to) == 0) {