aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/sed
diff options
context:
space:
mode:
authorMaxim Sobolev <sobomax@FreeBSD.org>2002-06-14 01:28:52 +0000
committerMaxim Sobolev <sobomax@FreeBSD.org>2002-06-14 01:28:52 +0000
commit8701af62eedb4c3dbf36cf929de519930ebc1064 (patch)
tree4c61f275ec4c541ac0fdb59cba2ea4ad112101b7 /usr.bin/sed
parentad1026f9126c3ad7ac772cbc99ec3de10967cdd2 (diff)
Notes
Diffstat (limited to 'usr.bin/sed')
-rw-r--r--usr.bin/sed/main.c130
1 files changed, 60 insertions, 70 deletions
diff --git a/usr.bin/sed/main.c b/usr.bin/sed/main.c
index de89280202a9..26201315da5c 100644
--- a/usr.bin/sed/main.c
+++ b/usr.bin/sed/main.c
@@ -48,6 +48,8 @@ static const char copyright[] =
static const char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/3/94";
#endif
+#include <sys/types.h>
+#include <sys/mman.h>
#include <sys/param.h>
#include <sys/stat.h>
@@ -300,48 +302,57 @@ mf_fgets(sp, spflag)
size_t len;
char *p;
int c;
+ static int firstfile;
- if (f == NULL)
- /* Advance to first non-empty file */
- for (;;) {
- if (files == NULL) {
- lastline = 1;
- return (0);
- }
- if (files->fname == NULL) {
- if (inplace != NULL)
- errx(1, "-i may not be used with stdin");
- f = stdin;
- fname = "stdin";
- } else {
- if (inplace != NULL) {
- if (inplace_edit(&files->fname) == -1)
- continue;
- }
- fname = files->fname;
- if ((f = fopen(fname, "r")) == NULL) {
- warn("%s", fname);
- rval = 1;
- files = files->next;
- continue;
- }
- if (inplace != NULL && *inplace == '\0')
- unlink(fname);
- }
- if ((c = getc(f)) != EOF) {
- (void)ungetc(c, f);
- break;
- }
- (void)fclose(f);
- files = files->next;
+ if (f == NULL) {
+ /* stdin? */
+ if (files->fname == NULL) {
+ if (inplace != NULL)
+ errx(1, "-i may not be used with stdin");
+ f = stdin;
+ fname = "stdin";
}
-
- if (lastline) {
- sp->len = 0;
- return (0);
+ firstfile = 1;
}
+ sp->len = 0;
+ for (;;) {
+ if (f != NULL && (c = getc(f)) != EOF) {
+ (void)ungetc(c, f);
+ break;
+ }
+ /* If we are here then either eof or no files are open yet */
+ if (f == stdin) {
+ lastline = 1;
+ return (0);
+ }
+ if (f != NULL) {
+ fclose(f);
+ }
+ if (firstfile == 0) {
+ files = files->next;
+ } else
+ firstfile = 0;
+ if (files == NULL) {
+ lastline = 1;
+ return (0);
+ }
+ if (inplace != NULL) {
+ if (inplace_edit(&files->fname) == -1)
+ continue;
+ }
+ fname = files->fname;
+ if ((f = fopen(fname, "r")) == NULL) {
+ warn("%s", fname);
+ continue;
+ }
+ if (inplace != NULL && *inplace == '\0')
+ unlink(fname);
+ }
/*
+ * We are here only when f is open and we still have something to
+ * read from it.
+ *
* Use fgetln so that we can handle essentially infinite input data.
* Can't use the pointer into the stdio buffer as the process space
* because the ungetc() can cause it to move.
@@ -352,35 +363,14 @@ mf_fgets(sp, spflag)
cspace(sp, p, len, spflag);
linenum++;
- /* Advance to next non-empty file */
- while ((c = getc(f)) == EOF) {
- (void)fclose(f);
-next: files = files->next;
- if (files == NULL) {
- lastline = 1;
- return (1);
- }
- if (files->fname == NULL) {
- if (inplace != NULL)
- errx(1, "-i may not be used with stdin");
- f = stdin;
- fname = "stdin";
+ if (files->next == NULL) {
+ if ((c = getc(f)) != EOF) {
+ (void)ungetc(c, f);
} else {
- if (inplace != NULL) {
- if (inplace_edit(&files->fname) == -1)
- continue;
- }
- fname = files->fname;
- if ((f = fopen(fname, "r")) == NULL) {
- warn("%s", fname);
- rval = 1;
- goto next;
- }
- if (inplace != NULL && *inplace == '\0')
- unlink(fname);
+ lastline = 1;
}
}
- (void)ungetc(c, f);
+
return (1);
}
@@ -449,7 +439,7 @@ inplace_edit(filename)
} else {
strlcpy(backup, *filename, MAXPATHLEN);
strlcat(backup, inplace, MAXPATHLEN);
- output = open(backup, O_WRONLY | O_CREAT | O_EXCL);
+ output = open(backup, O_WRONLY | O_CREAT | O_TRUNC);
if (output == -1)
err(1, "open(%s)", backup);
}
@@ -459,13 +449,13 @@ inplace_edit(filename)
err(1, "open(%s)", *filename);
if (fchmod(output, orig.st_mode & ~S_IFMT) == -1)
err(1, "chmod");
- buffer = malloc(orig.st_size);
- if (buffer == NULL)
- errx(1, "malloc failed");
- if (read(input, buffer, orig.st_size) == -1)
- err(1, "read");
+ 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");
+ 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);