]> git.mdlowis.com Git - projs/tide.git/commitdiff
Added stderr capture for executed commands
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 30 Nov 2016 01:30:50 +0000 (20:30 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 30 Nov 2016 01:30:50 +0000 (20:30 -0500)
TODO.md
inc/edit.h
libedit/exec.c
xedit.c

diff --git a/TODO.md b/TODO.md
index e06cdec2223e7ff349cb495938c8ce52cd0f2670..bba87b2b045aac2ab97f114084c2460a1372322f 100644 (file)
--- a/TODO.md
+++ b/TODO.md
@@ -1,9 +1,8 @@
 # Implementation Tweaks and Bug Fixes
 
 * Should not be able to undo initial tag line text insertion
-* capture stderr of executed commands and place it in tags view
 * Disallow scrolling past end of buffer
-* track down double click bug  for selecting whole line
+* track down double click bug for selecting whole line
 * Add tag for ctags lookup
 * Implement minimal regex search (per Kernighan article)
 * Implement fuzzy file/buffer/tag picker
index 30f765c283fb244d7a82eeb8e969744853bdc36f..4c94f258f7f490b911432a3c3f6f1137e2f145c3 100644 (file)
@@ -182,18 +182,10 @@ void view_scrollpage(View* view, int move);
 
 /* Command Executions
  *****************************************************************************/
-typedef struct {
-    int pid; /* process id of the child process */
-    int in;  /* file descriptor for the child process's standard input */
-    int out; /* file descriptor for the child process's standard output */
-    int err; /* file descriptor for the child process's standard error */
-} Process;
-
-void detach(Process* proc);
-void terminate(Process* proc, int sig);
-char* cmdread(char** cmd);
-void cmdwrite(char** cmd, char* text);
-char* cmdwriteread(char** cmd, char* text);
+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);
 
 /* Color Scheme Handling
  *****************************************************************************/
@@ -249,7 +241,6 @@ typedef struct {
     } action;
 } Tag;
 
