From b46085271a02e6623e10b66c7874c8a1afddfd8b Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Thu, 13 Jul 2017 10:51:52 -0400 Subject: [PATCH] cleaned up exec.c a bit. Still need to get rid of blocking command execution... --- inc/edit.h | 9 +-- lib/colors.c | 7 +- lib/exec.c | 189 ++++++++++++++++++++------------------------------- lib/x11.c | 2 +- tide.c | 16 +++-- 5 files changed, 87 insertions(+), 136 deletions(-) diff --git a/inc/edit.h b/inc/edit.h index 0396d24..c2323ec 100644 --- a/inc/edit.h +++ b/inc/edit.h @@ -224,13 +224,10 @@ Rune view_getrune(View* view); /* Command Executions *****************************************************************************/ -int cmdspawn(char** cmd, int* in, int* out); -int cmdrun(char** cmd, char** err); -char* cmdread(char** cmd, char** err); -void cmdwrite(char** cmd, char* text, char** err); -char* cmdwriteread(char** cmd, char* text, char** err); -void exec_reap(void); +bool exec_reap(void); void exec_job(char** cmd, char* data, size_t ndata, View* dest); +void exec_cmd(char** cmd, char* text, char** out, char** err); +int exec_spawn(char** cmd, int* in, int* out); /* Configuration Data *****************************************************************************/ diff --git a/lib/colors.c b/lib/colors.c index 3a9d7b1..5728270 100644 --- a/lib/colors.c +++ b/lib/colors.c @@ -16,7 +16,7 @@ static int read_num(void); void colors_init(char* path) { if (config_get_bool(SyntaxEnabled)) - cmdspawn((char*[]){ "tide-hl.rb", path, NULL }, &ChildIn, &ChildOut); + exec_spawn((char*[]){ "tide-hl.rb", path, NULL }, &ChildIn, &ChildOut); } SyntaxSpan* colors_scan(SyntaxSpan* spans, Buf* buf, size_t beg, size_t end) { @@ -37,13 +37,10 @@ SyntaxSpan* colors_scan(SyntaxSpan* spans, Buf* buf, size_t beg, size_t end) { if (e > 0 && c > 0) { c = (c > 15 ? config_get_int(SynNormal + (c >> 4) - 1) : c) & 0xf; currspan = mkspan(beg+b, beg+e-1, c, currspan); - //printf("(%lu-%lu) %lu,%lu,%lu\n", beg, end, b, e, c); } if (!firstspan) firstspan = currspan; } while (e > 0); - //printf("left: %lu\n", DataEnd-DataBeg); - //printf("done\n\n"); fflush(stdout); DataBeg = DataEnd = Buffer; } @@ -94,9 +91,7 @@ static void write_chunk(Buf* buf, size_t beg, size_t end) { } } long nwrite = write(ChildIn, wbuf, wlen); - //printf("write: %lu -> %d\n", wlen, nwrite); if (nwrite < 0) { - //perror("write failed:"); /* child process probably died. shut everything down */ close(ChildIn), ChildIn = -1; close(ChildOut), ChildOut = -1; diff --git a/lib/exec.c b/lib/exec.c index f48be39..e6e063e 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -6,8 +6,6 @@ #include #include -static uint NumChildren = 0; - #define PIPE_READ 0 #define PIPE_WRITE 1 @@ -18,120 +16,6 @@ typedef struct { int err; /* file descriptor for the child process's standard error */ } Proc; -static int execute(char** cmd, Proc* proc) { - int inpipe[2], outpipe[2], errpipe[2]; - /* create the pipes */ - if ((pipe(inpipe) < 0) || (pipe(outpipe) < 0) || (pipe(errpipe) < 0)) - return -1; - /* create the process */ - proc->pid = fork(); - if (proc->pid < 0) { - /* signal that we failed to fork */ - proc->in = -1; - proc->out = -1; - proc->err = -1; - } else if (0 == proc->pid) { - /* redirect child process's io to the pipes */ - if ((dup2(inpipe[PIPE_READ], STDIN_FILENO) < 0) || - (dup2(outpipe[PIPE_WRITE], STDOUT_FILENO) < 0) || - (dup2(errpipe[PIPE_WRITE], STDERR_FILENO) < 0)) { - perror("failed to pipe"); - exit(1); - } - /* execute the process */ - close(inpipe[PIPE_WRITE]); - close(outpipe[PIPE_READ]); - close(errpipe[PIPE_READ]); - exit(execvp(cmd[0], cmd)); - } else { - close(inpipe[PIPE_READ]); - close(outpipe[PIPE_WRITE]); - close(errpipe[PIPE_WRITE]); - proc->in = inpipe[PIPE_WRITE]; - proc->out = outpipe[PIPE_READ]; - proc->err = errpipe[PIPE_READ]; - } - return proc->pid; -} - -int cmdspawn(char** cmd, int* in, int* out) { - Proc proc; - if (execute(cmd, &proc) < 0) { - perror("failed to execute"); - return -1; - } - *in = proc.in; - *out = proc.out; - return proc.pid; -} - -int cmdrun(char** cmd, char** err) { - Proc proc; - if (execute(cmd, &proc) < 0) { - perror("failed to execute"); - return -1; - } - NumChildren++; - if (err) *err = fdgets(proc.err); - close(proc.in); - close(proc.out); - close(proc.err); - return proc.pid; -} - -char* cmdread(char** cmd, char** err) { - Proc proc; - if (execute(cmd, &proc) < 0) { - perror("failed to execute"); - return NULL; - } - close(proc.in); - char* str = fdgets(proc.out); - close(proc.out); - if (err) *err = fdgets(proc.err); - close(proc.err); - waitpid(proc.pid, NULL, 0); - return str; -} - -void cmdwrite(char** cmd, char* text, char** err) { - Proc proc; - if (execute(cmd, &proc) < 0) { - perror("failed to execute"); - return; - } - if (text && write(proc.in, text, strlen(text)) < 0) { - perror("failed to write"); - return; - } - close(proc.in); - if (err) *err = fdgets(proc.err); - close(proc.err); - close(proc.out); - waitpid(proc.pid, NULL, 0); -} - -char* cmdwriteread(char** cmd, char* text, char** err) { - Proc proc; - if (execute(cmd, &proc) < 0) { - perror("failed to execute"); - return NULL; - } - if (text && write(proc.in, text, strlen(text)) < 0) { - perror("failed to write"); - return NULL; - } - close(proc.in); - char* str = fdgets(proc.out); - close(proc.out); - if (err) *err = fdgets(proc.err); - close(proc.err); - waitpid(proc.pid, NULL, 0); - return str; -} - -/******************************************************************************/ - typedef struct Job Job; typedef struct { @@ -158,8 +42,9 @@ static void send_data(int fd, void* data); static void recv_data(int fd, void* data); static void watch_or_close(bool valid, int dir, int fd, void* data); static void rcvr_finish(Rcvr* rcvr); +static int execute(char** cmd, Proc* proc); -void exec_reap(void) { +bool exec_reap(void) { int pid; while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) { Job* job = JobList; @@ -176,6 +61,7 @@ void exec_reap(void) { free(job); } } + return (JobList != NULL); } void exec_job(char** cmd, char* data, size_t ndata, View* dest) { @@ -204,6 +90,39 @@ void exec_job(char** cmd, char* data, size_t ndata, View* dest) { } } +void exec_cmd(char** cmd, char* text, char** out, char** err) { + Proc proc; + if (execute(cmd, &proc) < 0) { + perror("failed to execute"); + return; + } + /* send the input to stdin of the command */ + if (text && write(proc.in, text, strlen(text)) < 0) { + perror("failed to write"); + return; + } + close(proc.in); + /* read the stderr of the command */ + if (err) *err = fdgets(proc.err); + close(proc.err); + /* read the stdout of the command */ + if (out) *out = fdgets(proc.out); + close(proc.out); + /* wait for the process to finish */ + waitpid(proc.pid, NULL, 0); +} + +int exec_spawn(char** cmd, int* in, int* out) { + Proc proc; + if (execute(cmd, &proc) < 0) { + perror("failed to execute"); + return -1; + } + *in = proc.in; + *out = proc.out; + return proc.pid; +} + static void send_data(int fd, void* data) { Job* job = data; long nwrite = write(fd, (job->data + job->nwrite), job->ndata); @@ -260,3 +179,39 @@ static void rcvr_finish(Rcvr* rcvr) { view->selection.end = rcvr->beg + rcvr->count; } } + +static int execute(char** cmd, Proc* proc) { + int inpipe[2], outpipe[2], errpipe[2]; + /* create the pipes */ + if ((pipe(inpipe) < 0) || (pipe(outpipe) < 0) || (pipe(errpipe) < 0)) + return -1; + /* create the process */ + proc->pid = fork(); + if (proc->pid < 0) { + /* signal that we failed to fork */ + proc->in = -1; + proc->out = -1; + proc->err = -1; + } else if (0 == proc->pid) { + /* redirect child process's io to the pipes */ + if ((dup2(inpipe[PIPE_READ], STDIN_FILENO) < 0) || + (dup2(outpipe[PIPE_WRITE], STDOUT_FILENO) < 0) || + (dup2(errpipe[PIPE_WRITE], STDERR_FILENO) < 0)) { + perror("failed to pipe"); + exit(1); + } + /* execute the process */ + close(inpipe[PIPE_WRITE]); + close(outpipe[PIPE_READ]); + close(errpipe[PIPE_READ]); + exit(execvp(cmd[0], cmd)); + } else { + close(inpipe[PIPE_READ]); + close(outpipe[PIPE_WRITE]); + close(errpipe[PIPE_WRITE]); + proc->in = inpipe[PIPE_WRITE]; + proc->out = outpipe[PIPE_READ]; + proc->err = errpipe[PIPE_READ]; + } + return proc->pid; +} diff --git a/lib/x11.c b/lib/x11.c index f26b52d..f59e849 100644 --- a/lib/x11.c +++ b/lib/x11.c @@ -198,7 +198,7 @@ void x11_finish(void) { XCloseDisplay(X.display); /* we're exiting now. If we own the clipboard, make sure it persists */ if (Selections[CLIPBOARD].text) - cmdwrite((char*[]){ "xcpd", NULL }, Selections[CLIPBOARD].text, NULL); + exec_cmd((char*[]){ "xcpd", NULL }, Selections[CLIPBOARD].text, NULL, NULL); } /******************************************************************************/ diff --git a/tide.c b/tide.c index da7b1ec..0f84018 100644 --- a/tide.c +++ b/tide.c @@ -272,7 +272,8 @@ static void find(char* arg) { } static void open_file(void) { - char* file = cmdread(PickFileCmd, NULL); + char* file = NULL; + exec_cmd(PickFileCmd, NULL, &file, NULL); if (file) { file = chomp(file); if ((!win_buf(EDIT)->path || x11_keymodsset(ModShift)) && @@ -280,7 +281,7 @@ static void open_file(void) { view_init(win_view(EDIT), file, ondiagmsg); } else { OpenCmd[1] = file; - cmdrun(OpenCmd, NULL); + exec_job(OpenCmd,0,0,0); } } free(file); @@ -289,7 +290,8 @@ static void open_file(void) { static void pick_symbol(char* symbol) { PickTagCmd[1] = "fetch"; PickTagCmd[3] = symbol; - char* pick = cmdread(PickTagCmd, NULL); + char* pick = NULL; + exec_cmd(PickTagCmd, NULL, &pick, NULL); if (pick) { Buf* buf = win_buf(EDIT); if (buf->path && 0 == strncmp(buf->path, pick, strlen(buf->path))) { @@ -300,7 +302,8 @@ static void pick_symbol(char* symbol) { view_init(win_view(EDIT), pick, ondiagmsg); } else { OpenCmd[1] = chomp(pick); - cmdrun(OpenCmd, NULL); + exec_job(OpenCmd,0,0,0); + } } } @@ -316,7 +319,8 @@ static void complete(void) { view->selection.end = buf_byrune(&(view->buffer), view->selection.end, RIGHT); PickTagCmd[1] = "print"; PickTagCmd[3] = view_getstr(view, NULL); - char* pick = cmdread(PickTagCmd, NULL); + char* pick = NULL; + exec_cmd(PickTagCmd, NULL, &pick, NULL); if (pick) view_putstr(view, chomp(pick)); free(PickTagCmd[3]); @@ -676,7 +680,7 @@ int main(int argc, char** argv) { for (argc--, argv++; argc > 1; argc--, argv++) { if (!strcmp(*argv, "--")) break; OpenCmd[1] = *argv; - cmdrun(OpenCmd, NULL); + exec_job(OpenCmd,0,0,0); } /* if we still have args left we're going to open it in this instance */ -- 2.49.0