From c9c5f9da9366d1587c588507433cec35ef243579 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sat, 30 Aug 2003 19:06:06 +0000 Subject: 18980: new zsh/system module --- ChangeLog | 7 + Doc/.cvsignore | 1 + Doc/Makefile.in | 5 +- Doc/Zsh/mod_system.yo | 128 ++++++++++++++ Doc/Zsh/params.yo | 3 +- Src/Modules/.cvsignore | 1 + Src/Modules/errnames1.awk | 18 ++ Src/Modules/errnames2.awk | 42 +++++ Src/Modules/system.c | 418 ++++++++++++++++++++++++++++++++++++++++++++++ Src/Modules/system.mdd | 27 +++ zshconfig.ac | 33 ++++ 11 files changed, 680 insertions(+), 3 deletions(-) create mode 100644 Doc/Zsh/mod_system.yo create mode 100644 Src/Modules/errnames1.awk create mode 100644 Src/Modules/errnames2.awk create mode 100644 Src/Modules/system.c create mode 100644 Src/Modules/system.mdd diff --git a/ChangeLog b/ChangeLog index ee08cb553..20ea2b6d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2003-08-30 Peter Stephenson + * 18980: zshconfig.ac, Doc/.cvsignore, Doc/Makefile.in, + Doc/Zsh/mod_system.yo, Doc/Zsh/params.yo, Src/params.c, + Src/Modules/.cvsignore, Src/Modules/errnames1.awk, + Src/Modules/errnames2.awk, Src/Modules/system.c, + Src/Modules/system.mdd: zsh/system module provides interface + to read, write and system errors. + * 18982: Src/subst.c: Comments/rant for paramsubst(). * 18981: Doc/Zsh/tcpsys.yo: General tidy up. diff --git a/Doc/.cvsignore b/Doc/.cvsignore index 9d1374c2f..23228b27f 100644 --- a/Doc/.cvsignore +++ b/Doc/.cvsignore @@ -15,3 +15,4 @@ zsh.tp zsh.tps zsh_*.ps infodir *.swp +zsh.pdf zsh_a4.pdf zsh_us.pdf diff --git a/Doc/Makefile.in b/Doc/Makefile.in index e5f691f08..692b7653b 100644 --- a/Doc/Makefile.in +++ b/Doc/Makefile.in @@ -60,10 +60,11 @@ Zsh/mod_computil.yo \ Zsh/mod_deltochar.yo Zsh/mod_example.yo Zsh/mod_files.yo \ Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo Zsh/mod_parameter.yo Zsh/mod_pcre.yo \ Zsh/mod_sched.yo Zsh/mod_socket.yo \ -Zsh/mod_stat.yo Zsh/mod_termcap.yo Zsh/mod_terminfo.yo \ +Zsh/mod_stat.yo Zsh/mod_system.yo Zsh/mod_tcp.yo \ +Zsh/mod_termcap.yo Zsh/mod_terminfo.yo \ Zsh/mod_zftp.yo Zsh/mod_zle.yo Zsh/mod_zleparameter.yo \ Zsh/mod_zprof.yo Zsh/mod_zpty.yo Zsh/mod_zselect.yo \ -Zsh/mod_zutil.yo Zsh/mod_tcp.yo +Zsh/mod_zutil.yo YODLSRC = zmacros.yo zman.yo ztexi.yo Zsh/arith.yo Zsh/builtins.yo \ Zsh/compat.yo Zsh/compctl.yo Zsh/compsys.yo Zsh/compwid.yo Zsh/cond.yo \ diff --git a/Doc/Zsh/mod_system.yo b/Doc/Zsh/mod_system.yo new file mode 100644 index 000000000..1dc581bed --- /dev/null +++ b/Doc/Zsh/mod_system.yo @@ -0,0 +1,128 @@ +COMMENT(!MOD!zsh/system +A builtin interface to various low-level system features. +!MOD!) +The tt(zsh/system) module makes available three builtin commands and +a parameter. + +sect(Builtins) + +startitem() +findex(syserror) +item(tt(syserror) tt([ -e) var(errvar) tt(] [ -p) var(prefix) tt(] [) var(errno) tt(|) var(errname ]))( +This command prints out the error message associated with var(errno), a +system error number, followed by a newline to standard error. + +Instead of the error number, a name var(errname), for example +tt(ENOENT), may be used. The set of names is the same as the contents +of the array tt(errnos), see below. + +If the string var(prefix) is given, it is printed in front of the error +message, with no intervening space. + +If var(errvar) is supplied, the entire message, without a newline, is +assigned to the parameter names var(errvar) and nothing is output. + +A return value of 0 indicates the message was successfully printed +(although it may not be useful if the error number was out of the +system's range), a return value of 1 indicates an error in the +parameters, and a return value of 2 indicates the error name was +not recognised (no message is printed for this). +) +findex(sysread) +xitem(tt(sysread [ -c) var(countvar) tt(] [ -i) var(infd) tt(] [ -o) var(outfd) tt(])) +item( tt([ -s) var(bufsize) tt(] [ -t) var(timeout) tt(] [) var(param) tt(]))( +Perform a single system read from file descriptor var(infd), or zero if +that is not given. The result of the read is stored in var(param) or +var(REPLY) if that is not given. If var(countvar) is given, the number +of bytes read is assigned to the parameter named by var(countvar). + +The maximum number of bytes read is var(bufsize) or 8192 if that is not +given, however the command returns as soon as any number of bytes was +successfully read. + +If var(timeout) is given, it specifies a timeout in seconds, which may +be zero to poll the file descriptor. This is handled by the tt(poll) +system call if available, otherwise the tt(select) system call if +available. + +If var(outfd) is given, an attempt is made to write all the bytes just +read to the file descriptor var(outfd). If this fails, because of a +system error other than tt(EINTR) or because of an internal zsh error +during an interrupt, the bytes read but not written are stored in the +parameter named by var(param) if supplied (no default is used in this +case), and the number of bytes read but not written is stored in the +parameter named by var(countvar) if that is supplied. If it was +successful, var(countvar) contains the full number of bytes transferred, +as usual, and var(param) is not set. + +The error tt(EINTR) (interrupted system call) is handled internally so +that shell interrupts are transparent to the caller. Any other error +causes a return. + +The possible return values are +startitem() +item(0)( +At least one byte of data was successfully read and, if appropriate, +written. +) +item(1)( +There was an error in the parameters to the command. This is the only +error for which a message is printed to standard error. +) +item(2)( +There was an error on the read, or on polling the input file descriptor +for a timeout. The parameter tt(ERRNO) gives the error. +) +item(3)( +Data were successfully read, but there was an error writing them +to var(outfd). The parameter tt(ERRNO) gives the error. +) +item(4)( +The attempt to read timed out. Note this does not set tt(ERRNO) as this +is not a system error. +) +item(5)( +No system error occurred, but zero bytes were read. This usually +indicates end of file. The parameters are set according to the +usual rules; no write to var(outfd) is attempted. +) +enditem() +) +item(tt(syswrite [ -c) var(countvar) tt(] [ -o) var(outfd) tt(]) var(data))( +The data (a single string of bytes) are written to the file descriptor +var(outfd), or 1 if that is not given, using the tt(write) system call. +Multiple write operations may be used if the first does not write all +the data. + +If var(countvar) is given, the number of byte written is stored in the +parameter named by var(countvar); this may not be the full length of +var(data) if an error occurred. + +The error tt(EINTR) (interrupted system call) is handled internally by +retrying; otherwise an error causes the command to return. For example, +if the file descriptor is set to non-blocking output, an error +tt(EAGAIN) (on some systems, tt(EWOULDBLOCK)) may result in the command +returning early. + +The return status may be 0 for success, 1 for an error in the parameters +to the command, or 2 for an error on the write; no error message is +printed in the last case, but the parameter tt(ERRNO) will reflect +the error that occurred. +) +enditem() + +sect(Parameters) + +startitem() +item(tt(errnos))( +A readonly array of the names of errors defined on the system. These +are typically macros defined in C by including the system header file +tt(errno.h). The index of each name (assuming the option tt(KSH_ARRAYS) +is unset) corresponds to the error number. Error numbers var(num) +before the last known error which have no name are given the name +tt(E)var(num) in the array. + +Note that aliases for errors are not handled; only the canonical name is +used. +) +enditem() diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 675a75991..f2f64c93c 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -520,7 +520,8 @@ item(tt(ERRNO) )( The value of errno (see manref(errno)(3)) as set by the most recently failed system call. This value is system dependent and is intended for debugging -purposes. +purposes. It is also useful with the tt(zsh/system) module which +allows the number to be turned into a name or message. ) vindex(GID) item(tt(GID) )( diff --git a/Src/Modules/.cvsignore b/Src/Modules/.cvsignore index d0ea7d755..acafc7ad3 100644 --- a/Src/Modules/.cvsignore +++ b/Src/Modules/.cvsignore @@ -13,3 +13,4 @@ so_locations *.mdhs *.mdh.tmp *.swp +ernames.c errcount.h diff --git a/Src/Modules/errnames1.awk b/Src/Modules/errnames1.awk new file mode 100644 index 000000000..5c41197cb --- /dev/null +++ b/Src/Modules/errnames1.awk @@ -0,0 +1,18 @@ +# Edited version of Src/signames1.awk. +# +# This is an awk script which finds out what the possibilities for +# the error names are, and dumps them out so that cpp can turn them +# into numbers. Since we don't need to decide here what the +# real signals are, we can afford to be generous about definitions, +# in case the definitions are in terms of other definitions. +# However, we need to avoid definitions with parentheses, which will +# mess up the syntax. +BEGIN { printf "#include \n\n" } + +/^[\t ]*#[\t ]*define[\t ]*E[A-Z0-9]*[\t ][\t ]*[^(\t ]/ { + eindex = index($0, "E") + etail = substr($0, eindex, 80) + split(etail, tmp) + enam = substr(tmp[1], 2, 20) + printf("XXNAMES XXE%s E%s\n", enam, enam) +} diff --git a/Src/Modules/errnames2.awk b/Src/Modules/errnames2.awk new file mode 100644 index 000000000..60969b423 --- /dev/null +++ b/Src/Modules/errnames2.awk @@ -0,0 +1,42 @@ +# Edited version of Src/signames2.awk. +# +# {g,n}awk script to generate errnames.c +# This version relies on the previous output of the preprocessor +# on sigtmp.c, sigtmp.out, which is in turn generated by errnames1.awk. +# +# NB: On SunOS 4.1.3 - user-functions don\'t work properly, also \" problems +# Without 0 + hacks some nawks compare numbers as strings +# +/^XXNAMES XXE[A-Z0-9]*[\t ][\t ]*[1-9][0-9]*/ { + eindex = index($0, "E") + etail = substr($0, 11, 80) + split(etail, tmp) + enam = tmp[1] + enum = tmp[2] + if (errname[enum] == "") { + errname[enum] = enam + if (0 + max < 0 + enum && enum < 1024) + max = enum + } +} + +END { + ps = "%s" + printf "/** errnames.c **/\n" + printf "/** architecture-customized errnames.c for zsh **/\n" + printf "\n" + printf "#define ERRCOUNT\t%d\n", max + printf "\n" + printf "#include %csystem.mdh%c\n", 34, 34 + printf "\n" + printf "/**/\n" + printf "const char *sys_errnames[ERRCOUNT+1] = {\n" + + for (i = 1; i <= 0 + max; i++) + if (errname[i] == "") + printf("\t%cE%d%c,\n", 34, i, 34) + else + printf("\t%c%s%c,\n", 34, errname[i], 34) + print "\tNULL" + print "};" +} diff --git a/Src/Modules/system.c b/Src/Modules/system.c new file mode 100644 index 000000000..174bf133d --- /dev/null +++ b/Src/Modules/system.c @@ -0,0 +1,418 @@ +/* + * sysread.c - interface to system read/write + * + * This file is part of zsh, the Z shell. + * + * Copyright (c) 1998-2003 Peter Stephenson + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Peter Stephenson or the Zsh Development + * Group be liable to any party for direct, indirect, special, incidental, + * or consequential damages arising out of the use of this software and + * its documentation, even if Peter Stephenson, and the Zsh + * Development Group have been advised of the possibility of such damage. + * + * Peter Stephenson and the Zsh Development Group specifically + * disclaim any warranties, including, but not limited to, the implied + * warranties of merchantability and fitness for a particular purpose. The + * software provided hereunder is on an "as is" basis, and Peter Stephenson + * and the Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ + +#include "system.mdh" +#include "system.pro" + +#ifdef HAVE_POLL_H +# include +#endif +#if defined(HAVE_POLL) && !defined(POLLIN) +# undef HAVE_POLL +#endif + +#define SYSREAD_BUFSIZE 8192 + +/**/ +static int +getposint(char *instr, char *nam) +{ + char *eptr; + int ret; + + ret = (int)zstrtol(instr, &eptr, 10); + if (*eptr || ret < 0) { + zwarnnam(nam, "integer expected: %s", instr, 0); + return -1; + } + + return ret; +} + + +/* + * Return values of bin_sysread: + * 0 Successfully read (and written if appropriate) + * 1 Error in parameters to command + * 2 Error on read, or polling read fd ) ERRNO set by + * 3 Error on write ) system + * 4 Timeout on read + * 5 Zero bytes read, end of file + */ + +/**/ +static int +bin_sysread(char *nam, char **args, Options ops, int func) +{ + int infd = 0, outfd = -1, bufsize = SYSREAD_BUFSIZE, count; + char *outvar = NULL, *countvar = NULL, *inbuf; + + /* -i: input file descriptor if not stdin */ + if (OPT_ISSET(ops, 'i')) { + infd = getposint(OPT_ARG(ops, 'i'), nam); + if (infd < 0) + return 1; + } + + /* -o: output file descriptor, else store in REPLY */ + if (OPT_ISSET(ops, 'o')) { + if (*args) { + zwarnnam(nam, "no argument allowed with -o", NULL, 0); + return 1; + } + outfd = getposint(OPT_ARG(ops, 'o'), nam); + if (outfd < 0) + return 1; + } + + /* -s: buffer size if not default SYSREAD_BUFSIZE */ + if (OPT_ISSET(ops, 's')) { + bufsize = getposint(OPT_ARG(ops, 's'), nam); + if (bufsize < 0) + return 1; + } + + /* -c: name of variable to store count of transferred bytes */ + if (OPT_ISSET(ops, 'c')) { + countvar = OPT_ARG(ops, 'c'); + if (!isident(countvar)) { + zwarnnam(nam, "not an identifier: %s", countvar, 0); + return 1; + } + } + + if (*args) { + /* + * Variable in which to store result if doing a plain read. + * Default variable if not specified is REPLY. + * If writing, only stuff we couldn't write is stored here, + * no default in that case (we just discard it if no variable). + */ + outvar = *args; + if (!isident(outvar)) { + zwarnnam(nam, "not an identifier: %s", outvar, 0); + return 1; + } + } + + inbuf = zhalloc(bufsize); + +#if defined(HAVE_POLL) || defined(HAVE_SELECT) + /* -t: timeout */ + if (OPT_ISSET(ops, 't')) + { +# ifdef HAVE_POLL + struct pollfd poll_fd; + mnumber to_mn; + int to_int, ret; + + poll_fd.fd = infd; + poll_fd.events = POLLIN; + + to_mn = matheval(OPT_ARG(ops, 't')); + if (errflag) + return 1; + if (to_mn.type == MN_FLOAT) + to_int = (int) (1000 * to_mn.u.d); + else + to_int = 1000 * (int)to_mn.u.l; + + while ((ret = poll(&poll_fd, 1, to_int)) < 0) { + if (errno != EINTR || errflag || retflag || breaks || contflag) + break; + } + if (ret <= 0) { + /* treat non-timeout error as error on read */ + return ret ? 2 : 4; + } +# else + /* using select */ + struct timeval select_tv; + fd_set fds; + mnumber to_mn; + int ret; + + FD_ZERO(&fds); + FD_SET(infd, &fds); + to_mn = matheval(OPT_ARG(ops, 't')); + if (errflag) + return 1; + + if (to_mn.type == MN_FLOAT) { + select_tv.tv_sec = (int) to_mn.u.d; + select_tv.tv_usec = + (int) ((to_mn.u.d - select_tv.tv_sec) * 1e6); + } else { + select_tv.tv_sec = (int) to_mn.u.l; + select_tv.tv_usec = 0; + } + + while ((ret = select(infd+1, (SELECT_ARG_2_T) &fds, + NULL, NULL,&select_tv)) < 1) { + if (errno != EINTR || errflag || retflag || breaks || contflag) + break; + } + if (ret <= 0) { + /* treat non-timeout error as error on read */ + return ret ? 2 : 4; + } +# endif + } +#endif + + while ((count = read(infd, inbuf, bufsize)) < 0) { + if (errno != EINTR || errflag || retflag || breaks || contflag) + break; + } + if (countvar) + setiparam(countvar, count); + if (count < 0) + return 2; + + if (outfd >= 0) { + if (!count) + return 5; + while (count > 0) { + int ret; + + ret = write(outfd, inbuf, count); + if (ret < 0) { + if (errno == EINTR && !errflag && + !retflag && !breaks && !contflag) + continue; + if (outvar) + setsparam(outvar, metafy(inbuf, count, META_DUP)); + if (countvar) + setiparam(countvar, count); + return 3; + } + inbuf += ret; + count -= ret; + } + return 0; + } + + if (!outvar) + outvar = "REPLY"; + /* do this even if we read zero bytes */ + setsparam(outvar, metafy(inbuf, count, META_DUP)); + + return count ? 0 : 5; +} + + +/* + * Return values of bin_syswrite: + * 0 Successfully written + * 1 Error in parameters to command + * 2 Error on write, ERRNO set by system + */ + +/**/ +static int +bin_syswrite(char *nam, char **args, Options ops, int func) +{ + int outfd = 1, len, count, totcount; + char *countvar = NULL; + + /* -o: output file descriptor if not stdout */ + if (OPT_ISSET(ops, 'o')) { + outfd = getposint(OPT_ARG(ops, 'o'), nam); + if (outfd < 0) + return 1; + } + + /* -c: variable in which to store count of bytes written */ + if (OPT_ISSET(ops, 'c')) { + countvar = OPT_ARG(ops, 'c'); + if (!isident(countvar)) { + zwarnnam(nam, "not an identifier: %s", countvar, 0); + return 1; + } + } + + totcount = 0; + unmetafy(*args, &len); + while (len) { + while ((count = write(outfd, *args, len)) < 0) { + if (errno != EINTR || errflag || retflag || breaks || contflag) + { + if (countvar) + setiparam(countvar, totcount); + return 2; + } + } + *args += count; + totcount += count; + len -= count; + } + if (countvar) + setiparam(countvar, totcount); + + return 0; +} + + +/* + * Return values of bin_syserror: + * 0 Successfully processed error + * (although if the number was invalid the string + * may not be useful) + * 1 Error in parameters + * 2 Name of error not recognised. + */ + +/**/ +static int +bin_syserror(char *nam, char **args, Options ops, int func) +{ + int num = 0; + char *errvar = NULL, *msg, *pfx = "", *str; + + /* variable in which to write error message */ + if (OPT_ISSET(ops, 'e')) { + errvar = OPT_ARG(ops, 'e'); + if (!isident(errvar)) { + zwarnnam(nam, "not an identifier: %s", errvar, 0); + return 1; + } + } + /* prefix for error message */ + if (OPT_ISSET(ops, 'p')) + pfx = OPT_ARG(ops, 'p'); + + if (!*args) + num = errno; + else { + char *ptr = *args; + while (*ptr && idigit(*ptr)) + ptr++; + if (!*ptr && ptr > *args) + num = atoi(*args); + else { + const char **eptr; + for (eptr = sys_errnames; *eptr; eptr++) { + if (!strcmp(*eptr, *args)) { + num = (eptr - sys_errnames) + 1; + break; + } + } + if (!*eptr) + return 2; + } + } + + msg = strerror(num); + if (errvar) { + str = (char *)zalloc(strlen(msg) + strlen(pfx) + 1); + sprintf(str, "%s%s", pfx, msg); + setsparam(errvar, str); + } else { + fprintf(stderr, "%s%s\n", pfx, msg); + } + + return 0; +} + + +/* Functions for the errnos special parameter. */ + +/**/ +static char ** +errnosgetfn(Param pm) +{ + /* arrdup etc. should really take const pointers as arguments */ + return arrdup((char **)sys_errnames); +} + + +static struct builtin bintab[] = { + BUILTIN("syserror", 0, bin_syserror, 0, 1, 0, "e:p:", NULL), + BUILTIN("sysread", 0, bin_sysread, 0, 1, 0, "c:i:o:s:t:", NULL), + BUILTIN("syswrite", 0, bin_syswrite, 1, 1, 0, "c:o:", NULL), +}; + + +/* The load/unload routines required by the zsh library interface */ + +/**/ +int +setup_(Module m) +{ + return 0; +} + +/**/ +static void +tidyparam(Param pm) +{ + if (!pm) + return; + pm->flags &= ~PM_READONLY; + unsetparam_pm(pm, 0, 1); +} + + +/**/ +int +boot_(Module m) +{ + Param pm_nos; + + /* this takes care of an autoload on errnos */ + unsetparam("errnos"); + if (!(pm_nos = createparam("errnos", PM_ARRAY|PM_SPECIAL|PM_READONLY| + PM_HIDE|PM_HIDEVAL|PM_REMOVABLE))) + return 1; + pm_nos->gets.afn = errnosgetfn; + + if (!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab))) { + tidyparam(pm_nos); + return 1; + } + return 0; +} + + +/**/ +int +cleanup_(Module m) +{ + tidyparam((Param)paramtab->getnode(paramtab, "errnos")); + + deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); + return 0; +} + +/**/ +int +finish_(Module m) +{ + return 0; +} diff --git a/Src/Modules/system.mdd b/Src/Modules/system.mdd new file mode 100644 index 000000000..61950994a --- /dev/null +++ b/Src/Modules/system.mdd @@ -0,0 +1,27 @@ +name=zsh/system +link=dynamic +load=no + +autobins="sysread syswrite syserror" + +autoparams="errnos" + +objects="system.o errnames.o" + +headers="errcount.h" + +:<<\Make +errnames.c: errnames1.awk errnames2.awk $(dir_top)/config.h @ERRNO_H@ + if [ x@ERRNO_H@ = x ]; then \ + touch errtmp.out; \ + else \ + $(AWK) -f $(sdir)/errnames1.awk @ERRNO_H@ >errtmp.c; \ + $(CPP) errtmp.c >errtmp.out; \ + fi + $(AWK) -f $(sdir)/errnames2.awk errtmp.out > $@ + rm -f errtmp.c errtmp.out + +errcount.h: errnames.c + grep 'define.*ERRCOUNT' errnames.c > $@ +Make + diff --git a/zshconfig.ac b/zshconfig.ac index 01cc9a086..a9992c603 100644 --- a/zshconfig.ac +++ b/zshconfig.ac @@ -1117,6 +1117,39 @@ zsh_cv_path_signal_h=$SIGNAL_H SIGNAL_H=$zsh_cv_path_signal_h AC_SUBST(SIGNAL_H)dnl +dnl Where are error names located? Needed as input for errnames1.awk +AC_CACHE_CHECK(where error names are located, zsh_cv_path_errno_h, +[dnl Look at the output from the preprocessor. +dnl We should get lines of the form `# 1 "/usr/include/errno.h"' +dnl The following assumes the real definitions are in a file which +dnl contains the name `err'; we could relax this if necessary, +dnl but then you can get a rather long list of files to test. +dnl The backslash substitution is to persuade cygwin to cough up +dnl slashes rather than doubled backslashes in the path. +echo "#include " > nametmp.c +errfile_list="`$CPP nametmp.c | +sed -n 's/^#[ ].*\"\(.*\)\"/\1/p' | +sed 's/\\\\\\\\/\//g' | +$AWK '{ if (\$1 ~ \"err\") files[[\$1]] = \$1 } + END { for (var in files) print var }'`" +rm -f nametmp.c +for ERRNO_H in $errfile_list /dev/null +do + dnl Try to make sure it doesn't get confused by files that don't + dnl have real error definitions in. Count definitions to make sure. + nerrs=`test -f $ERRNO_H && \ + grep '#[ ]*define[ ][ ]*E[0-9A-Z]*[ ]*[0-9][0-9]*' $ERRNO_H | \ + wc -l | sed 's/[ ]//g'` + test "x$nerrs" != x && test "$nerrs" -ge 7 && break +done +if test $ERRNO_H = "/dev/null"; then + AC_MSG_ERROR(ERROR MACROS NOT FOUND: please report to developers) +fi +zsh_cv_path_errno_h=$ERRNO_H +]) +ERRNO_H=$zsh_cv_path_errno_h +AC_SUBST(ERRNO_H)dnl + dnl ----------------------------------------------------- dnl Look for the file containing the RLIMIT_* definitions dnl ----------------------------------------------------- -- cgit 1.4.1