-
 /* Configuration
  *****************************************************************************/
 enum {
index aad984268c68cb9b2f17f9eef1a878119c3f9c11..403b7ddf86a76689484ee1cdda83015d25d7bf04 100644 (file)
@@ -8,6 +8,13 @@
 #define PIPE_READ 0
 #define PIPE_WRITE 1
 
+typedef struct {
+    int pid; /* process id of the child process */
+    int in;  /* file descriptor for the child process's standard input */
+    int out; /* file descriptor for the child process's standard output */
+    int err; /* file descriptor for the child process's standard error */
+} Process;
+
 static int execute(char** cmd, Process* proc) {
     int inpipe[2], outpipe[2], errpipe[2];
     /* create the pipes */
@@ -44,30 +51,37 @@ static int execute(char** cmd, Process* proc) {
     return proc->pid;
 }
 
-void detach(Process* proc) {
+static void detach(Process* proc) {
     close(proc->in);
     close(proc->out);
     close(proc->err);
 }
 
-void terminate(Process* proc, int sig) {
-    detach(proc);
-    kill(proc->pid, sig);
+int cmdrun(char** cmd, char** err) {
+    Process proc;
+    if (execute(cmd, &proc) < 0) {
+        perror("failed to execute");
+        return -1;
+    }
+    if (err) *err = fdgets(proc.err);
+    detach(&proc);
+    return proc.pid;
 }
 
-char* cmdread(char** cmd) {
+char* cmdread(char** cmd, char** err) {
     Process proc;
     if (execute(cmd, &proc) < 0) {
         perror("failed to execute");
         return NULL;
     }
     char* str = fdgets(proc.out);
+    if (err) *err = fdgets(proc.err);
     detach(&proc);
     waitpid(proc.pid, NULL, 0);
     return str;
 }
 
-void cmdwrite(char** cmd, char* text) {
+void cmdwrite(char** cmd, char* text, char** err) {
     Process proc;
     if (execute(cmd, &proc) < 0) {
         perror("failed to execute");
@@ -77,11 +91,12 @@ void cmdwrite(char** cmd, char* text) {
         perror("failed to write");
         return;
     }
+    if (err) *err = fdgets(proc.err);
     detach(&proc);
     waitpid(proc.pid, NULL, 0);
 }
 
-char* cmdwriteread(char** cmd, char* text) {
+char* cmdwriteread(char** cmd, char* text, char** err) {
     Process proc;
     if (execute(cmd, &proc) < 0) {
         perror("failed to execute");
@@ -93,6 +108,7 @@ char* cmdwriteread(char** cmd, char* text) {
     }
     close(proc.in);
     char* str = fdgets(proc.out);
+    if (err) *err = fdgets(proc.err);
     detach(&proc);
     waitpid(proc.pid, NULL, 0);
     return str;
diff --git a/xedit.c b/xedit.c
index 5cd3c38a2dedb0f762dfc7cb8221a93b49f03be1..6820019862afb67e54562a2051bf76bde3cfaaf1 100644 (file)
--- a/xedit.c
+++ b/xedit.c
@@ -442,7 +442,7 @@ static void redo(void) {
 static void cut(void) {
     char* str = view_getstr(currview(), NULL);
     if (str && *str) {
-        cmdwrite(CopyCmd, str);
+        cmdwrite(CopyCmd, str, NULL);
         delete();
     }
     free(str);
@@ -451,12 +451,12 @@ static void cut(void) {
 static void copy(void) {
     char* str = view_getstr(currview(), NULL);
     if (str && *str)
-        cmdwrite(CopyCmd, str);
+        cmdwrite(CopyCmd, str, NULL);
     free(str);
 }
 
 static void paste(void) {
-    char* str = cmdread(PasteCmd);
+    char* str = cmdread(PasteCmd, NULL);
     if (str && *str)
         view_putstr(currview(), str);
     free(str);
@@ -479,14 +479,14 @@ static void find(char* arg) {
 }
 
 static void open_file(void) {
-    char* file = cmdread(PickFileCmd);
+    char* file = cmdread(PickFileCmd, NULL);
     if (file) {
         file[strlen(file)-1] = '\0';
         if (!getbuf(EDIT)->path && !getbuf(EDIT)->modified) {
             buf_load(getbuf(EDIT), file);
         } else {
             OpenCmd[1] = file;
-            free(cmdread(OpenCmd));
+            free(cmdread(OpenCmd, NULL));
         }
     }
     free(file);
@@ -528,25 +528,30 @@ static void tag_exec(Tag* tag, char* arg) {
     free(arg);
 }
 
+static char* chomp(char* in) {
+    return (in[strlen(in)-1] = '\0', in);
+}
 static void cmd_exec(char* cmd) {
     char op = '\0';
     if (*cmd == '!' || *cmd == '<' || *cmd == '|' || *cmd == '>')
         op = *cmd, cmd++;
     ShellCmd[2] = cmd;
     /* execute the command */
-    char *input = NULL, *output = NULL;
+    char *input = NULL, *output = NULL, *error = NULL;
     enum RegionId dest = EDIT;
     input = view_getstr(getview(EDIT), NULL);
     if (op == '!') {
         printf("null: '%s'\n", cmd);
     } else if (op == '>') {
-        cmdwrite(ShellCmd, input);
+        cmdwrite(ShellCmd, input, &error);
     } else if (op == '|') {
-        output = cmdwriteread(ShellCmd, input);
+        output = cmdwriteread(ShellCmd, input, &error);
     } else {
         if (op != '<') dest = Focused;
-        output = cmdread(ShellCmd);
+        output = cmdread(ShellCmd, &error);
     }
+    if (error)
+        view_append(getview(TAGS), chomp(error));
     if (output) {
         view_putstr(getview(dest), output);
         view_selprev(getview(dest));
@@ -554,6 +559,7 @@ static void cmd_exec(char* cmd) {
     /* cleanup */
     free(input);
     free(output);
+    free(error);
 }
 
 static void exec(char* cmd) {