diff options
Diffstat (limited to 'extension')
-rw-r--r-- | extension/.gitignore | 3 | ||||
-rw-r--r-- | extension/ChangeLog | 50 | ||||
-rw-r--r-- | extension/Makefile.am | 57 | ||||
-rw-r--r-- | extension/arrayparm.c | 2 | ||||
-rw-r--r-- | extension/filefuncs.c | 189 | ||||
-rw-r--r-- | extension/fork.c | 32 | ||||
-rw-r--r-- | extension/readfile.c | 10 | ||||
-rw-r--r-- | extension/rwarray.c | 4 |
8 files changed, 244 insertions, 103 deletions
diff --git a/extension/.gitignore b/extension/.gitignore new file mode 100644 index 00000000..ee95901f --- /dev/null +++ b/extension/.gitignore @@ -0,0 +1,3 @@ +# ignore files created by libtool +*.l[oa] +.libs diff --git a/extension/ChangeLog b/extension/ChangeLog index 0b3053ed..7c6976de 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,53 @@ +2012-04-11 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * filefuncs.c (array_set): New function to set an array element. + (do_set): Use new array_set function to reduce code duplication and + to make sure the memory management is handled properly. + +2012-04-07 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * filefuncs.c: Remove unnecessary #include <sys/sysmacros.h>. + (read_symlink): New function to read symbolic links more robustly. + (do_stat): Use read_symlink instead of readlink. + * fork.c (do_wait): new function. + (dlload): Call make_builtin to add "wait" function. + +2012-04-02 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * fork.c (do_fork): Test whether PROCINFO_node exists before updating + the pid values. And do so properly using make_number. + * readfile.c (do_readfile): Function should be static. + +2012-04-01 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * filefuncs.c (do_chdir, do_stat): Replace update_ERRNO() with + update_ERRNO_int(errno). + * fork.c (do_fork, do_waitpid): Ditto. + * readfile.c (do_readfile): Ditto. + * rwarray.c (do_writea, do_reada): Ditto. + +2012-03-25 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * Makefile.am: Major cleanup. Use libtool options -module and + -avoid-version to create the modules properly without my local hack + to override the default behavior. + +2012-03-25 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * .gitignore: New file to ignore files created by libtool (including + binaries and associated metadata). + +2012-03-21 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * Makefile.am (INCLUDES): Remove -I$(top_srcdir)/intl. + +2012-03-20 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * Makefile.am: New file to build and install shared libraries. + * arrayparm.c (do_mkarray): Get it to compile by removing 2nd arg + to assoc_clear. + * filefuncs.c (do_stat): Ditto. + 2011-08-31 John Haque <j.eh@mchsi.com> * arrayparm.c, filefuncs.c, fork.c, ordchr.c, readfile.c, diff --git a/extension/Makefile.am b/extension/Makefile.am new file mode 100644 index 00000000..a2f47229 --- /dev/null +++ b/extension/Makefile.am @@ -0,0 +1,57 @@ +# +# extension/Makefile.am --- automake input file for gawk +# +# Copyright (C) 1995-2006 the Free Software Foundation, Inc. +# +# This file is part of GAWK, the GNU implementation of the +# AWK Programming Language. +# +# GAWK is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# GAWK is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# + +## Process this file with automake to produce Makefile.in. + +INCLUDES = -I.. -I$(top_srcdir) + +# The arrayparm, zaxxon (dl), and testarg libraries do not do anything useful, +# so do not build or install them. + +# Note: rwarray does not currently compile. + +pkgextension_LTLIBRARIES = \ + filefuncs.la \ + fork.la \ + ordchr.la \ + readfile.la + +MY_MODULE_FLAGS = -module -avoid-version + +filefuncs_la_SOURCES = filefuncs.c +filefuncs_la_LDFLAGS = $(MY_MODULE_FLAGS) +fork_la_SOURCES = fork.c +fork_la_LDFLAGS = $(MY_MODULE_FLAGS) +ordchr_la_SOURCES = ordchr.c +ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS) +readfile_la_SOURCES = readfile.c +readfile_la_LDFLAGS = $(MY_MODULE_FLAGS) +#rwarray_la_SOURCES = rwarray.c +#rwarray_la_LDFLAGS = $(MY_MODULE_FLAGS) + +EXTRA_DIST = \ + ChangeLog \ + ChangeLog.0 \ + *.awk \ + doit \ + steps diff --git a/extension/arrayparm.c b/extension/arrayparm.c index b0aee33d..1e28811e 100644 --- a/extension/arrayparm.c +++ b/extension/arrayparm.c @@ -60,7 +60,7 @@ do_mkarray(int nargs) printf("sub->type = %s\n", nodetype2str(sub->type)); printf("val->type = %s\n", nodetype2str(val->type)); - assoc_clear(var, NULL); + assoc_clear(var); elemval = assoc_lookup(var, sub); *elemval = dupnode(val); diff --git a/extension/filefuncs.c b/extension/filefuncs.c index 1a0a86ef..8e5e8daa 100644 --- a/extension/filefuncs.c +++ b/extension/filefuncs.c @@ -29,8 +29,6 @@ #include "awk.h" -#include <sys/sysmacros.h> - int plugin_is_GPL_compatible; /* do_chdir --- provide dynamically loaded chdir() builtin for gawk */ @@ -48,7 +46,7 @@ do_chdir(int nargs) (void) force_string(newdir); ret = chdir(newdir->stptr); if (ret < 0) - update_ERRNO(); + update_ERRNO_int(errno); return make_number((AWKNUM) ret); } @@ -157,15 +155,83 @@ format_mode(unsigned long fmode) return outbuf; } +/* read_symlink -- read a symbolic link into an allocated buffer. + This is based on xreadlink; the basic problem is that lstat cannot be relied + upon to return the proper size for a symbolic link. This happens, + for example, on linux in the /proc filesystem, where the symbolic link + sizes are often 0. */ + +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif +#ifndef SSIZE_MAX +# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) +#endif + +#define MAXSIZE (SIZE_MAX < SSIZE_MAX ? SIZE_MAX : SSIZE_MAX) + +static char * +read_symlink(const char *fname, size_t bufsize, ssize_t *linksize) +{ + if (bufsize) + bufsize += 2; + else + bufsize = BUFSIZ*2; + /* Make sure that bufsize >= 2 and within range */ + if ((bufsize > MAXSIZE) || (bufsize < 2)) + bufsize = MAXSIZE; + while (1) { + char *buf; + + emalloc(buf, char *, bufsize, "read_symlink"); + if ((*linksize = readlink(fname, buf, bufsize)) < 0) { + /* On AIX 5L v5.3 and HP-UX 11i v2 04/09, readlink + returns -1 with errno == ERANGE if the buffer is + too small. */ + if (errno != ERANGE) { + free(buf); + return NULL; + } + } + /* N.B. This test is safe because bufsize must be >= 2 */ + else if ((size_t)*linksize <= bufsize-2) { + buf[*linksize] = '\0'; + return buf; + } + free(buf); + if (bufsize <= MAXSIZE/2) + bufsize *= 2; + else if (bufsize < MAXSIZE) + bufsize = MAXSIZE; + else + return NULL; + } + return NULL; +} + +/* array_set --- set an array element */ + +static void +array_set(NODE *array, const char *sub, NODE *value) +{ + NODE *tmp; + NODE **aptr; + + tmp = make_string(sub, strlen(sub)); + aptr = assoc_lookup(array, tmp); + unref(tmp); + unref(*aptr); + *aptr = value; +} + /* do_stat --- provide a stat() function for gawk */ static NODE * do_stat(int nargs) { - NODE *file, *array, *tmp; + NODE *file, *array; struct stat sbuf; int ret; - NODE **aptr; char *pmode; /* printable mode */ char *type = "unknown"; @@ -177,110 +243,55 @@ do_stat(int nargs) array = get_array_argument(1, FALSE); /* empty out the array */ - assoc_clear(array, NULL); + assoc_clear(array); /* lstat the file, if error, set ERRNO and return */ (void) force_string(file); ret = lstat(file->stptr, & sbuf); if (ret < 0) { - update_ERRNO(); + update_ERRNO_int(errno); return make_number((AWKNUM) ret); } /* fill in the array */ - aptr = assoc_lookup(array, tmp = make_string("name", 4)); - *aptr = dupnode(file); - unref(tmp); - - aptr = assoc_lookup(array, tmp = make_string("dev", 3)); - *aptr = make_number((AWKNUM) sbuf.st_dev); - unref(tmp); - - aptr = assoc_lookup(array, tmp = make_string("ino", 3)); - *aptr = make_number((AWKNUM) sbuf.st_ino); - unref(tmp); - - aptr = assoc_lookup(array, tmp = make_string("mode", 4)); - *aptr = make_number((AWKNUM) sbuf.st_mode); - unref(tmp); - - aptr = assoc_lookup(array, tmp = make_string("nlink", 5)); - *aptr = make_number((AWKNUM) sbuf.st_nlink); - unref(tmp); - - aptr = assoc_lookup(array, tmp = make_string("uid", 3)); - *aptr = make_number((AWKNUM) sbuf.st_uid); - unref(tmp); - - aptr = assoc_lookup(array, tmp = make_string("gid", 3)); - *aptr = make_number((AWKNUM) sbuf.st_gid); - unref(tmp); - - aptr = assoc_lookup(array, tmp = make_string("size", 4)); - *aptr = make_number((AWKNUM) sbuf.st_size); - unref(tmp); - - aptr = assoc_lookup(array, tmp = make_string("blocks", 6)); - *aptr = make_number((AWKNUM) sbuf.st_blocks); - unref(tmp); - - aptr = assoc_lookup(array, tmp = make_string("atime", 5)); - *aptr = make_number((AWKNUM) sbuf.st_atime); - unref(tmp); - - aptr = assoc_lookup(array, tmp = make_string("mtime", 5)); - *aptr = make_number((AWKNUM) sbuf.st_mtime); - unref(tmp); - - aptr = assoc_lookup(array, tmp = make_string("ctime", 5)); - *aptr = make_number((AWKNUM) sbuf.st_ctime); - unref(tmp); + array_set(array, "name", dupnode(file)); + array_set(array, "dev", make_number((AWKNUM) sbuf.st_dev)); + array_set(array, "ino", make_number((AWKNUM) sbuf.st_ino)); + array_set(array, "mode", make_number((AWKNUM) sbuf.st_mode)); + array_set(array, "nlink", make_number((AWKNUM) sbuf.st_nlink)); + array_set(array, "uid", make_number((AWKNUM) sbuf.st_uid)); + array_set(array, "gid", make_number((AWKNUM) sbuf.st_gid)); + array_set(array, "size", make_number((AWKNUM) sbuf.st_size)); + array_set(array, "blocks", make_number((AWKNUM) sbuf.st_blocks)); + array_set(array, "atime", make_number((AWKNUM) sbuf.st_atime)); + array_set(array, "mtime", make_number((AWKNUM) sbuf.st_mtime)); + array_set(array, "ctime", make_number((AWKNUM) sbuf.st_ctime)); /* for block and character devices, add rdev, major and minor numbers */ if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode)) { - aptr = assoc_lookup(array, tmp = make_string("rdev", 4)); - *aptr = make_number((AWKNUM) sbuf.st_rdev); - unref(tmp); - - aptr = assoc_lookup(array, tmp = make_string("major", 5)); - *aptr = make_number((AWKNUM) major(sbuf.st_rdev)); - unref(tmp); - - aptr = assoc_lookup(array, tmp = make_string("minor", 5)); - *aptr = make_number((AWKNUM) minor(sbuf.st_rdev)); - unref(tmp); + array_set(array, "rdev", make_number((AWKNUM) sbuf.st_rdev)); + array_set(array, "major", make_number((AWKNUM) major(sbuf.st_rdev))); + array_set(array, "minor", make_number((AWKNUM) minor(sbuf.st_rdev))); } #ifdef HAVE_ST_BLKSIZE - aptr = assoc_lookup(array, tmp = make_string("blksize", 7)); - *aptr = make_number((AWKNUM) sbuf.st_blksize); - unref(tmp); + array_set(array, "blksize", make_number((AWKNUM) sbuf.st_blksize)); #endif /* HAVE_ST_BLKSIZE */ - aptr = assoc_lookup(array, tmp = make_string("pmode", 5)); pmode = format_mode(sbuf.st_mode); - *aptr = make_string(pmode, strlen(pmode)); - unref(tmp); + array_set(array, "pmode", make_string(pmode, strlen(pmode))); /* for symbolic links, add a linkval field */ if (S_ISLNK(sbuf.st_mode)) { char *buf; - int linksize; - - emalloc(buf, char *, sbuf.st_size + 2, "do_stat"); - if (((linksize = readlink(file->stptr, buf, - sbuf.st_size + 2)) >= 0) && - (linksize <= sbuf.st_size)) { - /* - * set the linkval field only if we are able to - * retrieve the entire link value successfully. - */ - buf[linksize] = '\0'; - - aptr = assoc_lookup(array, tmp = make_string("linkval", 7)); - *aptr = make_str_node(buf, linksize, ALREADY_MALLOCED); - unref(tmp); - } + ssize_t linksize; + + if ((buf = read_symlink(file->stptr, sbuf.st_size, + &linksize)) != NULL) + array_set(array, "linkval", make_str_node(buf, linksize, ALREADY_MALLOCED)); + else + warning(_("unable to read symbolic link `%s'"), + file->stptr); } /* add a type field */ @@ -319,9 +330,7 @@ do_stat(int nargs) #endif } - aptr = assoc_lookup(array, tmp = make_string("type", 4)); - *aptr = make_string(type, strlen(type)); - unref(tmp); + array_set(array, "type", make_string(type, strlen(type))); return make_number((AWKNUM) ret); } diff --git a/extension/fork.c b/extension/fork.c index 88353879..5a6e96d5 100644 --- a/extension/fork.c +++ b/extension/fork.c @@ -44,16 +44,18 @@ do_fork(int nargs) ret = fork(); if (ret < 0) - update_ERRNO(); - else if (ret == 0) { + update_ERRNO_int(errno); + else if (ret == 0 && PROCINFO_node != NULL) { /* update PROCINFO in the child */ aptr = assoc_lookup(PROCINFO_node, tmp = make_string("pid", 3)); - (*aptr)->numbr = (AWKNUM) getpid(); + unref(*aptr); + *aptr = make_number((AWKNUM) getpid()); unref(tmp); aptr = assoc_lookup(PROCINFO_node, tmp = make_string("ppid", 4)); - (*aptr)->numbr = (AWKNUM) getppid(); + unref(*aptr); + *aptr = make_number((AWKNUM) getppid()); unref(tmp); } @@ -83,7 +85,7 @@ do_waitpid(int nargs) options = WNOHANG|WUNTRACED; ret = waitpid(pid, NULL, options); if (ret < 0) - update_ERRNO(); + update_ERRNO_int(errno); } else if (do_lint) lintwarn("wait: called with no arguments"); @@ -91,6 +93,25 @@ do_waitpid(int nargs) return make_number((AWKNUM) ret); } + +/* do_wait --- provide dynamically loaded wait() builtin for gawk */ + +static NODE * +do_wait(int nargs) +{ + int ret; + + if (do_lint && nargs > 0) + lintwarn("wait: called with too many arguments"); + + ret = wait(NULL); + if (ret < 0) + update_ERRNO_int(errno); + + /* Set the return value */ + return make_number((AWKNUM) ret); +} + /* dlload --- load new builtins in this library */ NODE * @@ -100,5 +121,6 @@ void *dl; { make_builtin("fork", do_fork, 0); make_builtin("waitpid", do_waitpid, 1); + make_builtin("wait", do_wait, 0); return make_number((AWKNUM) 0); } diff --git a/extension/readfile.c b/extension/readfile.c index c9b1efc3..57cf6cdd 100644 --- a/extension/readfile.c +++ b/extension/readfile.c @@ -41,7 +41,7 @@ int plugin_is_GPL_compatible; /* do_readfile --- read a file into memory */ -NODE * +static NODE * do_readfile(int nargs) { NODE *filename; @@ -59,18 +59,18 @@ do_readfile(int nargs) ret = stat(filename->stptr, & sbuf); if (ret < 0) { - update_ERRNO(); + update_ERRNO_int(errno); goto done; } else if ((sbuf.st_mode & S_IFMT) != S_IFREG) { errno = EINVAL; ret = -1; - update_ERRNO(); + update_ERRNO_int(errno); goto done; } if ((fd = open(filename->stptr, O_RDONLY|O_BINARY)) < 0) { ret = -1; - update_ERRNO(); + update_ERRNO_int(errno); goto done; } @@ -80,7 +80,7 @@ do_readfile(int nargs) if ((ret = read(fd, text, sbuf.st_size)) != sbuf.st_size) { (void) close(fd); ret = -1; - update_ERRNO(); + update_ERRNO_int(errno); goto done; } diff --git a/extension/rwarray.c b/extension/rwarray.c index 8175c7c0..f4f8cd58 100644 --- a/extension/rwarray.c +++ b/extension/rwarray.c @@ -115,7 +115,7 @@ do_writea(int nargs) done1: ret = -1; - update_ERRNO(); + update_ERRNO_int(errno); unlink(file->stptr); done0: @@ -297,7 +297,7 @@ do_reada(int nargs) done1: ret = -1; - update_ERRNO(); + update_ERRNO_int(errno); done0: close(fd); |