From 9f14b1b80e6b09e6b2dc067704fff2034dc0ad23 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 8 Jan 2004 21:21:42 +0000 Subject: Assorted work git-svn-id: file:///home/lennart/svn/public/ivam2/trunk@18 dbf6933d-3bce-0310-9bcc-ed052ba35b35 --- client/ivamApi.py | 3 ++ client/ivamPipeConnector.py | 22 ++++++++ client/ivamVoiceBox.py | 1 + conf/msntab | 2 +- doc/TODO | 6 ++- src/buffio.c | 7 +++ src/dtmffifo.c | 2 +- src/exec.c | 123 ++++++++++++++++++++++++++------------------ src/exec.h | 2 +- src/modem.c | 2 +- src/msntab.c | 8 ++- src/msntab.h | 1 + 12 files changed, 122 insertions(+), 57 deletions(-) diff --git a/client/ivamApi.py b/client/ivamApi.py index 1413116..8cab6f9 100644 --- a/client/ivamApi.py +++ b/client/ivamApi.py @@ -44,3 +44,6 @@ class Connector: def hangup(self, t): pass + + def flushOutput(self): + pass diff --git a/client/ivamPipeConnector.py b/client/ivamPipeConnector.py index 70fd93d..af302b8 100644 --- a/client/ivamPipeConnector.py +++ b/client/ivamPipeConnector.py @@ -34,6 +34,14 @@ class PipeConnector(ivamApi.Connector): self.ringNumber = os.getenv("RINGMSN") self.processor = processor + try: + s = os.fstat(128) + self.pipeHack = True + ivamCore.log("Found and enabled pipe hack.") + except OSError: + self.pipeHack = False + ivamCore.log("Pipe hack not detected.") + def openDtmf(self): try: @@ -223,3 +231,17 @@ class PipeConnector(ivamApi.Connector): self.dtmfFifo = None else: self.processor.onDtmfEvent(self, d) + + def flushOutput(self): + + if not self.pipeHack: + return + + try: + b = os.read(128, 4096) + if ivamCore.DEBUG: + ivamCore.log("Pipe hack succeeded") + except OSError: + + if ivamCore.DEBUG: + ivamCore.log("Pipe hack failed") diff --git a/client/ivamVoiceBox.py b/client/ivamVoiceBox.py index 131e5c5..252ce98 100644 --- a/client/ivamVoiceBox.py +++ b/client/ivamVoiceBox.py @@ -199,6 +199,7 @@ class VoiceBox(ivamApi.Processor): c.playClip(self.getClip("beep")) else: + c.flushOutput() c.stopPlayback2() def onTimeout(self, c): diff --git a/conf/msntab b/conf/msntab index b4823e9..02391ae 100644 --- a/conf/msntab +++ b/conf/msntab @@ -1,6 +1,6 @@ # local MSN remote MSN options action -41264179 * rings=0 ivam-autobox +41264179 * rings=0,pipehack ivam-autobox #41264179 41264177 rings=0 ivam-dialup --pin=4711 ppp0 #* 41264179 rings=0 @hangup diff --git a/doc/TODO b/doc/TODO index 8686af0..874d9fe 100644 --- a/doc/TODO +++ b/doc/TODO @@ -1,8 +1,10 @@ -* python part * implement shbuf support * uid switching support -* clean hangup on shutdown +* make it a daemon +* autoconf +* documentation +* python part (DONE) * implement msntab.c (DONE) * dtmf fifo (DONE) * env var passing (DONE) diff --git a/src/buffio.c b/src/buffio.c index 95db681..95e3dec 100644 --- a/src/buffio.c +++ b/src/buffio.c @@ -260,6 +260,10 @@ static void do_read(struct buffio *b) { //daemon_log(LOG_INFO, "%p: Read %u (%u) bytes.", b, s, m); if (s < 0) { + + if (errno == EAGAIN) + return; + daemon_log(LOG_ERR, "Failed to read from file descriptor: %s", strerror(errno)); buffio_close_input_fd(b); buffio_sched_cb(b, BUFFIO_SCHED_CB_ERROR); @@ -309,6 +313,9 @@ static void do_write(struct buffio *b) { //daemon_log(LOG_INFO, "%p: Wrote %u (%u) bytes.", b, s, m); if (s < 0) { + if (errno == EAGAIN) + return; + buffio_close_output_fd(b); if (errno == EPIPE) { diff --git a/src/dtmffifo.c b/src/dtmffifo.c index 54a1f62..f959158 100644 --- a/src/dtmffifo.c +++ b/src/dtmffifo.c @@ -75,7 +75,7 @@ void dtmf_fifo_free(struct dtmf_fifo *d) { void dtmf_fifo_pass(struct dtmf_fifo *d, char c) { assert(d && d->fd >= 0); - daemon_log(LOG_INFO, "Recieved DTMF character '%c'", c); + //daemon_log(LOG_INFO, "Recieved DTMF character '%c'", c); if (write(d->fd, &c, 1) != 1) daemon_log(LOG_ERR, "Failed to write to DTMF FIFO: %s", strerror(errno)); diff --git a/src/exec.c b/src/exec.c index fabe757..5691c75 100644 --- a/src/exec.c +++ b/src/exec.c @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -187,42 +188,38 @@ static void *oop_read_cb(oop_source *source, int fd, oop_event event, void *user } static void pipe_close(int fds[]) { - close(fds[0]); - close(fds[1]); + if (fds[0] >= 0) + close(fds[0]); + if (fds[1] >= 0) + close(fds[1]); } -pid_t child_process_create(const char *file, char *const argv[], int *ifd, int *ofd, process_exit_cb_t cb, void *user) { +pid_t child_process_create(const char *file, char *const argv[], int *ifd, int *ofd, process_exit_cb_t cb, void *user, int pipe_hack) { pid_t pid; - int stdin_fds[2]; - int stdout_fds[2]; - int stderr_fds[2]; + int stdin_fds[2] = { -1, -1 }; + int stdout_fds[2] = { -1, -1 }; + int stderr_fds[2] = { -1, -1 }; daemon_log(LOG_INFO, "Executing child process '%s'.", file); - if (pipe(stdin_fds) < 0) { + if (ofd && pipe(stdin_fds) < 0) { daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno)); - return -1; + goto fail; } - if (pipe(stdout_fds) < 0) { + if (ifd && pipe(stdout_fds) < 0) { daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno)); - pipe_close(stdin_fds); - return -1; + goto fail; } if (pipe(stderr_fds) < 0) { daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno)); - pipe_close(stdin_fds); - pipe_close(stdout_fds); - return -1; + goto fail; } if ((pid = fork()) < 0) { daemon_log(LOG_ERR, "fork() failed: %s", strerror(errno)); - pipe_close(stdin_fds); - pipe_close(stdout_fds); - pipe_close(stderr_fds); - return -1; + goto fail; } if (pid) { @@ -240,17 +237,15 @@ pid_t child_process_create(const char *file, char *const argv[], int *ifd, int * p->stderr_pipe = stderr_fds[0]; close(stderr_fds[1]); - if (ifd) + if (ifd) { *ifd = stdout_fds[0]; - else - close(stdout_fds[0]); - close(stdout_fds[1]); + close(stdout_fds[1]); + } - if (ofd) + if (ofd) { *ofd = stdin_fds[1]; - else - close(stdin_fds[1]); - close(stdin_fds[0]); + close(stdin_fds[0]); + } assert(event_source && event_source->on_fd); event_source->on_fd(event_source, p->stderr_pipe, OOP_READ, oop_read_cb, p); @@ -261,48 +256,78 @@ pid_t child_process_create(const char *file, char *const argv[], int *ifd, int * } else { /* child */ - int fd; + int fd, efd; close(stderr_fds[0]); - close(stdout_fds[0]); - close(stdin_fds[1]); + if (ifd) { + if (pipe_hack) { + /* This might get a problem in the future, when more tahn 127 fds have been allocated */ + struct stat s; + assert(fstat(128, &s) < 0 && errno == EBADF); + + + if (dup2(stdout_fds[0], 128) < 0) { + daemon_log(LOG_ERR, "dup2() failed: %s", strerror(errno)); + exit(1); + } + } + close(stdout_fds[0]); + } + if (ofd) + close(stdin_fds[1]); - for (fd = 0; fd <= 2; fd++) { - if (fd != stderr_fds[1] && fd != stdout_fds[1] && fd != stdin_fds[0]) + for (fd = 0; fd <= 127; fd++) { + if (fd != stderr_fds[1] && (!ifd || fd != stdout_fds[1]) && (!ofd || fd != stdin_fds[0])) close(fd); } - if ((stdin_fds[0] != 0 && dup2(stdin_fds[0], 0) < 0) || - (stdout_fds[1] != 1 && dup2(stdout_fds[1], 1) < 0) || - (stderr_fds[1] != 2 && dup2(stderr_fds[1], 2) < 0)) { - daemon_log(LOG_ERR, "dup2() failed: %s", strerror(errno)); - exit(1); + if (ofd) { + if (stdin_fds[0] != 0) { + if (dup2(stdin_fds[0], 0) < 0) { + daemon_log(LOG_ERR, "dup2() failed: %s", strerror(errno)); + exit(1); + } + close(stdin_fds[0]); + } + } else { + close(0); + if (open("/dev/null", O_RDONLY) != 0) { + daemon_log(LOG_ERR, "open(\"/dev/null\") != 0: %s", strerror(errno)); + exit(1); + } } - if (stdin_fds[0] > 2) close(stdin_fds[0]); - if (stdout_fds[1] > 2) close(stdout_fds[1]); - if (stderr_fds[1] > 2) close(stderr_fds[1]); - - if (!ifd) { - close(1); - if (open("/dev/null", O_WRONLY) != 1) { - daemon_log(LOG_ERR, "open(\"/dev/null\") failed: %s", strerror(errno)); + efd = ifd ? stdout_fds[1] : stderr_fds[1]; + if (efd != 1) { + if (dup2(efd, 1) < 0) { + daemon_log(LOG_ERR, "dup2() failed: %s", strerror(errno)); exit(1); } - } - if (!ofd) { - close(0); - if (open("/dev/null", O_RDONLY) != 0) { - daemon_log(LOG_ERR, "open(\"/dev/null\") failed: %s", strerror(errno)); + if (ifd) + close(stdout_fds[1]); + } + + if (stderr_fds[1] != 2){ + if (dup2(stderr_fds[1], 2) < 0) { + daemon_log(LOG_ERR, "dup2() failed: %s", strerror(errno)); exit(1); } + + close(stderr_fds[1]); } execvp(file, argv); daemon_log(LOG_ERR, "exec('%s', ...) failed: %s", file, strerror(errno)); exit(1); } + +fail: + pipe_close(stdin_fds); + pipe_close(stdout_fds); + pipe_close(stderr_fds); + + return (pid_t) -1; } diff --git a/src/exec.h b/src/exec.h index 32285d6..2c929da 100644 --- a/src/exec.h +++ b/src/exec.h @@ -5,7 +5,7 @@ typedef void (*process_exit_cb_t) (pid_t pid, int status, void *user); -pid_t child_process_create(const char *file, char *const argv[], int *ifd, int *ofd, process_exit_cb_t cb, void *user); +pid_t child_process_create(const char *file, char *const argv[], int *ifd, int *ofd, process_exit_cb_t cb, void *user, int pipehack); int child_process_kill(pid_t pid); int child_process_init(void); void child_process_done(void); diff --git a/src/modem.c b/src/modem.c index e3d3cec..ecc0019 100644 --- a/src/modem.c +++ b/src/modem.c @@ -455,7 +455,7 @@ static int modem_start_child(struct modem *m) { unsetenv("LISTENMSN"); assert(m->tabentry->args && m->tabentry->args[0]); - if ((m->child_pid = child_process_create(m->tabentry->args[0], m->tabentry->args, &ifd, &ofd, child_exit_cb, m)) < 0) { + if ((m->child_pid = child_process_create(m->tabentry->args[0], m->tabentry->args, &ifd, &ofd, child_exit_cb, m, m->tabentry->pipehack)) < 0) { dtmf_fifo_free(m->dtmf_fifo); return -1; } diff --git a/src/msntab.c b/src/msntab.c index 09709cc..cf84ec8 100644 --- a/src/msntab.c +++ b/src/msntab.c @@ -118,6 +118,9 @@ static int parse_options(const char *s, struct tabentry *t) { else if (!strcmp(o, "shbuf")) { t->shbuf = 1; continue; + } else if (!strcmp(o, "pipehack")) { + t->pipehack = 1; + continue; } else if (!strncmp(o, "rings=", 6)) { t->rings = atoi(o+6); continue; @@ -294,12 +297,13 @@ static void dump_entry(struct tabentry *t) { } else strncpy(s, "NOARGS", sizeof(s)); - daemon_log(LOG_INFO, "[%s:%02u] %-12s -> %-12s; shbuf=%-3s; rings=%u; action=%s; args=<%s>", + daemon_log(LOG_INFO, "[%s:%02u] %-12s -> %-12s; shbuf=%c; pipehack=%c; rings=%u; action=%s; args=<%s>", t->filename, t->line, t->local, t->remote, - t->shbuf ? "yes" : "no", + t->shbuf ? 'y' : 'n', + t->pipehack ? 'y' : 'n', t->rings, t->action == CALL_ACTION_ACCEPT ? "ACCEPT" : (t->action == CALL_ACTION_HANGUP ? "HANGUP" : "IGNORE"), s); diff --git a/src/msntab.h b/src/msntab.h index 9c473e3..dc1bf1c 100644 --- a/src/msntab.h +++ b/src/msntab.h @@ -16,6 +16,7 @@ struct tabentry { int shbuf; unsigned rings; + int pipehack; char *filename; /* filename of the msntab where this entry originates from */ unsigned line; -- cgit