typedef void (*jobfn_t)(Job* job);
struct Job {
+ Job *next;
int pid, fd;
- void* data;
- void (*writefn)(Job* job);
- void (*readfn)(Job* job);
+ 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_spawn(char** cmd, int* in, int* out);
+bool job_poll(int fd, int ms);
+void job_create(char** cmd, jobfn_t readfn, jobfn_t writefn, void* data);
+void job_start(char** cmd, char* data, size_t ndata, View* dest);
/* Configuration Data
*****************************************************************************/
static int read_byte(void);
static int read_num(void);
+static void writefn(Job* job) {
+}
+
+static void readfn(Job* job) {
+}
+
void colors_init(char* path) {
if (Syntax)
- exec_spawn((char*[]){ "tide-hl.rb", path, NULL }, &ChildIn, &ChildOut);
+ job_create((char*[]){ "tide-hl.rb", path, NULL }, readfn, writefn, 0);
}
SyntaxSpan* colors_scan(SyntaxSpan* spans, Buf* buf, size_t beg, size_t end) {
+#if 0
SyntaxSpan* firstspan = spans;
SyntaxSpan* currspan = spans;
/* if the engine died, clear all highlights and quit */
DataBeg = DataEnd = Buffer;
}
return firstspan;
+#else
+ return spans;
+#endif
}
SyntaxSpan* colors_rewind(SyntaxSpan* spans, size_t first) {
+#if 0
SyntaxSpan *curr = spans, *next = (spans ? spans->next : NULL);
while (curr && curr->end > first)
next = curr, curr = curr->prev;
free(dead);
}
return curr;
+#else
+ return spans;
+#endif
}
+#if 0
static SyntaxSpan* mkspan(size_t beg, size_t end, size_t clr, SyntaxSpan* span) {
SyntaxSpan* newspan = malloc(sizeof(SyntaxSpan));
newspan->beg = beg;
num = (num * 10) + (c - '0');
return num;
}
+#endif
#include <sys/un.h>
#include <poll.h>
-#define MAX_JOBS 1024
+static void job_process(int fd, int events);
+static int job_execute(char** cmd, int *fd, int *pid);
+static void job_finish(Job* job);
-static struct pollfd Jobs[MAX_JOBS];
+#define MAX_JOBS 256
-bool exec_poll(int fd, int ms) {
+static struct pollfd JobFds[MAX_JOBS];
+static Job* JobList = NULL;
+
+bool job_poll(int fd, int ms) {
int njobs = 0;
+ /* add the X11 connection if we have one */
if (fd > 0) {
- Jobs[0].fd = fd;
- Jobs[0].events = POLLIN;
- Jobs[0].revents = 0;
+ JobFds[0].fd = fd;
+ JobFds[0].events = POLLIN;
+ JobFds[0].revents = 0;
njobs = 1;
}
-
- long ret = poll(Jobs, njobs, ms);
-
+ /* Add jobs from the job list */
+ for (Job *job = JobList; job && njobs < MAX_JOBS; job = job->next) {
+ JobFds[njobs].fd = job->fd;
+ JobFds[njobs].events = 0;
+ JobFds[njobs].revents = 0;
+ if (job->readfn) JobFds[njobs].events = POLLIN;
+ if (job->writefn) JobFds[njobs].events = POLLOUT;
+ if (JobFds[njobs].events) njobs++;
+ }
+ /* Poll until a job is ready, call the functions based on events */
+ long ret = poll(JobFds, njobs, ms);
+ for (int i = 1; i < njobs; i++)
+ job_process(JobFds[i].fd, JobFds[i].revents);
/* reap zombie processes */
for (int status; waitpid(-1, &status, WNOHANG) > 0;);
-
+ // TODO: cleanup old jobs here...
return (ret > 0);
}
-int exec_reap(void) {
- return 0;
+void job_create(char** cmd, jobfn_t readfn, jobfn_t writefn, void* data) {
+ int fd = -1, pid = -1;
+ if (job_execute(cmd, &fd, &pid) > 0) {
+ Job *job = calloc(1, sizeof(job));
+ job->fd = fd;
+ job->pid = pid;
+ job->readfn = readfn;
+ job->writefn = writefn;
+ job->data = data;
+ job->next = JobList;
+ JobList = job;
+ }
}
-int exec_spawn(char** cmd, int* in, int* out) {
- return -1;
+void job_start(char** cmd, char* data, size_t ndata, View* dest) {
+
}
-void exec_job(char** cmd, char* data, size_t ndata, View* dest) {
+static void job_process(int fd, int events) {
+ Job* job = NULL; // Get job by fd
+ if (job->readfn && (events & POLLIN))
+ job->readfn(job);
+ if (job->writefn && (events & POLLOUT))
+ job->writefn(job);
+ if (!job->readfn && !job->writefn)
+ job_finish(job);
+}
+static void job_finish(Job* job) {
+ close(job->fd);
+ // delete job
+ // free(job);
}
-#if 0
-static int execute(char** cmd, Proc* proc) {
+static int job_execute(char** cmd, int *fd, int *pid) {
int fds[2];
/* create the sockets */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0)
return -1;
/* create the process */
- if ((proc->pid = fork()) < 0) {
- close(fds[0]), close(fds[1]), proc->fd = -1;
- } else if (0 == proc->pid) {
+ if ((*pid = fork()) < 0) {
+ close(fds[0]), close(fds[1]), *fd = -1;
+ } else if (0 == *pid) {
/* redirect child process's io to the pipes */
if ((dup2(fds[1], 0) < 0) || (dup2(fds[1], 1) < 0) || (dup2(fds[1], 2) < 0)) {
perror("failed to pipe");
close(fds[0]);
exit(execvp(cmd[0], cmd));
} else {
- close(fds[1]), proc->fd = fds[0];
+ close(fds[1]), *fd = fds[0];
}
- return proc->pid;
+ return *pid;
}
-#endif
void win_loop(void) {
x11_show();
while (x11_running()) {
- bool pending = exec_poll(x11_connfd(), Timeout);
- exec_reap();
+ bool pending = job_poll(x11_connfd(), Timeout);
int nevents = x11_events_queued();
if (update_focus() || pending || nevents) {
x11_events_take();
if (Selections[CLIPBOARD].text) {
char* text = Selections[CLIPBOARD].text;
size_t len = strlen(text);
- exec_job((char*[]){ "xcpd", NULL }, text, len, NULL);
- while (exec_poll(-1, 100));
+ job_start((char*[]){ "xcpd", NULL }, text, len, NULL);
+ while (job_poll(-1, 100));
}
}
/* execute the job */
if (op == '!')
- free(input), exec_job(execcmd, NULL, 0, NULL);
+ free(input), job_start(execcmd, NULL, 0, NULL);
else if (op == '>')
- exec_job(execcmd, input, len, tags);
+ job_start(execcmd, input, len, tags);
else if (op == '|' || op == ':')
- exec_job(execcmd, input, len, edit);
+ job_start(execcmd, input, len, edit);
else
- exec_job(execcmd, input, len, (op != '<' ? curr : edit));
+ job_start(execcmd, input, len, (op != '<' ? curr : edit));
}
static void cmd_execwitharg(char* cmd, char* arg) {