moreutils (0.42) UNRELEASED; urgency=low
* Typo. Closes: #596032
+ * sponge: Guarantee that output file is always updated atomically,
+ by renaming a temp file into place. Closes: #592144
-- Joey Hess <joeyh@debian.org> Wed, 08 Sep 2010 02:09:29 -0400
FILE *outfile, *tmpfile = 0;
ssize_t i = 0;
size_t mem_available = default_sponge_size();
+ struct stat statbuf;
if (argc > 2 || (argc == 2 && strcmp(argv[1], "-h") == 0)) {
usage();
if (argc == 2) {
outname = argv[1];
}
-
+
+ tmpfile = open_tmpfile();
bufstart = buf = malloc(bufsize);
if (!buf) {
perror("failed to allocate memory");
bufused = bufused+i;
if (bufused == bufsize) {
if ((bufsize*2) >= mem_available) {
- if (!tmpfile) {
- tmpfile=open_tmpfile();
- }
write_buff_tmp(bufstart, bufused, tmpfile);
bufused = 0;
}
perror("failed to read from stdin");
exit(1);
}
- if (tmpfile) {
- struct stat statbuf;
/* write whatever we have in memory to tmpfile */
if (bufused)
! S_ISLNK(statbuf.st_mode)
) || errno == ENOENT) &&
rename(tmpname, outname) == 0) {
+ tmpname=NULL;
/* Fix renamed file mode to match either
* the old file mode, or the default file
* mode for a newly created file. */
exit(1);
}
copy_tmpfile(tmpfile, outfile, bufstart, bufsize);
+ fclose(outfile);
}
else {
copy_tmpfile(tmpfile, stdout, bufstart, bufsize);
}
- }
- else {
- if (outname) {
- outfile = fopen(outname, "w");
- if (!outfile) {
- perror("error opening output file");
- exit(1);
- }
- }
- else {
- outfile = stdout;
- }
- if (bufused)
- write_buff_out(bufstart, bufused, outfile);
- fclose(outfile);
- }
return 0;
}
redirect, sponge soaks up all its input before
opening the output file. This allows constricting
pipelines that read from and write to
- the same file. </para>
+ the same file. It also creates the output file
+ atomically by renaming a temp file into place.</para>
<para>If no output file is specified, sponge outputs to
stdout.</para>