[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gawk-diffs] [SCM] gawk branch, read_timeout, created. d84926f0d651d5f55b1be3b760b572a50197593f,
John Haque <=