aboutsummaryrefslogtreecommitdiffstats
path: root/extension
diff options
context:
space:
mode:
Diffstat (limited to 'extension')
-rw-r--r--extension/ChangeLog12
-rw-r--r--extension/Makefile.am2
-rw-r--r--extension/Makefile.in9
-rwxr-xr-xextension/configure3
-rw-r--r--extension/configure.ac4
-rw-r--r--extension/filefuncs.c221
-rw-r--r--extension/filefuncs2.c365
-rw-r--r--extension/fork.c114
-rw-r--r--extension/ordchr.c70
-rw-r--r--extension/ordchr2.c107
-rw-r--r--extension/readfile.c54
-rw-r--r--extension/readfile2.c116
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, "")