gawk-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gawk-diffs] [SCM] gawk branch, read_timeout, created. d84926f0d651d5f55


From: John Haque
Subject: [gawk-diffs] [SCM] gawk branch, read_timeout, created. d84926f0d651d5f55b1be3b760b572a50197593f
Date: Sun, 01 Jan 2012 16:41:49 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".

The branch, read_timeout has been created
        at  d84926f0d651d5f55b1be3b760b572a50197593f (commit)

- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=d84926f0d651d5f55b1be3b760b572a50197593f

commit d84926f0d651d5f55b1be3b760b572a50197593f
Author: john haque <address@hidden>
Date:   Sun Jan 1 10:33:09 2012 -0600

    Added timeout for reading from input.

diff --git a/ChangeLog b/ChangeLog
index 292a03c..8fe80ac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2012-01-01         John Haque      <address@hidden>
+
+       * awk.h (struct iobuf): New entry read_func.
+       * io.c (Read_can_timeout, Read_timeout, Read_default_timeout):
+       New variables.
+       (init_io): New routine to initialize the variables.
+       (in_PROCINFO): New "clever" routine to parse elements with indices
+       seperated by a SUPSEP.
+       (get_read_timeout): New routine to read timeout value for an IOBUF.
+       (read_with_timeout): New routine to read from a fd with a timeout.
+       (pty_vs_pipe): Use in_PROCINFO().
+       (get_a_record): Set the timeout value and the read routine as necessary.
+       * main.c (main): Call init_io().
+
 2011-12-31         Arnold D. Robbins     <address@hidden>
 
        * profile_p.c: Remove the file.
