According to POSIX[0]: The standard input shall be used if no file operands are specified, and shall be used if a file operand is '-' and the implementation treats the '-' as meaning standard input. Otherwise, the standard input shall not be used. See the INPUT FILES section.
Which we currently don't support: $ cat /tmp/test test $ printf "foo\ntest\nbaz\n" | sed "s/test/bar/" - /tmp/test sed: 0: -: No such file or directory bar So let's fix that while reducing the LoC. I choose too accept stdin with the -i flag, because: 1) It allows us to combine it as an inplace editor and filter in a single operation. 2) It further simplifies the code. So now we can do fancy stuff like: $ printf "foo\ntest\nbaz\n" | ./sed "s/test/bar/" /tmp/test - bar foo bar baz and $ printf "foo\ntest\nbaz\n" | ./sed -i "s/test/bar/" /tmp/test - foo bar baz $ cat /tmp/test bar Note that gsed does support the "-" filename, but treats - in combination with -i as a filename, instead of stdin: $ echo test > - $ gsed -i s/test/bar/ - $ cat ./- bar OK? martijn@ Index: main.c =================================================================== RCS file: /cvs/src/usr.bin/sed/main.c,v retrieving revision 1.38 diff -u -p -r1.38 main.c --- main.c 14 Nov 2018 10:59:33 -0000 1.38 +++ main.c 6 Dec 2018 07:28:15 -0000 @@ -345,32 +345,13 @@ mf_fgets(SPACE *sp, enum e_spflag spflag size_t len; char *p; int c, fd; - static int firstfile; - - if (infile == NULL) { - /* stdin? */ - if (files->fname == NULL) { - if (inplace != NULL) - error(FATAL, "-i may not be used with stdin"); - infile = stdin; - fname = "stdin"; - outfile = stdout; - outfname = "stdout"; - } - - firstfile = 1; - } + static int firstfile = 1; for (;;) { if (infile != NULL && (c = getc(infile)) != EOF) { (void)ungetc(c, infile); break; } - /* If we are here then either eof or no files are open yet */ - if (infile == stdin) { - sp->len = 0; - return (0); - } finish_file(); if (firstfile == 0) files = files->next; @@ -381,6 +362,13 @@ mf_fgets(SPACE *sp, enum e_spflag spflag return (0); } fname = files->fname; + if (fname == NULL || strcmp(fname, "-") == 0) { + infile = stdin; + fname = "stdin"; + outfile = stdout; + outfname = "stdout"; + break; + } if (inplace != NULL) { if (lstat(fname, &sb) != 0) error(FATAL, "%s: %s", fname,