summaryrefslogtreecommitdiff
path: root/gawk/gawk-3.1.5-io.patch
blob: 80f2d085d176b4b30526325ea6448ab9e9ee7f51 (plain)
    1 # http://thread.gmane.org/gmane.comp.gnu.utils.bugs/13520/
    2 # http://thread.gmane.org/gmane.comp.gnu.utils.bugs/12433
    3 
    4 Mon Jul  3 00:27:59 2006  Arnold D. Robbins  <arnold @ skeeve.com>
    5 
    6 	* io.c (INTERNAL_HANDLE): New constant for use by `iop_alloc'
    7 	when allocating an internal IOBUF.
    8 	(pidopen, useropen): Use it.
    9 	(iop_alloc): Add check for it and just return iop.
   10 
   11 Sun Jun 18 22:27:25 2006  Arnold D. Robbins  <arnold @ skeeve.com>
   12 
   13 	Repair internal names like /dev/user, /dev/pid, as well as /dev/fd/N,
   14 	which have been broken for a long time but noone noticed.
   15 
   16 	* io.c (is_internal): new macro to check for internal file like `/dev/user'.
   17 	(spec_setup): Reduce to two parameters, allocate logic is always true.
   18 	Add IOP_NO_FREE to flag.
   19 	(pidopen, useropen): Return `IOBUF *' instead of int. Fix
   20 	logic to test if `iop' parameter is NULL and if so to allocate it.
   21 	(specfdopen,): Return `IOBUF *' instead of int. Fix
   22 	logic to test if `iop' parameter is NULL and if so to allocate it.
   23 	Don't set IOP_NO_FREE in flag.
   24 	(iop_open): Remove `IOBUF iob' field from `struct internal' and its use
   25 	and the use of `spec_setup' from the code here. Change the check in the
   26 	call to the open function to look for NULL.
   27 	(get_a_record): Use `is_internal' in initial check for filling the
   28 	buffer to not try to call `read' on internal files. If true, set
   29 	the IOP_AT_EOF in the flag and return EOF.
   30 
   31 Fri Aug 12 13:10:33 2005  Arnold D. Robbins  <arnold @ skeeve.com>
   32 
   33 	* io.c (iop_alloc): Only free `iop' if it was malloc'ed in
   34 	the first place.
   35 
   36 --- ../gawk-3.1.5/io.c	2005-07-26 21:07:43.000000000 +0300
   37 +++ io.c	2006-07-03 00:27:51.000000000 +0300
   38 @@ -103,6 +103,9 @@
   39 
   40  typedef enum { CLOSE_ALL, CLOSE_TO, CLOSE_FROM } two_way_close_type;
   41 
   42 +/* For internal files, /dev/pid, etc. */
   43 +#define INTERNAL_HANDLE		(-42)
   44 +
   45  /* Several macros make the code a bit clearer:                              */
   46  /*                                                                          */
   47  /*                                                                          */
   48 @@ -110,6 +113,7 @@
   49  #define at_eof(iop)     ((iop->flag & IOP_AT_EOF) != 0)
   50  #define has_no_data(iop)        (iop->dataend == NULL)
   51  #define no_data_left(iop)	(iop->off >= iop->dataend)
   52 +#define is_internal(iop) ((iop->flag & IOP_IS_INTERNAL) != 0)
   53  /* The key point to the design is to split out the code that searches through */
   54  /* a buffer looking for the record and the terminator into separate routines, */
   55  /* with a higher-level routine doing the reading of data and buffer management. */
   56 @@ -163,10 +167,10 @@
   57  static int gawk_pclose P((struct redirect *rp));
   58  static int do_pathopen P((const char *file));
   59  static int str2mode P((const char *mode));
   60 -static void spec_setup P((IOBUF *iop, int len, int allocate));
   61 -static int specfdopen P((IOBUF *iop, const char *name, const char *mode));
   62 -static int pidopen P((IOBUF *iop, const char *name, const char *mode));
   63 -static int useropen P((IOBUF *iop, const char *name, const char *mode));
   64 +static void spec_setup P((IOBUF *iop, int len));
   65 +static IOBUF *specfdopen P((IOBUF *iop, const char *name, const char *mode));
   66 +static IOBUF *pidopen P((IOBUF *iop, const char *name, const char *mode));
   67 +static IOBUF *useropen P((IOBUF *iop, const char *name, const char *mode));
   68  static int two_way_open P((const char *str, struct redirect *rp));
   69  static int pty_vs_pipe P((const char *command));
   70 
   71 @@ -1422,30 +1426,24 @@
   72  /* spec_setup --- setup an IOBUF for a special internal file */
   73 
   74  static void
   75 -spec_setup(IOBUF *iop, int len, int allocate)
   76 +spec_setup(IOBUF *iop, int len)
   77  {
   78  	char *cp;
   79 
   80 -	if (allocate) {
   81 -		emalloc(cp, char *, len+2, "spec_setup");
   82 -		iop->buf = cp;
   83 -	} else {
   84 -		len = strlen(iop->buf);
   85 -		iop->buf[len++] = '\n';	/* get_a_record clobbered it */
   86 -		iop->buf[len] = '\0';	/* just in case */
   87 -	}
   88 +	emalloc(cp, char *, len+2, "spec_setup");
   89 +	iop->buf = cp;
   90  	iop->off = iop->buf;
   91  	iop->count = 0;
   92  	iop->size = len;
   93  	iop->end = iop->buf + len;
   94  	iop->dataend = iop->end;
   95  	iop->fd = -1;
   96 -	iop->flag = IOP_IS_INTERNAL | IOP_AT_START;
   97 +	iop->flag = IOP_IS_INTERNAL | IOP_AT_START | IOP_NO_FREE;
   98  }
   99 
  100  /* specfdopen --- open an fd special file */
  101 
  102 -static int
  103 +static IOBUF *
  104  specfdopen(IOBUF *iop, const char *name, const char *mode)
  105  {
  106  	int fd;
  107 @@ -1453,17 +1451,14 @@
  108 
  109  	fd = devopen(name, mode);
  110  	if (fd == INVALID_HANDLE)
  111 -		return INVALID_HANDLE;
  112 -	tp = iop_alloc(fd, name, NULL);
  113 +		return NULL;
  114 +	tp = iop_alloc(fd, name, iop);
  115  	if (tp == NULL) {
  116  		/* don't leak fd's */
  117  		close(fd);
  118 -		return INVALID_HANDLE;
  119 +		return NULL;
  120  	}
  121 -	*iop = *tp;
  122 -	iop->flag |= IOP_NO_FREE;
  123 -	free(tp);
  124 -	return 0;
  125 +	return tp;
  126  }
  127 
  128  #ifdef GETPGRP_VOID
  129 @@ -1474,7 +1469,7 @@
  130 
  131  /* pidopen --- "open" /dev/pid, /dev/ppid, and /dev/pgrpid */
  132 
  133 -static int
  134 +static IOBUF *
  135  pidopen(IOBUF *iop, const char *name, const char *mode ATTRIBUTE_UNUSED)
  136  {
  137  	char tbuf[BUFSIZ];
  138 @@ -1483,6 +1478,12 @@
  139 
  140  	warning(_("use `PROCINFO[\"%s\"]' instead of `%s'"), cp, name);
  141 
  142 +	if (iop == NULL) {
  143 +		iop = iop_alloc(INTERNAL_HANDLE, name, iop);
  144 +		if (iop == NULL)
  145 +			return NULL;
  146 +	}
  147 +
  148  	if (name[6] == 'g')
  149  		sprintf(tbuf, "%d\n", (int) getpgrp(getpgrp_arg()));
  150  	else if (name[6] == 'i')
  151 @@ -1490,9 +1491,9 @@
  152  	else
  153  		sprintf(tbuf, "%d\n", (int) getppid());
  154  	i = strlen(tbuf);
  155 -	spec_setup(iop, i, TRUE);
  156 +	spec_setup(iop, i);
  157  	strcpy(iop->buf, tbuf);
  158 -	return 0;
  159 +	return iop;
  160  }
  161 
  162  /* useropen --- "open" /dev/user */
  163 @@ -1507,7 +1508,7 @@
  164   * supplementary group set.
  165   */
  166 
  167 -static int
  168 +static IOBUF *
  169  useropen(IOBUF *iop, const char *name ATTRIBUTE_UNUSED, const char *mode ATTRIBUTE_UNUSED)
  170  {
  171  	char tbuf[BUFSIZ], *cp;
  172 @@ -1515,6 +1516,12 @@
  173 
  174  	warning(_("use `PROCINFO[...]' instead of `/dev/user'"));
  175 
  176 +	if (iop == NULL) {
  177 +		iop = iop_alloc(INTERNAL_HANDLE, name, iop);
  178 +		if (iop == NULL)
  179 +			return NULL;
  180 +	}
  181 +
  182  	sprintf(tbuf, "%d %d %d %d", (int) getuid(), (int) geteuid(), (int) getgid(), (int) getegid());
  183 
  184  	cp = tbuf + strlen(tbuf);
  185 @@ -1529,9 +1536,9 @@
  186  	*cp++ = '\0';
  187 
  188  	i = strlen(tbuf);
  189 -	spec_setup(iop, i, TRUE);
  190 +	spec_setup(iop, i);
  191  	strcpy(iop->buf, tbuf);
  192 -	return 0;
  193 +	return iop;
  194  }
  195 
  196  /* iop_open --- handle special and regular files for input */
  197 @@ -1544,8 +1551,7 @@
  198  	static struct internal {
  199  		const char *name;
  200  		int compare;
  201 -		int (*fp) P((IOBUF *, const char *, const char *));
  202 -		IOBUF iob;
  203 +		IOBUF *(*fp) P((IOBUF *, const char *, const char *));
  204  	} table[] = {
  205  		{ "/dev/fd/",		8,	specfdopen },
  206  		{ "/dev/stdin",		10,	specfdopen },
  207 @@ -1570,12 +1576,7 @@
  208 
  209  		for (i = 0; i < devcount; i++) {
  210  			if (STREQN(name, table[i].name, table[i].compare)) {
  211 -				iop = & table[i].iob;
  212 -
  213 -				if (iop->buf != NULL) {
  214 -					spec_setup(iop, 0, FALSE);
  215 -					return iop;
  216 -				} else if ((*table[i].fp)(iop, name, mode) == 0)
  217 +				if ((iop = (*table[i].fp)(iop, name, mode)) != NULL)
  218  					return iop;
  219  				else {
  220  					warning(_("could not open `%s', mode `%s'"),
  221 @@ -2480,9 +2481,12 @@
  222  {
  223  	struct stat sbuf;
  224  	struct open_hook *oh;
  225 +	int iop_malloced = FALSE;
  226 
  227 -	if (iop == NULL)
  228 +	if (iop == NULL) {
  229  		emalloc(iop, IOBUF *, sizeof(IOBUF), "iop_alloc");
  230 +		iop_malloced = TRUE;
  231 +	}
  232  	memset(iop, '\0', sizeof(IOBUF));
  233  	iop->flag = 0;
  234  	iop->fd = fd;
  235 @@ -2494,8 +2498,12 @@
  236  			break;
  237  	}
  238 
  239 +	if (iop->fd == INTERNAL_HANDLE)
  240 +		return iop;
  241 +
  242  	if (iop->fd == INVALID_HANDLE) {
  243 -		free(iop);
  244 +		if (iop_malloced)
  245 +			free(iop);
  246  		return NULL;
  247  	}
  248  	if (isatty(iop->fd))
  249 @@ -2503,7 +2511,7 @@
  250  	iop->readsize = iop->size = optimal_bufsize(iop->fd, & sbuf);
  251  	iop->sbuf = sbuf;
  252  	if (do_lint && S_ISREG(sbuf.st_mode) && sbuf.st_size == 0)
  253 -			lintwarn(_("data file `%s' is empty"), name);
  254 +		lintwarn(_("data file `%s' is empty"), name);
  255  	errno = 0;
  256  	iop->count = iop->scanoff = 0;
  257  	emalloc(iop->buf, char *, iop->size += 2, "iop_alloc");
  258 @@ -2906,6 +2914,10 @@
  259 
  260          /* <fill initial buffer>=                                                   */
  261          if (has_no_data(iop) || no_data_left(iop)) {
  262 +		if (is_internal(iop)) {
  263 +			iop->flag |= IOP_AT_EOF;
  264 +			return EOF;
  265 +		}
  266                  iop->count = read(iop->fd, iop->buf, iop->readsize);
  267                  if (iop->count == 0) {
  268                          iop->flag |= IOP_AT_EOF;

Generated by cgit