diff --git a/awk.h b/awk.h
index c06e293..7259390 100644
--- a/awk.h
+++ b/awk.h
@@ -850,6 +850,11 @@ typedef struct iobuf {
        ssize_t count;          /* amount read last time */
        size_t scanoff;         /* where we were in the buffer when we had
                                   to regrow/refill */
+       /*
+        * No argument prototype on read_func. See get_src_buf()
+        * in awkgram.y.
+        */
+       ssize_t (*read_func)();
 
        void *opaque;           /* private data for open hooks */
        int (*get_record)(char **out, struct iobuf *, int *errcode);
@@ -862,7 +867,7 @@ typedef struct iobuf {
 #              define  IOP_NOFREE_OBJ  2
 #              define  IOP_AT_EOF      4
 #              define  IOP_CLOSED      8
-#              define  IOP_AT_START    16                      
+#              define  IOP_AT_START    16
 } IOBUF;
 
 typedef void (*Func_ptr)(void);
@@ -1434,6 +1439,7 @@ extern int ispath(const char *file);
 extern int isdirpunct(int c);
 
 /* io.c */
+extern void init_io(void);
 extern void register_open_hook(void *(*open_func)(IOBUF *));
 extern void set_FNR(void);
 extern void set_NR(void);
diff --git a/io.c b/io.c
index b6076eb..ca59b5c 100644
--- a/io.c
+++ b/io.c
@@ -206,10 +206,18 @@ static int get_a_record(char **out, IOBUF *iop, int 
*errcode);
 static void free_rp(struct redirect *rp);
 static int inetfile(const char *str, int *length, int *family);
 
+static NODE *in_PROCINFO(const char *pidx1, const char *pidx2, NODE 
**full_idx);
+static long get_read_timeout(IOBUF *iop);
+static ssize_t read_with_timeout(int fd, char *buf, size_t size);
+
 #if defined(HAVE_POPEN_H)
 #include "popen.h"
 #endif
 
+static int Read_can_timeout = FALSE;
+static long Read_timeout;
+static long Read_default_timeout;
+
 static struct redirect *red_head = NULL;
 static NODE *RS = NULL;
 static Regexp *RS_re_yes_case;
@@ -225,6 +233,31 @@ extern NODE *ARGIND_node;
 extern NODE *ERRNO_node;
 extern NODE **fields_arr;
 
+
+void
+init_io()
+{
+       long tmout;
+
+       /* N.B.: all these hacks are to minimize the affect
+        * on programs that do not care about timeout.
+        */
+
+       /* Parse the env. variable only once */
+       tmout = getenv_long("GAWK_READ_TIMEOUT");
+       if (tmout > 0) {
+               Read_default_timeout = tmout;
+               Read_can_timeout = TRUE;
+       }
+
+       /* PROCINFO entries for timeout are dynamic;
+        * We can't be any more specific than this.
+        */
+       if (PROCINFO_node != NULL)      
+               Read_can_timeout = TRUE;
+}
+
+
 #if defined(__DJGPP__) || defined(__MINGW32__) || defined(__EMX__) || 
defined(__CYGWIN__)
 /* binmode --- convert BINMODE to string for fopen */
 
@@ -376,6 +409,7 @@ nextfile(IOBUF **curfile, int skipping)
                fname = "-";
                iop = *curfile = iop_alloc(fileno(stdin), fname, &mybuf, FALSE);
                iop->flag |= IOP_NOFREE_OBJ;
+
                if (iop->fd == INVALID_HANDLE) {
                        errcode = errno;
                        errno = 0;
@@ -2554,22 +2588,21 @@ iop_alloc(int fd, const char *name, IOBUF *iop, int 
do_openhooks)
                iop_malloced = TRUE;
        }
        memset(iop, '\0', sizeof(IOBUF));
-       iop->flag = 0;
        iop->fd = fd;
        iop->name = name;
+       iop->read_func = ( ssize_t(*)() ) read;
 
-       if (do_openhooks)
+       if (do_openhooks) {
                find_open_hook(iop);
-       else if (iop->fd == INVALID_HANDLE)
+               /* tried to find open hook and could not */
+               if (iop->fd == INVALID_HANDLE) {
+                       if (iop_malloced)
+                               efree(iop);
+                       return NULL;
+               }
+       } else if (iop->fd == INVALID_HANDLE)
                return iop;
 
-       /* test reached if tried to find open hook and could not */
-       if (iop->fd == INVALID_HANDLE) {
-               if (iop_malloced)
-                       efree(iop);
-               return NULL;
-       }
-
        if (os_isatty(iop->fd))
                iop->flag |= IOP_IS_TTY;
        iop->readsize = iop->size = optimal_bufsize(iop->fd, & sbuf);
@@ -2983,12 +3016,15 @@ get_a_record(char **out,        /* pointer to pointer 
to data */
        if (at_eof(iop) && no_data_left(iop))
                return EOF;
 
+       if (Read_can_timeout)
+               Read_timeout = get_read_timeout(iop);
+
        if (iop->get_record != NULL)
                return (*iop->get_record)(out, iop, errcode);
 
         /* <fill initial buffer>= */
        if (has_no_data(iop) || no_data_left(iop)) {
-               iop->count = read(iop->fd, iop->buf, iop->readsize);
+               iop->count = iop->read_func(iop->fd, iop->buf, iop->readsize);
                if (iop->count == 0) {
                        iop->flag |= IOP_AT_EOF;
                        return EOF;
@@ -3054,7 +3090,7 @@ get_a_record(char **out,        /* pointer to pointer to 
data */
                        amt_to_read = min(amt_to_read, SSIZE_MAX);
 #endif
 
-                       iop->count = read(iop->fd, iop->dataend, amt_to_read);
+                       iop->count = iop->read_func(iop->fd, iop->dataend, 
amt_to_read);
                        if (iop->count == -1) {
                                *errcode = errno;
                                iop->flag |= IOP_AT_EOF;
@@ -3192,6 +3228,7 @@ set_FS:
                set_FS();
 }
 
+
 /* pty_vs_pipe --- return true if should use pty instead of pipes for `|&' */
 
 /*
@@ -3202,26 +3239,11 @@ static int
 pty_vs_pipe(const char *command)
 {
 #ifdef HAVE_TERMIOS_H
-       char *full_index;
-       size_t full_len;
-       NODE *val, *sub;
+       NODE *val;
 
        if (PROCINFO_node == NULL)
                return FALSE;
-
-       full_len = strlen(command)
-                       + SUBSEP_node->var_value->stlen
-                       + 3     /* strlen("pty") */
-                       + 1;    /* string terminator */
-       emalloc(full_index, char *, full_len, "pty_vs_pipe");
-       sprintf(full_index, "%s%.*spty", command,
-               (int) SUBSEP_node->var_value->stlen, 
SUBSEP_node->var_value->stptr);
-
-       sub = make_string(full_index, strlen(full_index));
-       val = in_array(PROCINFO_node, sub);
-       unref(sub);
-       efree(full_index);
-
+       val = in_PROCINFO(command, "pty", NULL);
        if (val) {
                if (val->flags & MAYBE_NUM)
                        (void) force_number(val);
@@ -3292,3 +3314,109 @@ inetfile(const char *str, int *length, int *family)
 
        return ret;
 }
+
+/* in_PROCINFO --- return value for a PROCINFO element with
+ *     SUBSEP seperated indices.
+ */ 
+
+static NODE *
+in_PROCINFO(const char *pidx1, const char *pidx2, NODE **full_idx)
+{
+       char *str;
+       size_t str_len;
+       NODE *r, *sub = NULL; 
+       NODE *subsep = SUBSEP_node->var_value;
+
+       /* full_idx is in+out parameter */
+
+       if (full_idx)
+               sub = *full_idx;
+
+       str_len = strlen(pidx1) + subsep->stlen + strlen(pidx2);
+       if (sub == NULL) {
+               emalloc(str, char *, str_len + 1, "in_PROCINFO");
+               sub = make_str_node(str, str_len, ALREADY_MALLOCED);
+               if (full_idx)
+                       *full_idx = sub;
+       } else if (str_len != sub->stlen) {
+               /* *full_idx != NULL */
+
+               assert(sub->valref == 1);
+               erealloc(sub->stptr, char *, str_len + 1, "in_PROCINFO");
+               sub->stlen = str_len;
+       }
+
+       sprintf(sub->stptr, "%s%.*s%s", pidx1, subsep->stlen, subsep->stptr, 
pidx2);
+       r = in_array(PROCINFO_node, sub);
+       if (! full_idx)
+               unref(sub);
+       return r;
+}
+
+
+/* get_read_timeout --- get timeout in milliseconds for reading */
+
+static long
+get_read_timeout(IOBUF *iop)
+{
+       long tmout = 0;
+       char *cp;
+
+       if (PROCINFO_node != NULL) {
+               const char *name = iop->name;
+               NODE *val = NULL;
+               static NODE *full_idx = NULL;
+               static const char *last_name = NULL;
+
+               /* Do not re-construct the full index when last redirection 
string is
+                * the same as the current; "efficiency_hack++".
+                */
+               if (full_idx == NULL || strcmp(name, last_name) != 0) {
+                       val = in_PROCINFO(name, "READ_TIMEOUT", & full_idx);
+                       last_name = name;
+               } else  /* use cached full index */
+                       val = in_array(PROCINFO_node, full_idx);
+               if (val != NULL)
+                       tmout = (long) force_number(val);
+       } else
+               tmout = Read_default_timeout;   /* initialized from env. 
variable in init_io() */
+
+       iop->read_func = tmout > 0 ? read_with_timeout : ( ssize_t(*)() ) read;
+       return tmout;
+}
+
+/* read_with_timeout --- read with a timeout, return failure
+       if no data is available within the timeout period.
+*/
+
+static ssize_t
+read_with_timeout(int fd, char *buf, size_t size)
+{
+       fd_set readfds;
+       struct timeval tv;
+
+       tv.tv_sec = Read_timeout / 1000;
+       tv.tv_usec = 1000 * (Read_timeout - 1000 * tv.tv_sec);
+
+       FD_ZERO(& readfds);
+       FD_SET(fd, & readfds);
+
+       errno = 0;
+       if (select(fd + 1, & readfds, NULL, NULL, & tv) < 0)
+               return -1;
+
+       if (FD_ISSET(fd, & readfds))
+               return read(fd, buf, size);
+       /* else
+               timed out */
+
+       /* Set a meaningful errno */
+#ifdef ETIMEDOUT
+       errno = ETIMEDOUT;
+#else
+       errno = EAGAIN;
+#endif
+       return -1;
+}
+
+
diff --git a/main.c b/main.c
index f8b5d81..8899db5 100644
--- a/main.c
+++ b/main.c
@@ -672,8 +672,10 @@ out:
        if (use_lc_numeric)
                setlocale(LC_NUMERIC, "");
 #endif
-
+       
+       init_io();
        output_fp = stdout;
+
        if (do_debug)
                debug_prog(code_block);
        else

-----------------------------------------------------------------------


hooks/post-receive
-- 
gawk



reply via email to

[Prev in Thread] Current Thread [Next in Thread]