summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sponge.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/sponge.c b/sponge.c
index df1b7a1..d232b5d 100644
--- a/sponge.c
+++ b/sponge.c
@@ -286,25 +286,28 @@ int main (int argc, char **argv) {
outname = argv[1];
}
if (tmpfile) {
+ struct stat statbuf;
+
/* write whatever we have in memory to tmpfile */
if (bufused)
write_buff_tmp(bufstart, bufused, tmpfile);
- struct stat statbuf;
- if (outname && !stat(outname, &statbuf)) {
- /* regular file */
- if (S_ISREG(statbuf.st_mode) && !fclose(tmpfile)) {
- if (rename(tmpname, outname)) {
- perror("error renaming temporary file to output file");
- exit(1);
- }
- }
- else {
- FILE *outfd = fopen(outname, "w");
- if (outfd < 0) {
- perror("error opening output file");
- exit(1);
+ fclose(tmpfile);
+
+ if (outname) {
+ /* If it's a regular file, or does not yet exist,
+ * attempt a fast rename of the temp file. */
+ if ((stat(outname, &statbuf) == 0 &&
+ S_ISREG(statbuf.st_mode)) ||
+ errno == ENOENT) {
+ if (rename(tmpname, outname) != 0) {
+ /* Slow copy. */
+ FILE *outfd = fopen(outname, "w");
+ if (outfd < 0) {
+ perror("error opening output file");
+ exit(1);
+ }
+ copy_tmpfile(tmpfile, outfd);
}
- copy_tmpfile(tmpfile, outfd);
}
}
else {