summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authorfanf <fanf@FreeBSD.org>2002-07-30 19:42:18 +0000
committerfanf <fanf@FreeBSD.org>2002-07-30 19:42:18 +0000
commitcd1b46e6b0f099c7be2a897f817fe301ee8eb4f8 (patch)
treeb8b7bcf2e4d8116f9a0cf52ef7c9fd45c66c7d2d /usr.bin
parentb2baff05fb67090f8db119f0d0bb418e4d61c212 (diff)
downloadFreeBSD-src-cd1b46e6b0f099c7be2a897f817fe301ee8eb4f8.zip
FreeBSD-src-cd1b46e6b0f099c7be2a897f817fe301ee8eb4f8.tar.gz
Fix some bugs in in-place editing:
(1) errors from freopen were not reported correctly (2) large files were not handled correctly (3) read-only files broke things MFC after: 1 week
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/sed/main.c54
1 files changed, 26 insertions, 28 deletions
diff --git a/usr.bin/sed/main.c b/usr.bin/sed/main.c
index 8b97486..2ccc988 100644
--- a/usr.bin/sed/main.c
+++ b/usr.bin/sed/main.c
@@ -413,9 +413,7 @@ inplace_edit(filename)
char **filename;
{
struct stat orig;
- int input, output;
char backup[MAXPATHLEN];
- char *buffer;
if (lstat(*filename, &orig) == -1)
err(1, "lstat");
@@ -425,36 +423,36 @@ inplace_edit(filename)
}
if (*inplace == '\0') {
- char template[] = "/tmp/sed.XXXXXXXXXX";
-
- output = mkstemp(template);
- if (output == -1)
- err(1, "mkstemp");
- strlcpy(backup, template, MAXPATHLEN);
+ /*
+ * This is a bit of a hack: we use mkstemp() to avoid the
+ * mktemp() link-time warning, although mktemp() would fit in
+ * this context much better. We're only interested in getting
+ * a name for use in the rename(); there aren't any security
+ * issues here that don't already exist in relation to the
+ * original file and its directory.
+ */
+ int fd;
+ strlcpy(backup, *filename, sizeof(backup));
+ strlcat(backup, ".XXXXXXXXXX", sizeof(backup));
+ fd = mkstemp(backup);
+ if (fd == -1)
+ errx(1, "could not create backup of %s", *filename);
+ else
+ close(fd);
} else {
- strlcpy(backup, *filename, MAXPATHLEN);
- strlcat(backup, inplace, MAXPATHLEN);
- output = open(backup, O_WRONLY | O_CREAT | O_TRUNC);
- if (output == -1)
- err(1, "open(%s)", backup);
+ strlcpy(backup, *filename, sizeof(backup));
+ strlcat(backup, inplace, sizeof(backup));
}
- input = open(*filename, O_RDONLY);
- if (input == -1)
- err(1, "open(%s)", *filename);
- if (fchmod(output, orig.st_mode & ~S_IFMT) == -1)
- err(1, "chmod");
- buffer = (char *)mmap(0, orig.st_size, PROT_READ, MAP_SHARED, input, 0);
- if (buffer == MAP_FAILED)
- err(1, "mmap(%s)", *filename);
- if (write(output, buffer, orig.st_size) == -1)
- err(1, "write(%s)", backup);
- if (munmap(buffer, orig.st_size) == -1)
- err(1, "munmap(%s)", *filename);
- close(input);
- close(output);
- freopen(*filename, "w", stdout);
+ if (rename(*filename, backup) == -1)
+ err(1, "rename(\"%s\", \"%s\")", *filename, backup);
+ if (freopen(*filename, "w", stdout) == NULL)
+ err(1, "open(\"%s\")", *filename);
+ if (fchmod(fileno(stdout), orig.st_mode) == -1)
+ err(1, "chmod(\"%s\")", *filename);
*filename = strdup(backup);
+ if (*filename == NULL)
+ err(1, "malloc");
return 0;
}
OpenPOWER on IntegriCloud