sandy

text editor
git clone git://git.suckless.org/sandy
Log | Files | Refs | README | LICENSE

commit 7e15b7be05a5c12c79765eb29863f06376356638
parent 7a101110fb1afe631f15ebfc37716f036768d640
Author: Rafael Garcia <rafael.garcia.gallego@gmail.com>
Date:   Mon, 29 Aug 2011 16:26:35 +0200

Trap stderr in i_pipetext and print a warning if anything comes on it. TODO: print the last line rather than a generic warning
Diffstat:
config.def.h | 4++--
sandy.c | 39+++++++++++++++++++++++++++++----------
2 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -39,8 +39,8 @@ static void f_pipenull(const Arg*); #define FINDBW PROMPT("Find (back):", "${SANDY_FIND}", "?") #define PIPE PROMPT("Pipe:", "${SANDY_PIPE}", "!") #define SAVEAS PROMPT("Save as:", "${SANDY_FILE}", "w") -#define REPLACE PROMPT("Replace:", "", "!echo 2>/dev/null -n ") -#define SED PROMPT("Sed:", "", "!sed 2>/dev/null ") +#define REPLACE PROMPT("Replace:", "", "!echo -n ") +#define SED PROMPT("Sed:", "", "!sed ") #define CMD_P PROMPT("Command:", "/\n?\nw\nq\n!\nsyntax\noffset\nicase\nro\nai", "") /* Args to f_pipe and friends, simple examples are inlined instead */ diff --git a/sandy.c b/sandy.c @@ -932,18 +932,24 @@ void /* Pipe text between fsel and fcur through cmd */ i_pipetext(const char *cmd) { struct timeval tv; char *s = NULL; - int pin[2], pout[2], pid=-1, nr=1, nw, written, iw=0, closed=0, exstatus; - char *buf = NULL; + int pin[2], pout[2], perr[2], pid=-1, nr=1, nerr=1, nw, written, iw=0, closed=0, exstatus; + char *buf = NULL; + char *ebuf = NULL; Filepos auxp; fd_set fdI, fdO; if(!cmd || cmd[0] == '\0') return; setenv(envs[EnvPipe], cmd, 1); - if (pipe(pin) == -1) return; - if (pipe(pout) == -1) { + if(pipe(pin) == -1) return; + if(pipe(pout) == -1) { close(pin[0]); close(pin[1]); return; } + if(pipe(perr) == -1) { + close(pin[0]); close(pin[1]); + close(pout[0]); close(pout[1]); + return; + } i_sortpos(&fsel, &fcur); @@ -954,9 +960,10 @@ i_pipetext(const char *cmd) { if((pid = fork()) == 0) { dup2(pin[0], 0); dup2(pout[1], 1); + dup2(perr[1], 2); close(pin[0]); close(pin[1]); close(pout[0]); close(pout[1]); - /* TODO: close stderr? redirect? update screen?? */ + close(perr[0]); close(perr[1]); execl("/bin/sh", "sh", "-c", cmd, NULL); /* I actually like it with sh so I can input pipes et al. */ fprintf(stderr, "sandy: execl sh -c %s", cmd); perror(" failed"); @@ -966,6 +973,7 @@ i_pipetext(const char *cmd) { if (pid > 0) { close(pin[0]); close(pout[1]); + close(perr[1]); if (t_rw()) { i_addundo(FALSE, fsel, fcur, strdup(s)); undos->flags^=RedoMore; @@ -974,13 +982,15 @@ i_pipetext(const char *cmd) { } fcntl(pin[1], F_SETFL, O_NONBLOCK); fcntl(pout[0], F_SETFL, O_NONBLOCK); - buf = calloc(1, PIPESIZ+1); + fcntl(perr[0], F_SETFL, O_NONBLOCK); + buf = calloc(1, PIPESIZ+1); + ebuf = calloc(1, PIPESIZ+1); FD_ZERO(&fdO); FD_SET(pin[1] , &fdO); - FD_ZERO(&fdI); FD_SET(pout[0], &fdI); + FD_ZERO(&fdI); FD_SET(pout[0], &fdI); FD_SET(perr[0], &fdI); tv.tv_sec = 5; tv.tv_usec = 0; nw=s?strlen(s):0; while (select(FD_SETSIZE, &fdI, &fdO, NULL, &tv) && (nw > 0 || nr > 0)) { fflush(NULL); - if (FD_ISSET(pout[0], &fdI) && nr>0) { + if(FD_ISSET(pout[0], &fdI) && nr>0) { nr = read(pout[0], buf, PIPESIZ); if (nr>=0) buf[nr]='\0'; else break; /* ...not seen it yet */ @@ -991,8 +1001,14 @@ i_pipetext(const char *cmd) { fcur=auxp; } } else if (nr>0) FD_SET(pout[0], &fdI); - else FD_ZERO(&fdI); - if (FD_ISSET(pin[1] , &fdO) && nw>0) { + else FD_CLR(pout[0], &fdI); + if(FD_ISSET(perr[0], &fdI) && nerr>0) { + nerr = read(perr[0], ebuf, PIPESIZ); /* Blatant TODO: take last line of stderr and copy as tmptitle */ + tmptitle="WARNING! command reported an error!!!"; + if(nerr<0) break; + } else if(nerr>0) FD_SET(perr[0], &fdI); + else FD_CLR(perr[0], &fdI); + if(FD_ISSET(pin[1] , &fdO) && nw>0) { written=write(pin[1], &(s[iw]), (nw<PIPESIZ?nw:PIPESIZ)); if (written < 0) break; /* broken pipe? */ iw+=(nw<PIPESIZ?nw:PIPESIZ); @@ -1007,12 +1023,15 @@ i_pipetext(const char *cmd) { if (t_rw()) undos->flags^=RedoMore; free(buf); + free(ebuf); if(!closed) close(pin[1]); waitpid(pid, &exstatus, 0); /* We don't want to close the pipe too soon */ close(pout[0]); + close(perr[0]); } else { close(pin[0]); close(pin[1]); close(pout[0]); close(pout[1]); + close(perr[0]); close(perr[1]); } /* Things I want back to normal */