]> git.mdlowis.com Git - projs/tide.git/commitdiff
starting combining job control and fd monitoring
authorMichael D. Lowis <mike@mdlowis.com>
Thu, 22 Mar 2018 02:12:52 +0000 (22:12 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Thu, 22 Mar 2018 02:12:52 +0000 (22:12 -0400)
Makefile
inc/edit.h
lib/event.c [deleted file]
lib/exec.c
lib/win.c
lib/x11.c
tide.c

index 00ecd475ea0bdbce7da7604a032964e21cb88dc5..231abe79104725d8283678a0afe6f7e637c677d1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -13,8 +13,7 @@ LIBEDIT_OBJS =     \
        lib/x11.o      \
        lib/win.o      \
        lib/colors.o   \
-       lib/config.o   \
-       lib/event.o
+       lib/config.o
 
 TEST_BINS =     \
        tests/tide  \
index ed5d1431380dcd98b4eefa968c8aeadc85deb345..98d41cc78a49f43ed003dd74ff0b1e284215f16b 100644 (file)
@@ -22,15 +22,6 @@ bool file_exists(char* path);
 char* strmcat(char* first, ...);
 int daemonize(void);
 
-/* File Descriptor Event Handling
- *****************************************************************************/
-enum { INPUT, OUTPUT };
-
-typedef void (*event_cbfn_t)(int fd, void* data);
-
-bool event_poll(int ms);
-void event_watchfd(int fd, int iodir, event_cbfn_t fn, void* data);
-
 /* Buffer management functions
  *****************************************************************************/
 /* undo/redo list item */
@@ -222,9 +213,21 @@ Rune view_getrune(View* view);
 
 /* Command Executions
  *****************************************************************************/
-bool exec_reap(void);
+
+typedef struct Job Job;
+
+typedef void (*jobfn_t)(Job* job);
+
+struct Job {
+    int pid, fd;
+    void* data;
+    void (*writefn)(Job* job);
+    void (*readfn)(Job* job);
+};
+
+bool exec_poll(int fd, int ms);
+int exec_reap(void);
 void exec_job(char** cmd, char* data, size_t ndata, View* dest);
-int exec_cmd(char** cmd);
 int exec_spawn(char** cmd, int* in, int* out);
 
 /* Configuration Data
diff --git a/lib/event.c b/lib/event.c
deleted file mode 100644 (file)
index 284f3ae..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#define _XOPEN_SOURCE 700
-#include <stdc.h>
-#include <utf.h>
-#include <edit.h>
-#include <unistd.h>
-#include <poll.h>
-
-struct event_data {
-    int iodir;
-    void* data;
-    event_cbfn_t fn;
-};
-
-static size_t NumDescriptors = 0;
-static struct pollfd* Descriptors = NULL;
-static struct event_data* EventData = NULL;
-
-bool event_poll(int ms) {
-    /* poll for new events */
-    long n = poll(Descriptors, NumDescriptors, ms);
-    if (n < 0) die("poll() :");
-    if (n == 0) return false;
-
-    /* Handle any events that occurred */
-    for (int i = 0; i < NumDescriptors; i++) {
-        /* skip any eventless entries */
-        if (!Descriptors[i].revents) continue;
-
-        /* if a requested event occurred, handle it */
-        if (Descriptors[i].revents & Descriptors[i].events) {
-            EventData[i].fn(Descriptors[i].fd, EventData[i].data);
-            Descriptors[i].revents = 0;
-        }
-
-        /* if the desriptor is done or errored, throw it out */
-        if (Descriptors[i].revents & (POLLNVAL|POLLERR|POLLHUP)) {
-            close(Descriptors[i].fd);
-            Descriptors[i].fd = -Descriptors[i].fd;
-            EventData[i].fn(Descriptors[i].fd, EventData[i].data);
-        }
-    }
-
-    /* remove any closed or invalid descriptors */
-    size_t nfds = 0;
-    for (int i = 0; i < NumDescriptors; i++) {
-        if (Descriptors[i].fd >= 0) {
-            Descriptors[nfds] = Descriptors[i];
-            EventData[nfds++] = EventData[i];
-        }
-    }
-    NumDescriptors = nfds;
-
-    return true;
-}
-
-void event_watchfd(int fd, int iodir, event_cbfn_t fn, void* data) {
-    int idx = NumDescriptors++;
-    Descriptors = realloc(Descriptors, NumDescriptors * sizeof(struct pollfd));
-    EventData   = realloc(EventData,   NumDescriptors * sizeof(struct event_data));
-    if (!Descriptors || !EventData)
-        die("event_Watchfd() : out of memory\n");
-    Descriptors[idx].fd = fd;
-    Descriptors[idx].revents = 0;
-    Descriptors[idx].events = (iodir == INPUT ? POLLIN : POLLOUT);
-    EventData[idx].data = data;
-    EventData[idx].fn   = fn;
-}
index 11d2bffedb1104faa9e5278a5af3c2f5e38107d9..9e7cf16b60716ffae1f56d36ee0b4cac87ec6ec7 100644 (file)
 #include <sys/wait.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <poll.h>
 
