handle SIGPIPE in built-in cat correctly (LP#1532621)
This commit is contained in:
parent
046d8e5b7a
commit
9167be0584
46
funcs.c
46
funcs.c
|
@ -38,7 +38,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.291 2016/01/19 23:12:13 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.292 2016/01/20 20:29:48 tg Exp $");
|
||||||
|
|
||||||
#if HAVE_KILLPG
|
#if HAVE_KILLPG
|
||||||
/*
|
/*
|
||||||
|
@ -3669,10 +3669,11 @@ c_realpath(const char **wp)
|
||||||
int
|
int
|
||||||
c_cat(const char **wp)
|
c_cat(const char **wp)
|
||||||
{
|
{
|
||||||
int fd = STDIN_FILENO, rv, eno;
|
int fd = STDIN_FILENO, rv;
|
||||||
ssize_t n, w;
|
ssize_t n, w;
|
||||||
const char *fn = "<stdin>";
|
const char *fn = "<stdin>";
|
||||||
char *buf, *cp;
|
char *buf, *cp;
|
||||||
|
int opipe = 0;
|
||||||
#define MKSH_CAT_BUFSIZ 4096
|
#define MKSH_CAT_BUFSIZ 4096
|
||||||
|
|
||||||
/* parse options: POSIX demands we support "-u" as no-op */
|
/* parse options: POSIX demands we support "-u" as no-op */
|
||||||
|
@ -3694,61 +3695,72 @@ c_cat(const char **wp)
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* catch SIGPIPE */
|
||||||
|
opipe = block_pipe();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (*wp) {
|
if (*wp) {
|
||||||
fn = *wp++;
|
fn = *wp++;
|
||||||
if (ksh_isdash(fn))
|
if (ksh_isdash(fn))
|
||||||
fd = STDIN_FILENO;
|
fd = STDIN_FILENO;
|
||||||
else if ((fd = binopen2(fn, O_RDONLY)) < 0) {
|
else if ((fd = binopen2(fn, O_RDONLY)) < 0) {
|
||||||
eno = errno;
|
bi_errorf("%s: %s", fn, cstrerror(errno));
|
||||||
bi_errorf("%s: %s", fn, cstrerror(eno));
|
|
||||||
rv = 1;
|
rv = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (/* CONSTCOND */ 1) {
|
while (/* CONSTCOND */ 1) {
|
||||||
n = blocking_read(fd, (cp = buf), MKSH_CAT_BUFSIZ);
|
if ((n = blocking_read(fd, (cp = buf),
|
||||||
eno = errno;
|
MKSH_CAT_BUFSIZ)) == -1) {
|
||||||
|
if (errno == EINTR) {
|
||||||
|
restore_pipe(opipe);
|
||||||
/* give the user a chance to ^C out */
|
/* give the user a chance to ^C out */
|
||||||
intrcheck();
|
intrcheck();
|
||||||
if (n == -1) {
|
|
||||||
if (eno == EINTR) {
|
|
||||||
/* interrupted, try again */
|
/* interrupted, try again */
|
||||||
|
opipe = block_pipe();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* an error occured during reading */
|
/* an error occured during reading */
|
||||||
bi_errorf("%s: %s", fn, cstrerror(eno));
|
bi_errorf("%s: %s", fn, cstrerror(errno));
|
||||||
rv = 1;
|
rv = 1;
|
||||||
break;
|
break;
|
||||||
} else if (n == 0)
|
} else if (n == 0)
|
||||||
/* end of file reached */
|
/* end of file reached */
|
||||||
break;
|
break;
|
||||||
while (n) {
|
while (n) {
|
||||||
w = write(STDOUT_FILENO, cp, n);
|
if ((w = write(STDOUT_FILENO, cp, n)) != -1) {
|
||||||
eno = errno;
|
n -= w;
|
||||||
|
cp += w;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (errno == EINTR) {
|
||||||
|
restore_pipe(opipe);
|
||||||
/* give the user a chance to ^C out */
|
/* give the user a chance to ^C out */
|
||||||
intrcheck();
|
intrcheck();
|
||||||
if (w == -1) {
|
|
||||||
if (eno == EINTR)
|
|
||||||
/* interrupted, try again */
|
/* interrupted, try again */
|
||||||
|
opipe = block_pipe();
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
if (errno == EPIPE) {
|
||||||
|
/* fake receiving signel */
|
||||||
|
rv = ksh_sigmask(SIGPIPE);
|
||||||
|
} else {
|
||||||
/* an error occured during writing */
|
/* an error occured during writing */
|
||||||
bi_errorf("%s: %s", "<stdout>",
|
bi_errorf("%s: %s", "<stdout>",
|
||||||
cstrerror(eno));
|
cstrerror(errno));
|
||||||
rv = 1;
|
rv = 1;
|
||||||
|
}
|
||||||
if (fd != STDIN_FILENO)
|
if (fd != STDIN_FILENO)
|
||||||
close(fd);
|
close(fd);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
n -= w;
|
|
||||||
cp += w;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (fd != STDIN_FILENO)
|
if (fd != STDIN_FILENO)
|
||||||
close(fd);
|
close(fd);
|
||||||
} while (*wp);
|
} while (*wp);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
restore_pipe(opipe);
|
||||||
free_osfunc(buf);
|
free_osfunc(buf);
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue