diff options
Diffstat (limited to 'extension')
-rw-r--r-- | extension/ChangeLog | 12 | ||||
-rw-r--r-- | extension/Makefile.am | 2 | ||||
-rw-r--r-- | extension/Makefile.in | 9 | ||||
-rwxr-xr-x | extension/configure | 3 | ||||
-rw-r--r-- | extension/configure.ac | 4 | ||||
-rw-r--r-- | extension/filefuncs.c | 221 | ||||
-rw-r--r-- | extension/filefuncs2.c | 365 | ||||
-rw-r--r-- | extension/fork.c | 114 | ||||
-rw-r--r-- | extension/ordchr.c | 70 | ||||
-rw-r--r-- | extension/ordchr2.c | 107 | ||||
-rw-r--r-- | extension/readfile.c | 54 | ||||
-rw-r--r-- | extension/readfile2.c | 116 |
12 files changed, 276 insertions, 801 deletions
diff --git a/extension/ChangeLog b/extension/ChangeLog index 692647a6..11c9f4d3 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,15 @@ +2012-05-24 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * Makefile.am (AM_CPPFLAGS): Use $(srcdir) to work properly when + built outside the source directory. + * configure.ac (INSTALL): Set location manually since autoconf was + not specifying the proper path for install-sh. + * filefuncs2.c, ordchr2.c, readfile2.c: Deleted. + * filefuncs.c: Install filefuncs2.c and patch for recent API changes. + * ordchr.c: Install ordchr2.c and patch for recent API changes. + * readfile.c: Install readfile2.c and patch for recent API changes. + * fork.c: Port to new API. + 2012-05-21 Andrew J. Schorr <aschorr@telemetry-investments.com> * configure.ac: New file to run configure with libtool support diff --git a/extension/Makefile.am b/extension/Makefile.am index b8b43598..81612236 100644 --- a/extension/Makefile.am +++ b/extension/Makefile.am @@ -23,7 +23,7 @@ ## Process this file with automake to produce Makefile.in. -AM_CPPFLAGS = -I.. +AM_CPPFLAGS = -I$(srcdir)/.. # This variable insures that aclocal runs # correctly after changing configure.ac diff --git a/extension/Makefile.in b/extension/Makefile.in index e8f10d09..c90a0b4c 100644 --- a/extension/Makefile.in +++ b/extension/Makefile.in @@ -84,9 +84,10 @@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/ltmain.sh \ $(top_srcdir)/build-aux/missing $(top_srcdir)/configure \ - AUTHORS COPYING ChangeLog INSTALL NEWS build-aux/ar-lib \ - build-aux/config.guess build-aux/config.sub build-aux/depcomp \ - build-aux/install-sh build-aux/ltmain.sh build-aux/missing + AUTHORS COPYING ChangeLog INSTALL NEWS build-aux/ChangeLog \ + build-aux/ar-lib build-aux/config.guess build-aux/config.sub \ + build-aux/depcomp build-aux/install-sh build-aux/ltmain.sh \ + build-aux/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ @@ -310,7 +311,7 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -AM_CPPFLAGS = -I.. +AM_CPPFLAGS = -I$(srcdir)/.. # This variable insures that aclocal runs # correctly after changing configure.ac diff --git a/extension/configure b/extension/configure index bb78dde0..7333bdad 100755 --- a/extension/configure +++ b/extension/configure @@ -2138,6 +2138,9 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. +INSTALL="$ac_aux_dir/install-sh -c" +export INSTALL + am__api_version='1.12' # Find a good install program. We prefer a C program (faster), diff --git a/extension/configure.ac b/extension/configure.ac index 9d58dc2a..461826e6 100644 --- a/extension/configure.ac +++ b/extension/configure.ac @@ -28,11 +28,15 @@ AC_INIT([GNU Awk Bundled Extensions], 4.0.70, bug-gawk@gnu.org, gawk-extensions) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([build-aux]) +INSTALL="$ac_aux_dir/install-sh -c" +export INSTALL + AM_INIT_AUTOMAKE([-Wall -Werror]) AM_PROG_AR AC_DISABLE_STATIC AC_PROG_LIBTOOL +dnl AC_PROG_INSTALL AC_SUBST([pkgextensiondir], ['${libdir}/gawk']) diff --git a/extension/filefuncs.c b/extension/filefuncs.c index 01f3fce2..74a086a9 100644 --- a/extension/filefuncs.c +++ b/extension/filefuncs.c @@ -7,7 +7,8 @@ */ /* - * Copyright (C) 2001, 2004, 2005, 2010, 2011 the Free Software Foundation, Inc. + * Copyright (C) 2001, 2004, 2005, 2010, 2011, 2012 + * the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Programming Language. @@ -27,28 +28,40 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "awk.h" +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "gawkapi.h" + +static const gawk_api_t *api; /* for convenience macros to work */ +static awk_ext_id_t *ext_id; int plugin_is_GPL_compatible; /* do_chdir --- provide dynamically loaded chdir() builtin for gawk */ -static NODE * -do_chdir(int nargs) +static awk_value_t * +do_chdir(int nargs, awk_value_t *result) { - NODE *newdir; + awk_value_t newdir; int ret = -1; if (do_lint && nargs != 1) - lintwarn("chdir: called with incorrect number of arguments"); + lintwarn(ext_id, "chdir: called with incorrect number of arguments"); - newdir = get_scalar_argument(0, false); - (void) force_string(newdir); - ret = chdir(newdir->stptr); - if (ret < 0) - update_ERRNO_int(errno); + if (get_curfunc_param(0, AWK_STRING, &newdir) != NULL) { + ret = chdir(newdir.str_value.str); + if (ret < 0) + update_ERRNO_int(errno); + } - return make_number((AWKNUM) ret); + return make_number(ret, result); } /* format_mode --- turn a stat mode field into something readable */ @@ -57,7 +70,15 @@ static char * format_mode(unsigned long fmode) { static char outbuf[12]; - int i; + static struct mode_map { + int mask; + int rep; + } map[] = { + { S_IRUSR, 'r' }, { S_IWUSR, 'w' }, { S_IXUSR, 'x' }, + { S_IRGRP, 'r' }, { S_IWGRP, 'w' }, { S_IXGRP, 'x' }, + { S_IROTH, 'r' }, { S_IWOTH, 'w' }, { S_IXOTH, 'x' }, + }; + int i, j, k; strcpy(outbuf, "----------"); /* first, get the file type */ @@ -97,39 +118,16 @@ format_mode(unsigned long fmode) #endif } - i++; - if ((fmode & S_IRUSR) != 0) - outbuf[i] = 'r'; - i++; - if ((fmode & S_IWUSR) != 0) - outbuf[i] = 'w'; - i++; - if ((fmode & S_IXUSR) != 0) - outbuf[i] = 'x'; - i++; - - if ((fmode & S_IRGRP) != 0) - outbuf[i] = 'r'; - i++; - if ((fmode & S_IWGRP) != 0) - outbuf[i] = 'w'; - i++; - if ((fmode & S_IXGRP) != 0) - outbuf[i] = 'x'; - i++; + for (j = 0, k = sizeof(map)/sizeof(map[0]); j < k; j++) { + i++; + if ((fmode & map[j].mask) != 0) + outbuf[i] = map[j].rep; + } - if ((fmode & S_IROTH) != 0) - outbuf[i] = 'r'; - i++; - if ((fmode & S_IWOTH) != 0) - outbuf[i] = 'w'; i++; - if ((fmode & S_IXOTH) != 0) - outbuf[i] = 'x'; - i++; - outbuf[i] = '\0'; + /* setuid bit */ if ((fmode & S_ISUID) != 0) { if (outbuf[3] == 'x') outbuf[3] = 's'; @@ -145,6 +143,7 @@ format_mode(unsigned long fmode) outbuf[6] = 'l'; } + /* the so-called "sticky" bit */ if ((fmode & S_ISVTX) != 0) { if (outbuf[9] == 'x') outbuf[9] = 't'; @@ -158,7 +157,7 @@ format_mode(unsigned long fmode) /* 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 + for example, on GNU/Linux in the /proc filesystem, where the symbolic link sizes are often 0. */ #ifndef SIZE_MAX @@ -176,10 +175,12 @@ read_symlink(const char *fname, size_t bufsize, ssize_t *linksize) if (bufsize) bufsize += 2; else - bufsize = BUFSIZ*2; + bufsize = BUFSIZ * 2; + /* Make sure that bufsize >= 2 and within range */ - if ((bufsize > MAXSIZE) || (bufsize < 2)) + if (bufsize > MAXSIZE || bufsize < 2) bufsize = MAXSIZE; + while (1) { char *buf; @@ -212,93 +213,106 @@ read_symlink(const char *fname, size_t bufsize, ssize_t *linksize) /* array_set --- set an array element */ static void -array_set(NODE *array, const char *sub, NODE *value) +array_set(awk_array_t array, const char *sub, awk_value_t *value) +{ + awk_element_t element; + awk_value_t tmp; + + memset(& element, 0, sizeof(element)); + + element.index = dup_string(sub, strlen(sub), & tmp)->str_value; + element.value = *value; + + set_array_element(array, & element); +} + +static void +array_set_numeric(awk_array_t array, const char *sub, double num) { - NODE *tmp; - NODE **aptr; - - tmp = make_string(sub, strlen(sub)); - aptr = assoc_lookup(array, tmp); - unref(tmp); - /* - * Note: since we initialized with assoc_clear, we know that aptr - * has been initialized with Nnull_string. Thus, the call to - * unref(*aptr) is not strictly necessary. However, I think it is - * generally more correct to call unref to maintain the proper - * reference count. - */ - unref(*aptr); - *aptr = value; + awk_value_t tmp; + return array_set(array, sub, make_number(num, & tmp)); } /* do_stat --- provide a stat() function for gawk */ -static NODE * -do_stat(int nargs) +static awk_value_t * +do_stat(int nargs, awk_value_t *result) { - NODE *file, *array; + awk_value_t file_param, array_param; + char *name; + awk_array_t array; struct stat sbuf; int ret; char *pmode; /* printable mode */ char *type = "unknown"; + awk_value_t tmp; - if (do_lint && nargs > 2) - lintwarn("stat: called with too many arguments"); + if (do_lint && nargs != 2) { + lintwarn(ext_id, "stat: called with wrong number of arguments"); + /* XXX previous version returned 0; why? */ + return make_number(-1, result); + } /* file is first arg, array to hold results is second */ - file = get_scalar_argument(0, false); - array = get_array_argument(1, false); + if (get_curfunc_param(0, AWK_STRING, &file_param) == NULL || + get_curfunc_param(1, AWK_ARRAY, &array_param) == NULL) { + warning(ext_id, "stat: bad parameters"); + /* XXX previous version returned 0; why? */ + return make_number(-1, result); + } + + name = file_param.str_value.str; + array = array_param.array_cookie; /* empty out the array */ - assoc_clear(array); + clear_array(array); /* lstat the file, if error, set ERRNO and return */ - (void) force_string(file); - ret = lstat(file->stptr, & sbuf); + ret = lstat(name, & sbuf); if (ret < 0) { update_ERRNO_int(errno); - return make_number((AWKNUM) ret); + /* XXX previous version returned 0; why? */ + return make_number(-1, result); } /* fill in the array */ - 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)); + array_set(array, "name", make_string(name, file_param.str_value.len, &tmp)); + array_set_numeric(array, "dev", sbuf.st_dev); + array_set_numeric(array, "ino", sbuf.st_ino); + array_set_numeric(array, "mode", sbuf.st_mode); + array_set_numeric(array, "nlink", sbuf.st_nlink); + array_set_numeric(array, "uid", sbuf.st_uid); + array_set_numeric(array, "gid", sbuf.st_gid); + array_set_numeric(array, "size", sbuf.st_size); + array_set_numeric(array, "blocks", sbuf.st_blocks); + array_set_numeric(array, "atime", sbuf.st_atime); + array_set_numeric(array, "mtime", sbuf.st_mtime); + array_set_numeric(array, "ctime", 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)) { - 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))); + array_set_numeric(array, "rdev", sbuf.st_rdev); + array_set_numeric(array, "major", major(sbuf.st_rdev)); + array_set_numeric(array, "minor", minor(sbuf.st_rdev)); } #ifdef HAVE_ST_BLKSIZE - array_set(array, "blksize", make_number((AWKNUM) sbuf.st_blksize)); + array_set_numeric(array, "blksize", sbuf.st_blksize); #endif /* HAVE_ST_BLKSIZE */ pmode = format_mode(sbuf.st_mode); - array_set(array, "pmode", make_string(pmode, strlen(pmode))); + array_set(array, "pmode", make_string(pmode, strlen(pmode), &tmp)); /* for symbolic links, add a linkval field */ if (S_ISLNK(sbuf.st_mode)) { char *buf; ssize_t linksize; - if ((buf = read_symlink(file->stptr, sbuf.st_size, + if ((buf = read_symlink(name, sbuf.st_size, &linksize)) != NULL) - array_set(array, "linkval", make_str_node(buf, linksize, ALREADY_MALLOCED)); + array_set(array, "linkval", make_string(buf, linksize, &tmp)); else - warning(_("unable to read symbolic link `%s'"), - file->stptr); + warning(ext_id, "unable to read symbolic link `%s'", name); } /* add a type field */ @@ -337,18 +351,19 @@ do_stat(int nargs) #endif } - array_set(array, "type", make_string(type, strlen(type))); + array_set(array, "type", make_string(type, strlen(type), &tmp)); - return make_number((AWKNUM) ret); + ret = 1; /* success */ + + return make_number(ret, result); } -/* dlload --- load new builtins in this library */ +static awk_ext_func_t func_table[] = { + { "chdir", do_chdir, 1 }, + { "stat", do_stat, 2 }, +}; -NODE * -dlload(NODE *tree, void *dl) -{ - make_builtin("chdir", do_chdir, 1); - make_builtin("stat", do_stat, 2); - return make_number((AWKNUM) 0); -} +/* define the dl_load function using the boilerplate macro */ + +dl_load_func(func_table, filefuncs, "") diff --git a/extension/filefuncs2.c b/extension/filefuncs2.c deleted file mode 100644 index 67b14185..00000000 --- a/extension/filefuncs2.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * filefuncs.c - Builtin functions that provide initial minimal iterface - * to the file system. - * - * Arnold Robbins, update for 3.1, Mon Nov 23 12:53:39 EST 1998 - * Arnold Robbins and John Haque, update for 3.1.4, applied Mon Jun 14 13:55:30 IDT 2004 - */ - -/* - * Copyright (C) 2001, 2004, 2005, 2010, 2011, 2012 - * 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 - */ - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include "gawkapi.h" - -static const gawk_api_t *api; /* for convenience macros to work */ -static awk_ext_id_t *ext_id; - -int plugin_is_GPL_compatible; - -/* do_chdir --- provide dynamically loaded chdir() builtin for gawk */ - -int -do_chdir(int nargs) -{ - const awk_value_t *newdir; - awk_value_t result; - int ret = -1; - - if (do_lint && nargs != 1) - lintwarn(ext_id, "chdir: called with incorrect number of arguments"); - - newdir = get_curfunc_param(0, AWK_PARAM_STRING); - ret = chdir(newdir->str_value.str); - if (ret < 0) - update_ERRNO_int(errno); - - result.val_type = AWK_NUMBER; - result.num_value = ret; - set_return_value(& result); - return 1; -} - -/* format_mode --- turn a stat mode field into something readable */ - -static char * -format_mode(unsigned long fmode) -{ - static char outbuf[12]; - static struct mode_map { - int mask; - int rep; - } map[] = { - { S_IRUSR, 'r' }, { S_IWUSR, 'w' }, { S_IXUSR, 'x' }, - { S_IRGRP, 'r' }, { S_IWGRP, 'w' }, { S_IXGRP, 'x' }, - { S_IROTH, 'r' }, { S_IWOTH, 'w' }, { S_IXOTH, 'x' }, - }; - int i, j, k; - - strcpy(outbuf, "----------"); - /* first, get the file type */ - i = 0; - switch (fmode & S_IFMT) { -#ifdef S_IFSOCK - case S_IFSOCK: - outbuf[i] = 's'; - break; -#endif -#ifdef S_IFLNK - case S_IFLNK: - outbuf[i] = 'l'; - break; -#endif - case S_IFREG: - outbuf[i] = '-'; /* redundant */ - break; - case S_IFBLK: - outbuf[i] = 'b'; - break; - case S_IFDIR: - outbuf[i] = 'd'; - break; -#ifdef S_IFDOOR /* Solaris weirdness */ - case S_IFDOOR: - outbuf[i] = 'D'; - break; -#endif /* S_IFDOOR */ - case S_IFCHR: - outbuf[i] = 'c'; - break; -#ifdef S_IFIFO - case S_IFIFO: - outbuf[i] = 'p'; - break; -#endif - } - - for (j = 0, k = sizeof(map)/sizeof(map[0]); j < k; j++) { - i++; - if ((fmode & map[j].mask) != 0) - outbuf[i] = map[j].rep; - } - - i++; - outbuf[i] = '\0'; - - /* setuid bit */ - if ((fmode & S_ISUID) != 0) { - if (outbuf[3] == 'x') - outbuf[3] = 's'; - else - outbuf[3] = 'S'; - } - - /* setgid without execute == locking */ - if ((fmode & S_ISGID) != 0) { - if (outbuf[6] == 'x') - outbuf[6] = 's'; - else - outbuf[6] = 'l'; - } - - /* the so-called "sticky" bit */ - if ((fmode & S_ISVTX) != 0) { - if (outbuf[9] == 'x') - outbuf[9] = 't'; - else - outbuf[9] = 'T'; - } - - 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 GNU/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(awk_array_t array, const char *sub, awk_value_t *value) -{ - awk_element_t element; - - memset(& element, 0, sizeof(element)); - - element.index = dup_string(sub, strlen(sub))->str_value; - element.value = *value; - - set_array_element(array, & element); -} - -/* do_stat --- provide a stat() function for gawk */ - -static int -do_stat(int nargs) -{ - awk_value_t *file_param, *array_param; - char *name; - awk_array_t array; - struct stat sbuf; - int ret; - char *pmode; /* printable mode */ - char *type = "unknown"; - - if (do_lint && nargs != 2) { - lintwarn(ext_id, "stat: called with wrong number of arguments"); - ret = 0; - goto out; - } - - /* file is first arg, array to hold results is second */ - file_param = get_curfunc_param(0, AWK_PARAM_STRING); - array_param = get_curfunc_param(0, AWK_PARAM_ARRAY); - - if (file_param == NULL || array_param == NULL) { - warning(ext_id, "stat: bad paramaters"); - ret = 0; - goto out; - } - - name = file_param->str_value.str; - array = array_param->array_cookie; - - /* empty out the array */ - clear_array(array); - - /* lstat the file, if error, set ERRNO and return */ - ret = lstat(name, & sbuf); - if (ret < 0) { - update_ERRNO_int(errno); - ret = 0; - goto out; - } - - /* fill in the array */ - array_set(array, "name", make_string(name, file_param->str_value.len)); - array_set(array, "dev", make_number((double) sbuf.st_dev)); - array_set(array, "ino", make_number((double) sbuf.st_ino)); - array_set(array, "mode", make_number((double) sbuf.st_mode)); - array_set(array, "nlink", make_number((double) sbuf.st_nlink)); - array_set(array, "uid", make_number((double) sbuf.st_uid)); - array_set(array, "gid", make_number((double) sbuf.st_gid)); - array_set(array, "size", make_number((double) sbuf.st_size)); - array_set(array, "blocks", make_number((double) sbuf.st_blocks)); - array_set(array, "atime", make_number((double) sbuf.st_atime)); - array_set(array, "mtime", make_number((double) sbuf.st_mtime)); - array_set(array, "ctime", make_number((double) 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)) { - array_set(array, "rdev", make_number((double) sbuf.st_rdev)); - array_set(array, "major", make_number((double) major(sbuf.st_rdev))); - array_set(array, "minor", make_number((double) minor(sbuf.st_rdev))); - } - -#ifdef HAVE_ST_BLKSIZE - array_set(array, "blksize", make_number((double) sbuf.st_blksize)); -#endif /* HAVE_ST_BLKSIZE */ - - pmode = format_mode(sbuf.st_mode); - array_set(array, "pmode", make_string(pmode, strlen(pmode))); - - /* for symbolic links, add a linkval field */ - if (S_ISLNK(sbuf.st_mode)) { - char *buf; - ssize_t linksize; - - if ((buf = read_symlink(name, sbuf.st_size, - &linksize)) != NULL) - array_set(array, "linkval", make_string(buf, linksize)); - else - warning(ext_id, "unable to read symbolic link `%s'", name); - } - - /* add a type field */ - switch (sbuf.st_mode & S_IFMT) { -#ifdef S_IFSOCK - case S_IFSOCK: - type = "socket"; - break; -#endif -#ifdef S_IFLNK - case S_IFLNK: - type = "symlink"; - break; -#endif - case S_IFREG: - type = "file"; - break; - case S_IFBLK: - type = "blockdev"; - break; - case S_IFDIR: - type = "directory"; - break; -#ifdef S_IFDOOR - case S_IFDOOR: - type = "door"; - break; -#endif - case S_IFCHR: - type = "chardev"; - break; -#ifdef S_IFIFO - case S_IFIFO: - type = "fifo"; - break; -#endif - } - - array_set(array, "type", make_string(type, strlen(type))); - - ret = 1; /* success */ - -out: - set_return_value(make_number((double) ret)); -} - -static awk_ext_func_t func_table[] = { - { "chdir", do_chdir, 1 }, - { "stat", do_stat, 2 }, -}; - - -/* define the dl_load function using the boilerplate macro */ - -dl_load_func(api, ext_id, func_table, filefuncs, "") diff --git a/extension/fork.c b/extension/fork.c index 3c288c04..a7f96017 100644 --- a/extension/fork.c +++ b/extension/fork.c @@ -25,102 +25,122 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "awk.h" +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <sys/wait.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "gawkapi.h" + +static const gawk_api_t *api; /* for convenience macros to work */ +static awk_ext_id_t *ext_id; int plugin_is_GPL_compatible; + +/* array_set --- set an array element */ + +static void +array_set_numeric(awk_array_t array, const char *sub, double num) +{ + awk_element_t element; + awk_value_t tmp; + + memset(& element, 0, sizeof(element)); + + element.index = dup_string(sub, strlen(sub), & tmp)->str_value; + make_number(num, &element.value); + + set_array_element(array, & element); +} + /* do_fork --- provide dynamically loaded fork() builtin for gawk */ -static NODE * -do_fork(int nargs) +static awk_value_t * +do_fork(int nargs, awk_value_t *result) { int ret = -1; - NODE **aptr; - NODE *tmp; if (do_lint && nargs > 0) - lintwarn("fork: called with too many arguments"); + lintwarn(ext_id, "fork: called with too many arguments"); ret = fork(); 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)); - unref(*aptr); - *aptr = make_number((AWKNUM) getpid()); - unref(tmp); - - aptr = assoc_lookup(PROCINFO_node, tmp = make_string("ppid", 4)); - unref(*aptr); - *aptr = make_number((AWKNUM) getppid()); - unref(tmp); + else if (ret == 0) { + /* update PROCINFO in the child, if the array exists */ + awk_value_t procinfo; + if (sym_lookup("PROCINFO", &procinfo) != NULL) { + if (procinfo.val_type != AWK_ARRAY) { + if (do_lint) + lintwarn(ext_id, "fork: PROCINFO is not an array!"); + } else { + array_set_numeric(procinfo.array_cookie, "pid", getpid()); + array_set_numeric(procinfo.array_cookie, "ppid", getppid()); + } + } } /* Set the return value */ - return make_number((AWKNUM) ret); + return make_number(ret, result); } /* do_waitpid --- provide dynamically loaded waitpid() builtin for gawk */ -static NODE * -do_waitpid(int nargs) +static awk_value_t * +do_waitpid(int nargs, awk_value_t *result) { - NODE *pidnode; + awk_value_t pid; int ret = -1; - double pidval; - pid_t pid; int options = 0; if (do_lint && nargs > 1) - lintwarn("waitpid: called with too many arguments"); + lintwarn(ext_id, "waitpid: called with too many arguments"); - pidnode = get_scalar_argument(0, false); - if (pidnode != NULL) { - pidval = get_number_d(pidnode); - pid = (int) pidval; + if (get_curfunc_param(0, AWK_NUMBER, &pid) != NULL) { options = WNOHANG|WUNTRACED; - ret = waitpid(pid, NULL, options); + ret = waitpid(pid.num_value, NULL, options); if (ret < 0) update_ERRNO_int(errno); } else if (do_lint) - lintwarn("wait: called with no arguments"); + lintwarn(ext_id, "wait: called with no arguments"); /* Set the return value */ - return make_number((AWKNUM) ret); + return make_number(ret, result); } /* do_wait --- provide dynamically loaded wait() builtin for gawk */ -static NODE * -do_wait(int nargs) +static awk_value_t * +do_wait(int nargs, awk_value_t *result) { int ret; if (do_lint && nargs > 0) - lintwarn("wait: called with too many arguments"); + lintwarn(ext_id, "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); + return make_number(ret, result); } -/* dlload --- load new builtins in this library */ +static awk_ext_func_t func_table[] = { + { "fork", do_fork, 0 }, + { "waitpid", do_waitpid, 1 }, + { "wait", do_wait, 0 }, +}; -NODE * -dlload(tree, dl) -NODE *tree; -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); -} +/* define the dl_load function using the boilerplate macro */ + +dl_load_func(func_table, fork, "") diff --git a/extension/ordchr.c b/extension/ordchr.c index 6abda181..95401650 100644 --- a/extension/ordchr.c +++ b/extension/ordchr.c @@ -28,71 +28,75 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "awk.h" +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "gawkapi.h" + +static const gawk_api_t *api; /* for convenience macros to work */ +static awk_ext_id_t *ext_id; int plugin_is_GPL_compatible; /* do_ord --- return numeric value of first char of string */ -static NODE * -do_ord(int nargs) +static awk_value_t * +do_ord(int nargs, awk_value_t *result) { - NODE *str; - int ret = -1; + awk_value_t str; + double ret = -1; if (do_lint && nargs > 1) - lintwarn("ord: called with too many arguments"); + lintwarn(ext_id, "ord: called with too many arguments"); - str = get_scalar_argument(0, false); - if (str != NULL) { - (void) force_string(str); - ret = str->stptr[0]; + if (get_curfunc_param(0, AWK_STRING, &str) != NULL) { + ret = str.str_value.str[0]; } else if (do_lint) - lintwarn("ord: called with no arguments"); - + lintwarn(ext_id, "ord: called with no arguments"); /* Set the return value */ - return make_number((AWKNUM) ret); + return make_number(ret, result); } /* do_chr --- turn numeric value into a string */ -static NODE * -do_chr(int nargs) +static awk_value_t * +do_chr(int nargs, awk_value_t *result) { - NODE *num; + awk_value_t num; unsigned int ret = 0; - AWKNUM val = 0.0; + double val = 0.0; char str[2]; str[0] = str[1] = '\0'; if (do_lint && nargs > 1) - lintwarn("chr: called with too many arguments"); + lintwarn(ext_id, "chr: called with too many arguments"); - num = get_scalar_argument(0, false); - if (num != NULL) { - val = get_number_d(num); + if (get_curfunc_param(0, AWK_NUMBER, &num) != NULL) { + val = num.num_value; ret = val; /* convert to int */ ret &= 0xff; str[0] = ret; str[1] = '\0'; } else if (do_lint) - lintwarn("chr: called with no arguments"); + lintwarn(ext_id, "chr: called with no arguments"); /* Set the return value */ - return make_string(str, 1); + return dup_string(str, 1, result); } -/* dlload --- load new builtins in this library */ +static awk_ext_func_t func_table[] = { + { "ord", do_ord, 1 }, + { "chr", do_chr, 1 }, +}; -NODE * -dlload(tree, dl) -NODE *tree; -void *dl; -{ - make_builtin("ord", do_ord, 1); - make_builtin("chr", do_chr, 1); +/* define the dl_load function using the boilerplate macro */ - return make_number((AWKNUM) 0); -} +dl_load_func(func_table, ord_chr, "") diff --git a/extension/ordchr2.c b/extension/ordchr2.c deleted file mode 100644 index 1f4a1fcb..00000000 --- a/extension/ordchr2.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * ordchr.c - Builtin functions that provide ord() and chr() functions. - * - * Arnold Robbins - * arnold@skeeve.com - * 8/2001 - * Revised 6/2004 - */ - -/* - * Copyright (C) 2001, 2004, 2011 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 - */ - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include "gawkapi.h" - -static const gawk_api_t *api; /* for convenience macros to work */ -static awk_ext_id_t *ext_id; - -int plugin_is_GPL_compatible; - -/* do_ord --- return numeric value of first char of string */ - -static int -do_ord(int nargs) -{ - const awk_value_t *str; - awk_value_t result; - double ret = -1; - - if (do_lint && nargs > 1) - lintwarn(ext_id, "ord: called with too many arguments"); - - str = get_curfunc_param(0, AWK_PARAM_STRING); - if (str != NULL) { - ret = str->str_value.str[0]; - } else if (do_lint) - lintwarn(ext_id, "ord: called with no arguments"); - - /* Set the return value */ - set_return_value(make_number(ret)); - return 1; -} - -/* do_chr --- turn numeric value into a string */ - -static int -do_chr(int nargs) -{ - const awk_value_t *num; - awk_value_t result; - unsigned int ret = 0; - double val = 0.0; - char str[2]; - - str[0] = str[1] = '\0'; - - if (do_lint && nargs > 1) - lintwarn(ext_id, "chr: called with too many arguments"); - - num = get_curfunc_param(0, AWK_PARAM_NUMBER); - if (num != NULL) { - val = num->num_value; - ret = val; /* convert to int */ - ret &= 0xff; - str[0] = ret; - str[1] = '\0'; - } else if (do_lint) - lintwarn(ext_id, "chr: called with no arguments"); - - /* Set the return value */ - set_return_value(dup_string(str, 1)); - return 1; -} - -static awk_ext_func_t func_table[] = { - { "ord", do_ord, 1 }, - { "chr", do_chr, 1 }, -}; - -/* define the dl_load function using the boilerplate macro */ - -dl_load_func(api, ext_id, func_table, ord_chr, "") diff --git a/extension/readfile.c b/extension/readfile.c index 17e70a6d..639c897a 100644 --- a/extension/readfile.c +++ b/extension/readfile.c @@ -30,34 +30,43 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "awk.h" +#include <stdio.h> +#include <errno.h> #include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "gawkapi.h" #ifndef O_BINARY #define O_BINARY 0 #endif +static const gawk_api_t *api; /* for convenience macros to work */ +static awk_ext_id_t *ext_id; + int plugin_is_GPL_compatible; /* do_readfile --- read a file into memory */ -static NODE * -do_readfile(int nargs) +static awk_value_t * +do_readfile(int nargs, awk_value_t *result) { - NODE *filename; - int ret = -1; + awk_value_t filename; + double ret = -1; struct stat sbuf; char *text; int fd; if (do_lint && nargs > 1) - lintwarn("readfile: called with too many arguments"); - - filename = get_scalar_argument(0, false); - if (filename != NULL) { - (void) force_string(filename); + lintwarn(ext_id, "readfile: called with too many arguments"); - ret = stat(filename->stptr, & sbuf); + if (get_curfunc_param(0, AWK_STRING, &filename) != NULL) { + ret = stat(filename.str_value.str, & sbuf); if (ret < 0) { update_ERRNO_int(errno); goto done; @@ -68,7 +77,7 @@ do_readfile(int nargs) goto done; } - if ((fd = open(filename->stptr, O_RDONLY|O_BINARY)) < 0) { + if ((fd = open(filename.str_value.str, O_RDONLY|O_BINARY)) < 0) { ret = -1; update_ERRNO_int(errno); goto done; @@ -85,25 +94,20 @@ do_readfile(int nargs) } close(fd); - return make_string(text, sbuf.st_size); + return make_string(text, sbuf.st_size, result); } else if (do_lint) - lintwarn("filename: called with no arguments"); + lintwarn(ext_id, "readfile: called with no arguments"); done: /* Set the return value */ - return make_number((AWKNUM) ret); + return make_number(ret, result); } +static awk_ext_func_t func_table[] = { + { "readfile", do_readfile, 1 }, +}; -/* dlload --- load new builtins in this library */ +/* define the dl_load function using the boilerplate macro */ -NODE * -dlload(tree, dl) -NODE *tree; -void *dl; -{ - make_builtin("readfile", do_readfile, 1); - - return make_number((AWKNUM) 0); -} +dl_load_func(func_table, readfile, "") diff --git a/extension/readfile2.c b/extension/readfile2.c deleted file mode 100644 index 4d8cd245..00000000 --- a/extension/readfile2.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * readfile.c - Read an entire file into a string. - * - * Arnold Robbins - * Tue Apr 23 17:43:30 IDT 2002 - * Revised per Peter Tillier - * Mon Jun 9 17:05:11 IDT 2003 - * Revised for new dynamic function facilities - * Mon Jun 14 14:53:07 IDT 2004 - */ - -/* - * Copyright (C) 2002, 2003, 2004, 2011 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 - */ - -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include "gawkapi.h" - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -static const gawk_api_t *api; /* for convenience macros to work */ -static awk_ext_id_t *ext_id; - -int plugin_is_GPL_compatible; - -/* do_readfile --- read a file into memory */ - -static int -do_readfile(int nargs) -{ - const awk_value_t *filename; - awk_value_t result; - double ret = -1; - struct stat sbuf; - char *text; - int fd; - - if (do_lint && nargs > 1) - lintwarn(ext_id, "readfile: called with too many arguments"); - - filename = get_curfunc_param(0, AWK_PARAM_STRING); - if (filename != NULL) { - ret = stat(filename->str_value.str, & sbuf); - if (ret < 0) { - update_ERRNO_int(errno); - goto done; - } else if ((sbuf.st_mode & S_IFMT) != S_IFREG) { - errno = EINVAL; - ret = -1; - update_ERRNO_int(errno); - goto done; - } - - if ((fd = open(filename->str_value.str, O_RDONLY|O_BINARY)) < 0) { - ret = -1; - update_ERRNO_int(errno); - goto done; - } - - emalloc(text, char *, sbuf.st_size + 2, "do_readfile"); - memset(text, '\0', sbuf.st_size + 2); - - if ((ret = read(fd, text, sbuf.st_size)) != sbuf.st_size) { - (void) close(fd); - ret = -1; - update_ERRNO_int(errno); - goto done; - } - - close(fd); - set_return_value(make_string(text, sbuf.st_size)); - return 1; - } else if (do_lint) - lintwarn(ext_id, "readfile: called with no arguments"); - - -done: - /* Set the return value */ - set_return_value(make_number(ret)); - return 0; -} - -static awk_ext_func_t func_table[] = { - { "readfile", do_readfile, 1 }, -}; - -/* define the dl_load function using the boilerplate macro */ - -dl_load_func(api, ext_id, func_table, readfile, "") |