-#define PIPE_READ  0
-#define PIPE_WRITE 1
+#define MAX_JOBS 1024
 
-typedef struct {
-    int pid; /* process id of the child process */
-    int fd;  /* file descriptor for the child process's io */
-} Proc;
+static struct pollfd Jobs[MAX_JOBS];
 
-typedef struct Job Job;
-
-typedef struct {
-    Job* job;     /* pointer to the job the receiver belongs to */
-    View* view;   /* destination view */
-    size_t beg;   /* start of output */
-    size_t count; /* number of bytes written */
-} Rcvr;
-
-struct Job {
-    Job* next;           /* Pointer to previous job in the job list */
-    Job* prev;           /* Pointer to next job in the job list */
-    Proc proc;           /* Process id and descriptors */
-    size_t ndata;        /* number of bytes to write to stdout */
-    size_t nwrite;       /* number of bytes written to stdout so far */
-    char* data;          /* data to write to stdout */
-    Rcvr out_rcvr;       /* receiver for the normal output of the job */
-    View* dest;          /* destination view where output will be placed */
-};
-
-static Job* JobList = NULL;
-
-static void job_closefd(Job* job, int fd);
-static bool job_done(Job* job);
-static Job* job_finish(Job* job);
-static void send_data(int fd, void* data);
-static void recv_data(int fd, void* data);
-static int watch_or_close(bool valid, int dir, int fd, void* data);
-static void rcvr_finish(Rcvr* rcvr);
-static int execute(char** cmd, Proc* proc);
-
-bool exec_reap(void) {
-    int status;
-    Job* job = JobList;
-    while (job) {
-        if (job_done(job)) {
-            rcvr_finish(&(job->out_rcvr));
-            waitpid(job->proc.pid, &status, WNOHANG);
-            job = job_finish(job);
-        } else {
-            job = job->next;
-        }
+bool exec_poll(int fd, int ms) {
+    int njobs = 0;
+    if (fd > 0) {
+        Jobs[0].fd = fd;
+        Jobs[0].events = POLLIN;
+        Jobs[0].revents = 0;
+        njobs = 1;
     }
-    if (JobList == NULL)
-        while (waitpid(-1, &status, WNOHANG) > 0);
-    return (JobList != NULL);
-}
 
-void exec_job(char** cmd, char* data, size_t ndata, View* dest) {
-    Job* job = calloc(1, sizeof(Job));
-    job->proc.pid = execute(cmd, &(job->proc));
-    if (job->proc.pid < 0) {
-        die("job_start() :");
-    } else {
-        /* add the job to the job list */
-        job->out_rcvr.view = dest;
-        job->out_rcvr.job = job;
-        job->ndata  = ndata;
-        job->nwrite = 0;
-        job->data   = data;
-        job->next   = JobList;
-        if (JobList) JobList->prev = job;
-        JobList = job;
-        /* register watch events for file descriptors */
-        bool need_in  = (job->data != NULL),
-             need_out = (dest != NULL);
-        watch_or_close(need_in,  OUTPUT, job->proc.fd,  job);
-        watch_or_close(need_out, INPUT,  job->proc.fd, &(job->out_rcvr));
+    long ret = poll(Jobs, njobs, ms);
 
-/*
-    event_cbfn_t fn = (dir == OUTPUT ? send_data : recv_data);
-    if (valid)
-        event_watchfd(fd, dir, fn, data);
-    else
-        close(fd), fd = -fd;
-*/
+    /* reap zombie processes */
+    for (int status; waitpid(-1, &status, WNOHANG) > 0;);
 
-    }
+    return (ret > 0);
 }
 
-int exec_cmd(char** cmd) {
-    Proc proc;
-    if (execute(cmd, &proc) < 0) {
-        perror("failed to execute");
-        return -1;
-    }
-    /* wait for the process to finish */
-    int status;
-    waitpid(proc.pid, &status, 0);
-    return status;
+int exec_reap(void) {
+    return 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.fd;
-    *out = proc.fd;
-    return proc.pid;
-}
-
-static void job_closefd(Job* job, int fd) {
-    if (fd >= 0) close(fd), fd = -fd;
-    if (job->proc.fd == -fd) job->proc.fd = fd;
-}
-
-static bool job_done(Job* job) {
-    return (job->proc.fd < 0);
+    return -1;
 }
 
-static Job* job_finish(Job* job) {
-    Job* next = job->next;
-    if (job->prev) {
-        job->prev->next = next;
-        if (next)
-            next->prev = job->prev;
-    } else {
-        if (next)
-            next->prev = NULL;
-        JobList = next;
-    }
-    free(job->data);
-    free(job);
-    return next;
-}
-
-static void send_data(int fd, void* data) {
-    Job* job = data;
-    if (fd >= 0) {
-        long nwrite = write(fd, (job->data + job->nwrite), job->ndata);
-        if (nwrite >= 0) {
-            job->ndata  -= nwrite;
-            job->nwrite += nwrite;
-        }
-        if (nwrite < 0 || job->ndata <= 0)
-            shutdown(fd, SHUT_WR);
-    } else {
-        //event_unwatchfd(job, fd);
-    }
-}
-
-static void recv_data(int fd, void* data) {
-    static char buffer[4096];
-    Rcvr* rcvr = data;
-    Job* job = rcvr->job;
-    View* view = rcvr->view;
-    Sel sel = view->selection;
-
-    if (fd >= 0) {
-        long i = 0, nread = read(fd, buffer, sizeof(buffer));
-        if (nread > 0) {
-            if (!rcvr->count)
-                rcvr->beg = min(sel.beg, sel.end);
-            while (i < nread) {
-                Rune r;
-                size_t len = 0;
-                while (!utf8decode(&r, &len, buffer[i++]));
-                view_insert(rcvr->view, false, r);
-                rcvr->count++;
-            }
-        } else {
-            close(fd);
-        }
-    } else {
-        job_closefd(job, fd);
-    }
-}
-
-static int watch_or_close(bool valid, int dir, int fd, void* data) {
-    event_cbfn_t fn = (dir == OUTPUT ? send_data : recv_data);
-    if (valid)
-        event_watchfd(fd, dir, fn, data);
-    else
-        close(fd), fd = -fd;
-    return fd;
-}
+void exec_job(char** cmd, char* data, size_t ndata, View* dest) {
 
-static void rcvr_finish(Rcvr* rcvr) {
-    if (rcvr->count) {
-        View* view = rcvr->view;
-        Buf* buf = &(rcvr->view->buffer);
-        if (rcvr->view == win_view(TAGS))
-            buf_chomp(buf), rcvr->count--;
-        view->selection.beg = rcvr->beg;
-        view->selection.end = rcvr->beg + rcvr->count;
-    }
 }
 
+#if 0
 static int execute(char** cmd, Proc* proc) {
     int fds[2];
     /* create the sockets */
@@ -228,3 +65,4 @@ static int execute(char** cmd, Proc* proc) {
     }
     return proc->pid;
 }
+#endif
index 8b84d20c09a9c5f99dc41856997a08fb6aebef3d..9e767cfada5b4246b44ecfdafdf8ea71d9823df8 100644 (file)
--- a/lib/win.c
+++ b/lib/win.c
@@ -97,12 +97,10 @@ void win_save(char* path) {
 
 void win_loop(void) {
     x11_show();
-    x11_flip();
-    event_watchfd(x11_connfd(), INPUT, win_update, NULL);
     while (x11_running()) {
-        bool pending = event_poll(Timeout);
+        bool pending = exec_poll(x11_connfd(), Timeout);
         exec_reap();
-        int nevents  = x11_events_queued();
+        int nevents = x11_events_queued();
         if (update_focus() || pending || nevents) {
             x11_events_take();
             if (x11_running())
index d941d72babb0fbb4f9cd00d32e9852938adac1da..7dc504c1e4539d08f1ac1349cd864362a5648e84 100644 (file)
--- a/lib/x11.c
+++ b/lib/x11.c
@@ -211,7 +211,7 @@ void x11_finish(void) {
         char* text = Selections[CLIPBOARD].text;
         size_t len = strlen(text);
         exec_job((char*[]){ "xcpd", NULL }, text, len, NULL);
-        while (event_poll(100));
+        while (exec_poll(-1, 100));
     }
 }
 
diff --git a/tide.c b/tide.c
index 7b04b997cfc8de8daf4dea49e8b2cb5168b3589c..7af97c15fe07559abb4983b0057c0090474dc4d5 100644 (file)
--- a/tide.c
+++ b/tide.c
@@ -211,18 +211,12 @@ void onmouseright(WinRegion id, bool pressed, size_t row, size_t col) {
     if (win_btnpressed(MouseLeft)) {
         paste();
     } else {
-        char* text = view_fetch(win_view(id), row, col, risfile);
-        FetchCmd[1] = text;
-        if (exec_cmd(FetchCmd) != 0) {
-            SearchDir *= (x11_keymodsset(ModShift) ? -1 : +1);
-            free(SearchTerm);
-            SearchTerm = view_fetch(win_view(id), row, col, risfile);
-            if (view_findstr(win_view(EDIT), SearchDir, SearchTerm)) {
-                win_setregion(EDIT);
-                win_warpptr(EDIT);
-            }
-        } else {
-            free(text);
+        SearchDir *= (x11_keymodsset(ModShift) ? -1 : +1);
+        free(SearchTerm);
+        SearchTerm = view_fetch(win_view(id), row, col, risfile);
+        if (view_findstr(win_view(EDIT), SearchDir, SearchTerm)) {
+            win_setregion(EDIT);
+            win_warpptr(EDIT);
         }
     }
 }
@@ -386,7 +380,7 @@ static Tag Builtins[] = {
     { .tag = "SaveAs",    .action.arg   = saveas    },
     { .tag = "Tabs",      .action.noarg = tabs      },
     { .tag = "Undo",      .action.noarg = tag_undo  },
-     { .tag = NULL,        .action.noarg = NULL      }
+    { .tag = NULL,        .action.noarg = NULL      }
 };
 
 static KeyBinding Bindings[] = {