Updated patches. I still prefer the one that's 40 lines shorter :-)
Tony.
--
f.a.n.finch <[EMAIL PROTECTED]> http://dotat.at/
SOUTHEAST ICELAND: SOUTHWEST BECOMING VARIABLE 4. FAIR. GOOD.
--- main.c Mon Jul 29 13:16:44 2002
+++ main.c.two Mon Jul 29 13:08:49 2002
@@ -413,9 +413,7 @@
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 @@
}
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;
}
--- main.c Mon Jul 29 13:16:44 2002
+++ main.c.one Mon Jul 29 13:15:03 2002
@@ -68,6 +68,11 @@
#include "extern.h"
/*
+ * Maximum amount of data to mmap at a time when copying a file.
+ */
+#define MMAP_MAX (16*1024*1024)
+
+/*
* Linked list of units (strings and files) to be compiled
*/
struct s_compunit {
@@ -407,6 +412,8 @@
/*
* Modify a pointer to a filename for inplace editing and reopen stdout
+ *
+ * We remove the files before opening them in case of permissions problems
*/
static int
inplace_edit(filename)
@@ -416,6 +423,7 @@
int input, output;
char backup[MAXPATHLEN];
char *buffer;
+ off_t off, size;
if (lstat(*filename, &orig) == -1)
err(1, "lstat");
@@ -424,37 +432,57 @@
return -1;
}
+ /* create and open the backup file */
if (*inplace == '\0') {
- char template[] = "/tmp/sed.XXXXXXXXXX";
+ const char *tmp;
- output = mkstemp(template);
+ tmp = getenv("TMPDIR");
+ if (tmp == NULL)
+ tmp = "/tmp";
+ strlcpy(backup, tmp, sizeof(backup));
+ strlcat(backup, "/sed.XXXXXXXXXX", sizeof(backup));
+ output = mkstemp(backup);
if (output == -1)
err(1, "mkstemp");
- strlcpy(backup, template, MAXPATHLEN);
+ if (fchmod(output, orig.st_mode & ~S_IFMT) == -1)
+ err(1, "chmod(\"%s\")", backup);
} else {
- strlcpy(backup, *filename, MAXPATHLEN);
- strlcat(backup, inplace, MAXPATHLEN);
- output = open(backup, O_WRONLY | O_CREAT | O_TRUNC);
+ strlcpy(backup, *filename, sizeof(backup));
+ strlcat(backup, inplace, sizeof(backup));
+ if (unlink(backup) == -1 && errno != ENOENT)
+ err(1, "unlink(\"%s\")", backup);
+ output = open(backup, O_WRONLY | O_CREAT | O_TRUNC, orig.st_mode);
if (output == -1)
- err(1, "open(%s)", backup);
+ err(1, "open(\"%s\")", backup);
}
-
+ /* copy the original file to the 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);
+ err(1, "open(\"%s\")", *filename);
+ for (off = 0; off < orig.st_size; off += MMAP_MAX) {
+ size = orig.st_size - off;
+ if (size > MMAP_MAX)
+ size = MMAP_MAX;
+ buffer = mmap(NULL, size, PROT_READ, MAP_SHARED, input, off);
+ if (buffer == MAP_FAILED)
+ err(1, "mmap(\"%s\")", *filename);
+ if (write(output, buffer, size) == -1)
+ err(1, "write(\"%s\")", backup);
+ if (munmap(buffer, size) == -1)
+ err(1, "munmap(\"%s\")", *filename);
+ }
close(input);
close(output);
- freopen(*filename, "w", stdout);
+ /* create the replacement for the original file */
+ if (unlink(*filename) == -1)
+ err(1, "unlink(\"%s\")", *filename);
+ 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;
}
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message