aboutsummaryrefslogtreecommitdiffstats
path: root/pw.c
diff options
context:
space:
mode:
Diffstat (limited to 'pw.c')
-rw-r--r--pw.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/pw.c b/pw.c
index 23a7beb..b12c8de 100644
--- a/pw.c
+++ b/pw.c
@@ -1156,14 +1156,19 @@ static char **resizebuf(char **buf, size_t nlfrom, size_t nlto)
return buf;
}
-int isbkgnd(FILE *tty)
+int isbkgnd(int ttyfd)
{
- int fd = fileno(tty);
pid_t grp = getpgrp();
- pid_t fgrp = tcgetpgrp(fd);
+ pid_t fgrp = tcgetpgrp(ttyfd);
return (grp != fgrp);
}
+int ismytty(int ttyfd)
+{
+ pid_t fgrp = tcgetpgrp(ttyfd);
+ return fgrp != -1;
+}
+
void clipsplits(pwstate *pw)
{
int columns = pw->columns;
@@ -1188,6 +1193,7 @@ int main(int argc, char **argv)
size_t maxlen = 2047;
int opt;
int ifd = fileno(stdin);
+ int ofd = fileno(stdout);
int ttyfd = tty ? fileno(tty) : -1;
struct termios tty_saved, tty_new;
struct winsize ws = { 0 };
@@ -1198,6 +1204,7 @@ int main(int argc, char **argv)
int auto_quit = 1;
int quit_count = 1, quit_cntdwn = quit_count;
int exit_status = EXIT_FAILURE;
+ FILE *out = NULL;
#ifdef SIGWINCH
static struct sigaction sa;
#endif
@@ -1220,6 +1227,12 @@ int main(int argc, char **argv)
}
}
+ if (!isatty(ofd) || !ismytty(ttyfd)) {
+ int dup_ofd = dup(ofd);
+ dup2(ttyfd, ofd);
+ out = fdopen(dup_ofd, "w");
+ }
+
while ((opt = getopt(argc, argv, "n:i:l:dEBg:q:m:p:e:f:")) != -1) {
switch (opt) {
case 'n':
@@ -1392,7 +1405,7 @@ int main(int argc, char **argv)
if (fcntl(ifd, F_SETFL, O_NONBLOCK) < 0)
panic("unable to set stdin nonblocking");
- if (!isbkgnd(stdout))
+ if (!isbkgnd(ttyfd))
ttyset(ttyfd, &tty_new);
else
pw.stat = stat_bkgnd;
@@ -1415,9 +1428,14 @@ int main(int argc, char **argv)
if ((pw.stat & stat_eof) == 0) {
int ch;
- while ((ch = getc(stdin)) != EOF && ch != '\n' && dslen(line) < maxlen)
+ while ((ch = getchar()) != EOF && ch != '\n' && dslen(line) < maxlen) {
line = addchesc(line, pw.tstop, ch);
+ if (out)
+ putc(ch, out);
+ }
if (ch == EOF) {
+ if (out)
+ fflush(out);
if (feof(stdin) || (errno != EAGAIN && errno != EWOULDBLOCK)) {
nfds = 1;
if (!ferror(stdin))
@@ -1430,9 +1448,13 @@ int main(int argc, char **argv)
pw.stat |= stat_eof;
clrline(pw.stat);
drawstatus(&pw);
+ if (out)
+ fflush(out);
}
clearerr(stdin);
} else if (ch == '\n') {
+ if (out)
+ putc(ch, out);
nfds = 1;
line = dsensure(line);
if ((pw.stat & stat_grep)) {
@@ -1552,7 +1574,7 @@ int main(int argc, char **argv)
work = workbout;
if ((pw.stat & stat_bkgnd)) {
- if (!isbkgnd(stdout)) {
+ if (!isbkgnd(ttyfd)) {
pw.stat &= ~stat_bkgnd;
ttyset(ttyfd, &tty_new);
for (int i = 0; i < pw.nlines; i++)
@@ -2055,6 +2077,9 @@ int main(int argc, char **argv)
ttyset(ttyfd, &tty_saved);
}
+ if (out)
+ fclose(out);
+
#if CONFIG_DEBUG_LEAKS
freebuf(pw.circbuf, pw.maxlines);
free(pw.circbuf);