1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-30 07:10:58 +02:00

zsh-3.1.5-pws-19

This commit is contained in:
Tanaka Akira 1999-05-19 13:10:41 +00:00
parent ea0ddb0fc6
commit 4fec788fa5
52 changed files with 1568 additions and 340 deletions

View file

@ -1,6 +1,6 @@
DISTFILES_SRC='
.distfiles
_brace_parameter _command_names _condition _default _equal
_long_options _match_pattern _match_test _math _parameter
_precommand _redirect _subscript _tilde _vars
_long_options _math _parameter _precommand _redirect _subscript
_tilde _vars
'

View file

@ -2,6 +2,6 @@ DISTFILES_SRC='
.distfiles
_aliases _arrays _autoload _bg_jobs _bindkey _builtin _cd _command
_dirs _disable _echotc _enable _fc _functions _hash _jobs _kill
_limits _sched _set _setopt _source _trap _unhash _unsetopt _vars_eq
_wait _which _zftp _zle _zmodload
_limits _sched _set _setopt _source _stat _trap _unhash _unsetopt
_vars_eq _wait _which _zftp _zle _zmodload
'

View file

@ -1,3 +1,3 @@
DISTFILES_SRC='
.distfiles _correct_filename _most_recent_file
.distfiles _correct_filename _correct_word _most_recent_file
'

View file

@ -222,7 +222,7 @@ for prepath in "$prepaths[@]"; do
# Get the matching files by globbing.
if [[ "$tpre$tsuf" = */* ]]; then
tmp1=( ${^tmp1}*(D/) )
tmp1=( ${^tmp1}*(-D/) )
else
tmp1=( ${^tmp1}${^~pats} )
fi

View file

@ -27,5 +27,5 @@
# This must also serve as a shell script, so do not add spaces around the
# `=' signs.
VERSION=3.1.5-pws-18
VERSION_DATE='May 8, 1999'
VERSION=3.1.5-pws-19
VERSION_DATE='May 19, 1999'

View file

@ -2,11 +2,13 @@ DISTFILES_SRC='
.cvsignore .distfiles Makefile.in
META-FAQ.yo intro.ms
version.yo zmacros.yo zman.yo ztexi.yo
zsh.yo zshbuiltins.yo zshcompctl.yo zshexpn.yo zshmisc.yo
zshmodules.yo zshoptions.yo zshparam.yo zshzle.yo
zsh.yo zshbuiltins.yo zshcompctl.yo zshcompsys.yo zshcompwid.yo
zshexpn.yo zshmisc.yo zshmodules.yo zshoptions.yo zshparam.yo
zshzftpsys.yo zshzle.yo
zsh.texi
zsh.1 zshbuiltins.1 zshcompctl.1 zshexpn.1 zshmisc.1 zshmodules.1
zshoptions.1 zshparam.1 zshzle.1 zshall.1
zsh.1 zshbuiltins.1 zshcompctl.1 zshcompsys.1 zshcompwid.1
zshexpn.1 zshmisc.1 zshmodules.1 zshoptions.1 zshparam.1
zshzftpsys.1 zshzle.1 zshall.1
'
DISTFILES_DOC='

View file

@ -1,9 +1,10 @@
DISTFILES_SRC='
.distfiles
arith.yo builtins.yo compat.yo compctl.yo compwid.yo cond.yo exec.yo
expn.yo filelist.yo files.yo func.yo grammar.yo guide.yo index.yo intro.yo
invoke.yo jobs.yo metafaq.yo mod_cap.yo mod_clone.yo mod_comp1.yo
mod_compctl.yo mod_deltochar.yo mod_example.yo mod_files.yo mod_sched.yo
arith.yo builtins.yo compat.yo compctl.yo compsys.yo compwid.yo
cond.yo exec.yo expn.yo filelist.yo files.yo func.yo grammar.yo
guide.yo index.yo intro.yo invoke.yo jobs.yo metafaq.yo mod_cap.yo
mod_clone.yo mod_comp1.yo mod_compctl.yo mod_deltochar.yo
mod_example.yo mod_files.yo mod_parameter.yo mod_sched.yo
mod_stat.yo mod_zftp.yo mod_zle.yo modules.yo options.yo params.yo
prompt.yo redirect.yo restricted.yo seealso.yo zle.yo
prompt.yo redirect.yo restricted.yo seealso.yo zftpsys.yo zle.yo
'

View file

@ -7,7 +7,19 @@ cindex(compatibility)
cindex(sh, compatibility)
cindex(ksh, compatibility)
Zsh tries to emulate bf(sh) or bf(ksh) when it is invoked as
tt(sh) or tt(ksh) respectively. In this mode the following
tt(sh) or tt(ksh) respectively. More precisely, it looks at the first
letter of the name passed to it, which may not necessarily be the
name of the executable file, ignoring any initial `tt(-)' as well as
`tt(r)' (for restricted); an `tt(s)' or `tt(b)' will force
bf(sh) compatibility, while `tt(k)' will force bf(ksh) compatibility. An
exception is if the name excluding any `tt(-)' is tt(su), in which case
the environment variable tt(SHELL) will be used to test the emulation;
this is to workaround a problem under some operating systems where the
tt(su) command does not change the name when executing a user shell. Note
that, from within zsh itself, this mechanism can be invoked by `tt(ARGV0=sh
zsh ...)'.
In this emulation mode, the following
parameters are not special and not initialized by the shell:
tt(ARGC),
tt(argv),

View file

@ -1,4 +1,4 @@
texinode(The files Module)(The sched Module)(The example Module)(Zsh Modules)
texinode(The files Module)(The parameter Module)(The example Module)(Zsh Modules)
sect(The files Module)
cindex(files, manipulating)
The tt(files) module makes some standard commands available as builtins:

49
Doc/Zsh/mod_parameter.yo Normal file
View file

@ -0,0 +1,49 @@
texinode(The parameter Module)(The sched Module)(The files Module)(Zsh Modules)
sect(The parameter Module)
cindex(parameters, special)
The tt(parameter) module gives access to some of the internal hash
tables used by the shell, by defining four special associative arrays.
startitem()
vindex(options)
item(tt(options))(
The keys for this associative array are the names of the options that
can be set and unset using the tt(setopt) and tt(unsetopt)
builtins. The value of each key is either the string tt(on) if the
option is currently set, or the string tt(off) if the option is unset.
Setting a key to one of these strings is like setting or unsetting
the option, respectively. Unsetting a key in this array is like
setting it to the value tt(off).
)
vindex(commands)
item(tt(command))(
This array gives access to the command hash table. The keys are the
names of external commands, the values are the pathnames of the files
that would be executed when the command would be invoked. Setting a
key in this array defines a new entry in this table in the same way as
with the tt(hash) builtin. Unsetting a key as in `tt(unset
"commands[foo]")' removes the entry for the given key from the command
hash table.
)
vindex(functions)
item(tt(functions))(
This association maps function names to their definitions. Setting a
key in it is like defining a function with the name given by the key
and the body given by the value. Unsetting a key removes the
definition for the function named by the key.
)
vindex(parameters)
item(tt(parameters))(
The keys in this associative array are the names of the parameters
currently defined. The values are strings describing the type of the
parameter, in the same format used by the tt(t) parameter flag, see
ifzman(\
zmanref(zshexpn)
)\
ifnzman(\
noderef(Parameter Expansion)
)\
.
Setting or unsetting keys in this array is not possible.
)
enditem()

View file

@ -1,4 +1,4 @@
texinode(The sched Module)(The stat Module)(The files Module)(Zsh Modules)
texinode(The sched Module)(The stat Module)(The parameter Module)(Zsh Modules)
sect(The sched Module)
The tt(sched) module makes available one builtin command:

View file

@ -31,6 +31,9 @@ An example of how to write a module.
item(tt(files))(
Some basic file manipulation commands as builtins.
)
item(tt(parameter))(
Access to internal hash tables via special associative arrays.
)
item(tt(sched))(
A builtin that provides a timed execution facility within the shell.
)
@ -52,6 +55,7 @@ menu(The compctl Module)
menu(The deltochar Module)
menu(The example Module)
menu(The files Module)
menu(The parameter Module)
menu(The sched Module)
menu(The stat Module)
menu(The zftp Module)
@ -64,6 +68,7 @@ includefile(Zsh/mod_compctl.yo)
includefile(Zsh/mod_deltochar.yo)
includefile(Zsh/mod_example.yo)
includefile(Zsh/mod_files.yo)
includefile(Zsh/mod_parameter.yo)
includefile(Zsh/mod_sched.yo)
includefile(Zsh/mod_stat.yo)
includefile(Zsh/mod_zftp.yo)

View file

@ -479,9 +479,9 @@ of tt(exit) or tt(logout) instead.
However, ten consecutive EOFs will cause the shell to exit anyway,
to avoid the shell hanging if its tty goes away.
)
pindex(INCREMENTAL_APPEND_HISTORY)
pindex(INC_APPEND_HISTORY)
cindex(history, incremental appending to a file)
item(tt(INCREMENTAL_APPEND_HISTORY))(
item(tt(INC_APPEND_HISTORY))(
This options works like APPEND_HISTORY except that new history lines
are added to the tt($HISTFILE) when they finish running, rather than
waiting until the shell is killed. The file is periodically trimmed

27
INSTALL
View file

@ -202,6 +202,32 @@ Any startup/shutdown script can be disabled by giving the
--disable-scriptname option to "configure". The --disable-etcdir option
disables all startup/shutdown files which are not explicitely enabled.
Support for large files and integers
------------------------------------
Some 32-bit systems allow special compilation modes to get around the 2GB
file size barrier; the zsh support for this is still experimental, and
feedback is particularly appreciated. The option --enable-lfs turns on the
configure check for support for large files. Not all systems recognize the
test used by zsh (via the getconf command), so flags may need to be set by
hand, but --enable-lfs should be used in any case to compile in the code
for using 64 bit integers. On HP-UX 10.20, zsh has been successfully
compiled with large file support by configuring with
CC="cc -Ae" CPPFLAGS="-D_LARGEFILE_SOURCE -D_FILE64" configure \
--enable-lfs ...
You can also give a value to --enable-lfs, which will be interpreted as the
name of a 64-bit integer type, for example --enable-lfs="long long"
(although this type is checked for anyway).
Furthermore, use of --enable-lfs will also enable 64-bit arithmetic for
shell parameters, and anywhere they are used such as in mathematical
formulae. This depends only on the shell finding a suitable 64-bit integer
type; it does not require that support for large files is actually
enabled. Hence you might consider using --enable-lfs on any 32-bit system
with a suitable compiler such as gcc.
None of this is relevant for 64-bit systems; zsh should compile and run
without problems if (sizeof(long) == 8).
Options For Configure
---------------------
@ -244,3 +270,4 @@ Features:
zprofile=pathname # the full pathname of the global zprofile script
zlogout=pathname # the full pathname of the global zlogout script
dynamic # allow dynamically loaded binary modules
lfs # allow configure check for large files

View file

@ -112,9 +112,15 @@ showlimits(int hard, int lim)
else
printf("%lldkB\n", val / 1024L);
# else
# ifdef RLIM_T_IS_UNSIGNED
printf("%luMB\n", val / (1024L * 1024L));
else
printf("%lukB\n", val / 1024L);
# else
printf("%ldMB\n", val / (1024L * 1024L));
else
printf("%ldkB\n", val / 1024L);
# endif /* RLIM_T_IS_UNSIGNED */
# endif /* RLIM_T_IS_LONG_LONG */
# endif /* RLIM_T_IS_QUAD_T */
}

View file

@ -4,6 +4,7 @@ DISTFILES_SRC='
clone.mdd clone.c
example.mdd example.c
files.mdd files.c
parameter.mdd parameter.c
stat.mdd stat.c
zftp.mdd zftp.c
'

View file

@ -32,7 +32,7 @@
/* parameters */
static long intparam;
static zlong intparam;
static char *strparam;
static char **arrparam;
@ -55,7 +55,11 @@ bin_example(char *nam, char **args, char *ops, int func)
fputs(*args, stdout);
}
printf("\nName: %s\n", nam);
#ifdef ZSH_64_BIT_TYPE
printf("\nInteger Parameter: %s\n", output64(intparam));
#else
printf("\nInteger Parameter: %ld\n", intparam);
#endif
printf("String Parameter: %s\n", strparam ? strparam : "");
printf("Array Parameter:");
if (p)
@ -79,7 +83,7 @@ cond_p_len(char **a, int id)
char *s1 = cond_str(a, 0);
if (a[1]) {
long v = cond_val(a, 1);
zlong v = cond_val(a, 1);
return strlen(s1) == v;
} else {

662
Src/Modules/parameter.c Normal file
View file

@ -0,0 +1,662 @@
/*
* parameter.c - parameter interface to zsh internals
*
* This file is part of zsh, the Z shell.
*
* Copyright (c) 1999 Sven Wischnowsky
* 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 Sven Wischnowsky 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 Sven Wischnowsky and the Zsh Development Group have been advised of
* the possibility of such damage.
*
* Sven Wischnowsky 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 Sven Wischnowsky and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
*
*/
#include "parameter.mdh"
#include "parameter.pro"
/* Empty dummy function for special hash parameters. */
/**/
static void
shempty(void)
{
}
/* Create a simple special hash parameter. */
/**/
static Param
createspecialhash(char *name, GetNodeFunc get, ScanTabFunc scan)
{
Param pm;
HashTable ht;
if (!(pm = createparam(name, PM_SPECIAL|PM_REMOVABLE|PM_HASHED)))
return NULL;
pm->level = pm->old ? locallevel : 0;
pm->gets.hfn = hashgetfn;
pm->sets.hfn = hashsetfn;
pm->unsetfn = stdunsetfn;
pm->u.hash = ht = newhashtable(7, name, NULL);
ht->hash = hasher;
ht->emptytable = (TableFunc) shempty;
ht->filltable = NULL;
ht->addnode = (AddNodeFunc) shempty;
ht->getnode = ht->getnode2 = get;
ht->removenode = (RemoveNodeFunc) shempty;
ht->disablenode = NULL;
ht->enablenode = NULL;
ht->freenode = (FreeNodeFunc) shempty;
ht->printnode = printparamnode;
ht->scantab = scan;
return pm;
}
/* Functions for the parameters special parameter. */
/* Return a string describing the type of a parameter. */
/**/
static char *
paramtypestr(Param pm)
{
char *val = NULL;
int f = pm->flags;
if (!(f & PM_UNSET)) {
switch (PM_TYPE(f)) {
case PM_SCALAR: val = "scalar"; break;
case PM_ARRAY: val = "array"; break;
case PM_INTEGER: val = "integer"; break;
case PM_HASHED: val = "association"; break;
}
DPUTS(!val, "BUG: type not handled in parameter");
val = dupstring(val);
if (f & PM_LEFT)
val = dyncat(val, "-left");
if (f & PM_RIGHT_B)
val = dyncat(val, "-right_blanks");
if (f & PM_RIGHT_Z)
val = dyncat(val, "-right_zeros");
if (f & PM_LOWER)
val = dyncat(val, "-lower");
if (f & PM_UPPER)
val = dyncat(val, "-upper");
if (f & PM_READONLY)
val = dyncat(val, "-readonly");
if (f & PM_TAGGED)
val = dyncat(val, "-tag");
if (f & PM_EXPORTED)
val = dyncat(val, "-export");
if (f & PM_UNIQUE)
val = dyncat(val, "-unique");
} else
val = dupstring("");
return val;
}
/**/
static HashNode
getpmparameter(HashTable ht, char *name)
{
Param rpm, pm = NULL;
HEAPALLOC {
pm = (Param) zhalloc(sizeof(struct param));
pm->nam = dupstring(name);
pm->flags = PM_SCALAR | PM_READONLY;
pm->sets.cfn = NULL;
pm->gets.cfn = strgetfn;
pm->unsetfn = NULL;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if ((rpm = (Param) realparamtab->getnode(realparamtab, name)) &&
!(rpm->flags & PM_UNSET))
pm->u.str = paramtypestr(rpm);
else {
pm->u.str = "";
pm->flags |= PM_UNSET;
}
} LASTALLOC;
return (HashNode) pm;
}
/**/
static void
scanpmparameters(HashTable ht, ScanFunc func, int flags)
{
struct param pm;
int i;
HashNode hn;
pm.flags = PM_SCALAR | PM_READONLY;
pm.sets.cfn = NULL;
pm.gets.cfn = strgetfn;
pm.unsetfn = NULL;
pm.ct = 0;
pm.env = NULL;
pm.ename = NULL;
pm.old = NULL;
pm.level = 0;
for (i = 0; i < realparamtab->hsize; i++)
for (hn = realparamtab->nodes[i]; hn; hn = hn->next) {
pm.nam = hn->nam;
if (func != scancountparams)
pm.u.str = paramtypestr((Param) hn);
func((HashNode) &pm, flags);
}
}
/* Functions for the commands special parameter. */
/**/
static void
setpmcommand(Param pm, char *value)
{
if (isset(RESTRICTED))
zwarnnam(NULL, "restricted: %s", value, 0);
else {
Cmdnam cn = zcalloc(sizeof(*cn));
cn->flags = HASHED;
cn->u.cmd = ztrdup(value);
cmdnamtab->addnode(cmdnamtab, ztrdup(pm->nam), (HashNode) cn);
}
}
/**/
static void
unsetpmcommand(Param pm, int exp)
{
HashNode hn = cmdnamtab->removenode(cmdnamtab, pm->nam);
if (hn)
cmdnamtab->freenode(hn);
}
/**/
static void
setpmcommands(Param pm, HashTable ht)
{
int i;
HashNode hn;
for (i = 0; i < ht->hsize; i++)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
Cmdnam cn = zcalloc(sizeof(*cn));
struct value v;
v.isarr = v.inv = v.a = 0;
v.b = -1;
v.arr = NULL;
v.pm = (Param) hn;
cn->flags = HASHED;
cn->u.cmd = ztrdup(getstrvalue(&v));
cmdnamtab->addnode(cmdnamtab, ztrdup(hn->nam), (HashNode) cn);
}
}
/**/
static HashNode
getpmcommand(HashTable ht, char *name)
{
Cmdnam cmd;
Param pm = NULL;
if (!(cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name)) &&
isset(HASHLISTALL)) {
cmdnamtab->filltable(cmdnamtab);
cmd = (Cmdnam) cmdnamtab->getnode(cmdnamtab, name);
}
HEAPALLOC {
pm = (Param) zhalloc(sizeof(struct param));
pm->nam = dupstring(name);
pm->flags = PM_SCALAR;
pm->sets.cfn = setpmcommand;
pm->gets.cfn = strgetfn;
pm->unsetfn = unsetpmcommand;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if (cmd) {
if (cmd->flags & HASHED)
pm->u.str = cmd->u.cmd;
else {
pm->u.str = zhalloc(strlen(*(cmd->u.name)) +
strlen(name) + 2);
strcpy(pm->u.str, *(cmd->u.name));
strcat(pm->u.str, "/");
strcat(pm->u.str, name);
}
} else {
pm->u.str = "";
pm->flags |= PM_UNSET;
}
} LASTALLOC;
return (HashNode) pm;
}
/**/
static void
scanpmcommands(HashTable ht, ScanFunc func, int flags)
{
struct param pm;
int i;
HashNode hn;
Cmdnam cmd;
if (isset(HASHLISTALL))
cmdnamtab->filltable(cmdnamtab);
pm.flags = PM_SCALAR;
pm.sets.cfn = setpmcommand;
pm.gets.cfn = strgetfn;
pm.unsetfn = unsetpmcommand;
pm.ct = 0;
pm.env = NULL;
pm.ename = NULL;
pm.old = NULL;
pm.level = 0;
for (i = 0; i < cmdnamtab->hsize; i++)
for (hn = cmdnamtab->nodes[i]; hn; hn = hn->next) {
pm.nam = hn->nam;
cmd = (Cmdnam) hn;
if (func != scancountparams) {
if (cmd->flags & HASHED)
pm.u.str = cmd->u.cmd;
else {
pm.u.str = zhalloc(strlen(*(cmd->u.name)) +
strlen(cmd->nam) + 2);
strcpy(pm.u.str, *(cmd->u.name));
strcat(pm.u.str, "/");
strcat(pm.u.str, cmd->nam);
}
}
func((HashNode) &pm, flags);
}
}
/* Functions for the functions special parameter. */
/**/
static void
setfunction(char *name, char *value)
{
char *val;
Shfunc shf;
List list;
int sn;
val = ztrdup(value);
val = metafy(val, strlen(val), META_REALLOC);
HEAPALLOC {
list = parse_string(val);
} LASTALLOC;
if (!list || list == &dummy_list) {
zwarnnam(NULL, "invalid function definition", val, 0);
zsfree(val);
return;
}
PERMALLOC {
shf = (Shfunc) zalloc(sizeof(*shf));
shf->funcdef = (List) dupstruct(list);
shf->flags = 0;
if (!strncmp(name, "TRAP", 4) &&
(sn = getsignum(name + 4)) != -1) {
if (settrap(sn, shf->funcdef)) {
freestruct(shf->funcdef);
zfree(shf, sizeof(*shf));
zsfree(val);
LASTALLOC_RETURN;
}
sigtrapped[sn] |= ZSIG_FUNC;
}
shfunctab->addnode(shfunctab, ztrdup(name), shf);
} LASTALLOC;
zsfree(val);
}
/**/
static void
setpmfunction(Param pm, char *value)
{
setfunction(pm->nam, value);
}
/**/
static void
unsetpmfunction(Param pm, int exp)
{
HashNode hn = shfunctab->removenode(shfunctab, pm->nam);
if (hn)
shfunctab->freenode(hn);
}
/**/
static void
setpmfunctions(Param pm, HashTable ht)
{
int i;
HashNode hn;
for (i = 0; i < ht->hsize; i++)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
struct value v;
v.isarr = v.inv = v.a = 0;
v.b = -1;
v.arr = NULL;
v.pm = (Param) hn;
setfunction(hn->nam, getstrvalue(&v));
}
}
/**/
static HashNode
getpmfunction(HashTable ht, char *name)
{
Shfunc shf;
Param pm = NULL;
HEAPALLOC {
pm = (Param) zhalloc(sizeof(struct param));
pm->nam = dupstring(name);
pm->flags = PM_SCALAR;
pm->sets.cfn = setpmfunction;
pm->gets.cfn = strgetfn;
pm->unsetfn = unsetpmfunction;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if ((shf = (Shfunc) shfunctab->getnode(shfunctab, name))) {
if (shf->flags & PM_UNDEFINED)
pm->u.str = "undefined";
else {
char *t = getpermtext((void *) dupstruct((void *)
shf->funcdef)), *h;
h = dupstring(t);
zsfree(t);
unmetafy(h, NULL);
pm->u.str = h;
}
} else {
pm->u.str = "";
pm->flags |= PM_UNSET;
}
} LASTALLOC;
return (HashNode) pm;
}
/**/
static void
scanpmfunctions(HashTable ht, ScanFunc func, int flags)
{
struct param pm;
int i;
HashNode hn;
pm.flags = PM_SCALAR;
pm.sets.cfn = setpmcommand;
pm.gets.cfn = strgetfn;
pm.unsetfn = unsetpmcommand;
pm.ct = 0;
pm.env = NULL;
pm.ename = NULL;
pm.old = NULL;
pm.level = 0;
for (i = 0; i < shfunctab->hsize; i++)
for (hn = shfunctab->nodes[i]; hn; hn = hn->next) {
if (!(hn->flags & DISABLED)) {
pm.nam = hn->nam;
if (func != scancountparams) {
if (((Shfunc) hn)->flags & PM_UNDEFINED)
pm.u.str = "undefined";
else {
char *t = getpermtext((void *)
dupstruct((void *) ((Shfunc) hn)->funcdef));
unmetafy((pm.u.str = dupstring(t)), NULL);
zsfree(t);
}
}
func((HashNode) &pm, flags);
}
}
}
/* Functions for the options special parameter. */
/**/
static void
setpmoption(Param pm, char *value)
{
int n;
if (!value || (strcmp(value, "on") && strcmp(value, "off")))
zwarnnam(NULL, "invalid value: %s", value, 0);
else if (!(n = optlookup(pm->nam)))
zwarnnam(NULL, "no such option: %s", pm->nam, 0);
else if (dosetopt(n, (value && strcmp(value, "off")), 0))
zwarnnam(NULL, "can't change option: %s", pm->nam, 0);
}
/**/
static void
unsetpmoption(Param pm, int exp)
{
int n;
if (!(n = optlookup(pm->nam)))
zwarnnam(NULL, "no such option: %s", pm->nam, 0);
else if (dosetopt(n, 0, 0))
zwarnnam(NULL, "can't change option: %s", pm->nam, 0);
}
/**/
static void
setpmoptions(Param pm, HashTable ht)
{
int i;
HashNode hn;
for (i = 0; i < ht->hsize; i++)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
struct value v;
char *val;
v.isarr = v.inv = v.a = 0;
v.b = -1;
v.arr = NULL;
v.pm = (Param) hn;
val = getstrvalue(&v);
if (!val || (strcmp(val, "on") && strcmp(val, "off")))
zwarnnam(NULL, "invalid value: %s", val, 0);
else if (dosetopt(optlookup(hn->nam),
(val && strcmp(val, "off")), 0))
zwarnnam(NULL, "can't change option: %s", hn->nam, 0);
}
}
/**/
static HashNode
getpmoption(HashTable ht, char *name)
{
Param pm = NULL;
int n;
HEAPALLOC {
pm = (Param) zhalloc(sizeof(struct param));
pm->nam = dupstring(name);
pm->flags = PM_SCALAR;
pm->sets.cfn = setpmoption;
pm->gets.cfn = strgetfn;
pm->unsetfn = unsetpmoption;
pm->ct = 0;
pm->env = NULL;
pm->ename = NULL;
pm->old = NULL;
pm->level = 0;
if ((n = optlookup(name)))
pm->u.str = dupstring(opts[n] ? "on" : "off");
else {
pm->u.str = "";
pm->flags |= PM_UNSET;
}
} LASTALLOC;
return (HashNode) pm;
}
/**/
static void
scanpmoptions(HashTable ht, ScanFunc func, int flags)
{
struct param pm;
int i;
HashNode hn;
pm.flags = PM_SCALAR;
pm.sets.cfn = setpmoption;
pm.gets.cfn = strgetfn;
pm.unsetfn = unsetpmoption;
pm.ct = 0;
pm.env = NULL;
pm.ename = NULL;
pm.old = NULL;
pm.level = 0;
for (i = 0; i < optiontab->hsize; i++)
for (hn = optiontab->nodes[i]; hn; hn = hn->next) {
pm.nam = hn->nam;
pm.u.str = opts[((Optname) hn)->optno] ? "on" : "off";
func((HashNode) &pm, flags);
}
}
/* Names and Params for the special parameters. */
#define PAR_NAM "parameters"
#define CMD_NAM "commands"
#define FUN_NAM "functions"
#define OPT_NAM "options"
static Param parpm, cmdpm, funpm, optpm;
/**/
int
setup_parameter(Module m)
{
return 0;
}
/**/
int
boot_parameter(Module m)
{
/* Create the special associative arrays.
* As an example for autoloaded parameters, this is probably a bad
* example, because we the zsh core doesn't support creation of
* special hashes, yet. */
unsetparam(PAR_NAM);
if (!(parpm = createspecialhash(PAR_NAM, getpmparameter,
scanpmparameters)))
return 1;
parpm->flags |= PM_READONLY;
unsetparam(CMD_NAM);
if (!(cmdpm = createspecialhash(CMD_NAM, getpmcommand,
scanpmcommands)))
return 1;
cmdpm->sets.hfn = setpmcommands;
unsetparam(FUN_NAM);
if (!(funpm = createspecialhash(FUN_NAM, getpmfunction,
scanpmfunctions)))
return 1;
funpm->sets.hfn = setpmfunctions;
unsetparam(OPT_NAM);
if (!(optpm = createspecialhash(OPT_NAM, getpmoption,
scanpmoptions)))
return 1;
optpm->sets.hfn = setpmoptions;
return 0;
}
#ifdef MODULE
/**/
int
cleanup_parameter(Module m)
{
Param pm;
/* Remove the special parameters if they are still the same. */
if ((pm = (Param) paramtab->getnode(paramtab, PAR_NAM)) && pm == parpm) {
pm->flags &= ~PM_READONLY;
unsetparam_pm(pm, 0, 1);
}
if ((pm = (Param) paramtab->getnode(paramtab, CMD_NAM)) && pm == cmdpm)
unsetparam_pm(pm, 0, 1);
if ((pm = (Param) paramtab->getnode(paramtab, FUN_NAM)) && pm == funpm)
unsetparam_pm(pm, 0, 1);
if ((pm = (Param) paramtab->getnode(paramtab, OPT_NAM)) && pm == optpm)
unsetparam_pm(pm, 0, 1);
return 0;
}
/**/
int
finish_parameter(Module m)
{
return 0;
}
#endif

View file

@ -0,0 +1,3 @@
autoparams="parameters commands functions options"
objects="parameter.o"

View file

@ -213,7 +213,13 @@ statprint(struct stat *sbuf, char *outbuf, char *fname, int iwhich, int flags)
break;
case ST_INO:
#ifdef INO_T_IS_64_BIT
convbase(optr, sbuf->st_ino, 0);
#else
DPUTS(sizeof(sbuf->st_ino) > 4,
"Shell compiled with wrong ino_t size");
statulprint((unsigned long)sbuf->st_ino, optr);
#endif
break;
case ST_MODE:
@ -237,7 +243,13 @@ statprint(struct stat *sbuf, char *outbuf, char *fname, int iwhich, int flags)
break;
case ST_SIZE:
#ifdef OFF_T_IS_64_BIT
convbase(optr, sbuf->st_size, 0);
#else
DPUTS(sizeof(sbuf->st_size) > 4,
"Shell compiled with wrong off_t size");
statulprint((unsigned long)sbuf->st_size, optr);
#endif
break;
case ST_ATIM:

View file

@ -117,7 +117,7 @@ enum {
ZFHD_EORB = 128 /* block is end of file */
};
typedef int (*readwrite_t)(int, char *, size_t, int);
typedef int (*readwrite_t)(int, char *, off_t, int);
struct zftpcmd {
const char *nam;
@ -195,7 +195,7 @@ static char *zfparams[] = {
enum {
ZFPM_READONLY = 0x01, /* make parameter readonly */
ZFPM_IFUNSET = 0x02, /* only set if not already set */
ZFPM_INTEGER = 0x04 /* passed pointer to long */
ZFPM_INTEGER = 0x04 /* passed pointer to off_t */
};
/*
@ -250,25 +250,26 @@ static int zfhas_size, zfhas_mdtm;
* --- we don't try to track it because it's too complicated.
*/
enum {
ZFST_ASCI = 0x00, /* type for next transfer is ASCII */
ZFST_IMAG = 0x01, /* type for next transfer is image */
ZFST_ASCI = 0x0000, /* type for next transfer is ASCII */
ZFST_IMAG = 0x0001, /* type for next transfer is image */
ZFST_TMSK = 0x01, /* mask for type flags */
ZFST_TBIT = 0x01, /* number of bits in type flags */
ZFST_TMSK = 0x0001, /* mask for type flags */
ZFST_TBIT = 0x0001, /* number of bits in type flags */
ZFST_CASC = 0x00, /* current type is ASCII - default */
ZFST_CIMA = 0x02, /* current type is image */
ZFST_CASC = 0x0000, /* current type is ASCII - default */
ZFST_CIMA = 0x0002, /* current type is image */
ZFST_STRE = 0x00, /* stream mode - default */
ZFST_BLOC = 0x04, /* block mode */
ZFST_STRE = 0x0000, /* stream mode - default */
ZFST_BLOC = 0x0004, /* block mode */
ZFST_MMSK = 0x04, /* mask for mode flags */
ZFST_MMSK = 0x0004, /* mask for mode flags */
ZFST_LOGI = 0x08, /* user logged in */
ZFST_NOPS = 0x10, /* server doesn't understand PASV */
ZFST_NOSZ = 0x20, /* server doesn't send `(XXXX bytes)' reply */
ZFST_TRSZ = 0x40, /* tried getting 'size' from reply */
ZFST_CLOS = 0x80 /* connection closed */
ZFST_LOGI = 0x0008, /* user logged in */
ZFST_SYST = 0x0010, /* done system type check */
ZFST_NOPS = 0x0020, /* server doesn't understand PASV */
ZFST_NOSZ = 0x0040, /* server doesn't send `(XXXX bytes)' reply */
ZFST_TRSZ = 0x0080, /* tried getting 'size' from reply */
ZFST_CLOS = 0x0100 /* connection closed */
};
#define ZFST_TYPE(x) (x & ZFST_TMSK)
/*
@ -461,7 +462,7 @@ zfmovefd(int fd)
* set a non-special parameter.
* if ZFPM_IFUNSET, don't set if it already exists.
* if ZFPM_READONLY, make it readonly, but only when creating it.
* if ZFPM_INTEGER, val pointer is to long (NB not int), don't free.
* if ZFPM_INTEGER, val pointer is to off_t (NB not int), don't free.
*/
/**/
static void
@ -488,7 +489,7 @@ zfsetparam(char *name, void *val, int flags)
return;
}
if (type == PM_INTEGER)
pm->sets.ifn(pm, *(long *)val);
pm->sets.ifn(pm, *(off_t *)val);
else
pm->sets.cfn(pm, (char *)val);
}
@ -1009,7 +1010,7 @@ zfgetdata(char *name, char *rest, char *cmd, int getsize)
if (isdigit(STOUC(*ptr))) {
zfstatus &= ~ZFST_NOSZ;
if (getsize) {
long sz = zstrtol(ptr, NULL, 10);
off_t sz = zstrtol(ptr, NULL, 10);
zfsetparam("ZFTP_SIZE", &sz, ZFPM_READONLY|ZFPM_INTEGER);
}
}
@ -1090,9 +1091,9 @@ zfgetdata(char *name, char *rest, char *cmd, int getsize)
/**/
static int
zfstats(char *fnam, int remote, long *retsize, char **retmdtm, int fd)
zfstats(char *fnam, int remote, off_t *retsize, char **retmdtm, int fd)
{
long sz = -1;
off_t sz = -1;
char *mt = NULL;
int ret;
@ -1151,7 +1152,7 @@ zfstats(char *fnam, int remote, long *retsize, char **retmdtm, int fd)
if ((fd == -1 ? stat(fnam, &statbuf) : fstat(fd, &statbuf)) < 0)
return 1;
/* make sure it's long, since this has to be a pointer */
/* make sure it's off_t, since this has to be a pointer */
sz = statbuf.st_size;
if (retmdtm) {
@ -1179,9 +1180,9 @@ zfstats(char *fnam, int remote, long *retsize, char **retmdtm, int fd)
/**/
static void
zfstarttrans(char *nam, int recv, long sz)
zfstarttrans(char *nam, int recv, off_t sz)
{
long cnt = 0;
off_t cnt = 0;
/*
* sz = -1 signifies error getting size. don't set ZFTP_SIZE if sz is
* zero, either: it probably came from an fstat() on a pipe, so it
@ -1210,7 +1211,7 @@ zfendtrans()
/**/
static int
zfread(int fd, char *bf, size_t sz, int tmout)
zfread(int fd, char *bf, off_t sz, int tmout)
{
int ret;
@ -1235,7 +1236,7 @@ zfread(int fd, char *bf, size_t sz, int tmout)
/**/
static int
zfwrite(int fd, char *bf, size_t sz, int tmout)
zfwrite(int fd, char *bf, off_t sz, int tmout)
{
int ret;
@ -1262,11 +1263,11 @@ static int zfread_eof;
/**/
static int
zfread_block(int fd, char *bf, size_t sz, int tmout)
zfread_block(int fd, char *bf, off_t sz, int tmout)
{
int n;
struct zfheader hdr;
size_t blksz, cnt;
off_t blksz, cnt;
char *bfptr;
do {
/* we need the header */
@ -1314,11 +1315,11 @@ zfread_block(int fd, char *bf, size_t sz, int tmout)
/**/
static int
zfwrite_block(int fd, char *bf, size_t sz, int tmout)
zfwrite_block(int fd, char *bf, off_t sz, int tmout)
{
int n;
struct zfheader hdr;
size_t cnt;
off_t cnt;
char *bfptr;
/* we need the header */
do {
@ -1359,7 +1360,7 @@ zfwrite_block(int fd, char *bf, size_t sz, int tmout)
/**/
static int
zfsenddata(char *name, int recv, int progress, long startat)
zfsenddata(char *name, int recv, int progress, off_t startat)
{
#define ZF_BUFSIZE 32768
#define ZF_ASCSIZE (ZF_BUFSIZE/2)
@ -1367,7 +1368,7 @@ zfsenddata(char *name, int recv, int progress, long startat)
int n, ret = 0, gotack = 0, fdin, fdout, fromasc = 0, toasc = 0;
int rtmout = 0, wtmout = 0;
char lsbuf[ZF_BUFSIZE], *ascbuf = NULL, *optr;
long sofar = 0, last_sofar = 0;
off_t sofar = 0, last_sofar = 0;
readwrite_t read_ptr = zfread, write_ptr = zfwrite;
List l;
@ -1598,7 +1599,7 @@ zftp_open(char *name, char **args, int flags)
struct protoent *zprotop;
struct servent *zservp;
struct hostent *zhostp = NULL;
char **addrp, tbuf[2] = "X", *fname;
char **addrp, *fname;
int err, len, tmout;
if (!*args) {
@ -1802,32 +1803,11 @@ zftp_open(char *name, char **args, int flags)
#endif
unlink(fname);
/* now find out what system we're connected to */
if (!(zfprefs & ZFPF_DUMB) && zfsendcmd("SYST\r\n") == 2) {
char *ptr = lastmsg, *eptr, *systype;
for (eptr = ptr; *eptr; eptr++)
;
systype = ztrduppfx(ptr, eptr-ptr);
if (!strncmp(systype, "UNIX Type: L8", 13)) {
/*
* Use binary for transfers. This simple test saves much
* hassle for all concerned, particularly me.
*/
zfstatus |= ZFST_IMAG;
zfis_unix = 1;
}
/*
* we could set zfis_unix based just on the UNIX part,
* but I don't really know the consequences of that.
*/
zfsetparam("ZFTP_SYSTEM", systype, ZFPM_READONLY);
} else if (zcfd == -1) {
if (zcfd == -1) {
/* final paranoid check */
return 1;
}
tbuf[0] = (ZFST_TYPE(zfstatus) == ZFST_ASCI) ? 'A' : 'I';
zfsetparam("ZFTP_TYPE", ztrdup(tbuf), ZFPM_READONLY);
zfsetparam("ZFTP_MODE", ztrdup("S"), ZFPM_READONLY);
/* if remaining arguments, use them to log in. */
if (zcfd > -1 && *++args)
@ -1964,7 +1944,7 @@ static int
zftp_login(char *name, char **args, int flags)
{
char *ucmd, *passwd = NULL, *acct = NULL;
char *user;
char *user, tbuf[2] = "X";
int stopit;
if ((zfstatus & ZFST_LOGI) && zfsendcmd("REIN\r\n") >= 4)
@ -2044,6 +2024,36 @@ zftp_login(char *name, char **args, int flags)
if (acct)
zfsetparam("ZFTP_ACCOUNT", ztrdup(acct), ZFPM_READONLY);
/*
* Now find out what system we're connected to. Some systems
* won't let us do this until we're logged in; it's fairly safe
* to delay it here for all systems.
*/
if (!(zfprefs & ZFPF_DUMB) && !(zfstatus & ZFST_SYST)) {
if (zfsendcmd("SYST\r\n") == 2) {
char *ptr = lastmsg, *eptr, *systype;
for (eptr = ptr; *eptr; eptr++)
;
systype = ztrduppfx(ptr, eptr-ptr);
if (!strncmp(systype, "UNIX Type: L8", 13)) {
/*
* Use binary for transfers. This simple test saves much
* hassle for all concerned, particularly me.
*/
zfstatus |= ZFST_IMAG;
zfis_unix = 1;
}
/*
* we could set zfis_unix based just on the UNIX part,
* but I don't really know the consequences of that.
*/
zfsetparam("ZFTP_SYSTEM", systype, ZFPM_READONLY);
}
zfstatus |= ZFST_SYST;
}
tbuf[0] = (ZFST_TYPE(zfstatus) == ZFST_ASCI) ? 'A' : 'I';
zfsetparam("ZFTP_TYPE", ztrdup(tbuf), ZFPM_READONLY);
/*
* Get the directory. This is possibly an unnecessary overhead, of
* course, but when you're being driven by shell functions there's
@ -2307,7 +2317,7 @@ zftp_local(char *name, char **args, int flags)
{
int more = !!args[1], ret = 0, dofd = !*args;
while (*args || dofd) {
long sz;
off_t sz;
char *mt;
int newret = zfstats(*args, !(flags & ZFTP_HERE), &sz, &mt,
dofd ? 0 : -1);
@ -2324,7 +2334,12 @@ zftp_local(char *name, char **args, int flags)
fputs(*args, stdout);
fputc(' ', stdout);
}
#ifdef OFF_T_IS_64_BIT
printf("%s %s\n", output64(sz), mt);
#else
DPUTS(sizeof(sz) > 4, "Shell compiled with wrong off_t size");
printf("%ld %s\n", sz, mt);
#endif
zsfree(mt);
if (dofd)
break;
@ -2371,9 +2386,9 @@ zftp_getput(char *name, char **args, int flags)
fflush(stdout); /* since we may be using fd 1 */
for (; *args; args++) {
char *ln, *rest = NULL;
long startat = 0;
off_t startat = 0;
if (progress && (l = getshfunc("zftp_progress")) != &dummy_list) {
long sz;
off_t sz;
/*
* This calls the SIZE command to get the size for remote
* files. Some servers send the size with the reply to
@ -2701,7 +2716,7 @@ boot_zftp(Module m)
if ((ret = addbuiltins(m->nam, bintab,
sizeof(bintab)/sizeof(*bintab))) == 1) {
/* if successful, set some default parameters */
long tmout_def = 60;
off_t tmout_def = 60;
zfsetparam("ZFTP_VERBOSE", ztrdup("450"), ZFPM_IFUNSET);
zfsetparam("ZFTP_TMOUT", &tmout_def, ZFPM_IFUNSET|ZFPM_INTEGER);
zfsetparam("ZFTP_PREFS", ztrdup("PS"), ZFPM_IFUNSET);

View file

@ -100,11 +100,11 @@ int incompfunc;
/* global variables for shell parameters in new style completion */
/**/
long compcurrent,
compnmatches,
compmatcher,
compmatchertot,
complistmax;
zlong compcurrent,
compnmatches,
compmatcher,
compmatchertot,
complistmax;
/**/
char **compwords,

View file

@ -2270,7 +2270,7 @@ set_compstate(Param pm, HashTable ht)
v.arr = NULL;
v.pm = (Param) hn;
if (cp->type == PM_INTEGER)
*((long *) cp->var) = getintvalue(&v);
*((zlong *) cp->var) = getintvalue(&v);
else if ((str = getstrvalue(&v))) {
zsfree(*((char **) cp->var));
*((char **) cp->var) = ztrdup(str);
@ -2289,7 +2289,7 @@ get_unambig(Param pm)
}
/**/
static long
static zlong
get_unambig_curs(Param pm)
{
int c;
@ -2342,7 +2342,7 @@ comp_wrapper(List list, FuncWrap w, char *name)
return 1;
else {
char *orest, *opre, *osuf, *oipre, *oisuf, **owords;
long ocur;
zlong ocur;
unsigned int unset = 0, m, sm;
Param *pp;

View file

@ -101,8 +101,8 @@ makezleparams(int ro)
pm->gets.afn = (char **(*) _((Param))) zp->getfn;
break;
case PM_INTEGER:
pm->sets.ifn = (void (*) _((Param, long))) zp->setfn;
pm->gets.ifn = (long (*) _((Param))) zp->getfn;
pm->sets.ifn = (void (*) _((Param, zlong))) zp->setfn;
pm->gets.ifn = (zlong (*) _((Param))) zp->getfn;
pm->ct = 10;
break;
}
@ -146,7 +146,7 @@ get_buffer(Param pm)
/**/
static void
set_cursor(Param pm, long x)
set_cursor(Param pm, zlong x)
{
if(x < 0)
cs = 0;
@ -157,7 +157,7 @@ set_cursor(Param pm, long x)
}
/**/
static long
static zlong
get_cursor(Param pm)
{
return cs;
@ -264,20 +264,20 @@ get_keys(Param pm)
/**/
static void
set_numeric(Param pm, long x)
set_numeric(Param pm, zlong x)
{
zmult = x;
}
/**/
static long
static zlong
get_numeric(Param pm)
{
return zmult;
}
/**/
static long
static zlong
get_histno(Param pm)
{
return histline;

View file

@ -881,20 +881,8 @@ moveto(int ln, int cl)
}
}
if (cl == vcs)
return;
/* choose cheapest movements for ttys without multiple movement capabilities -
do this now because it's easier (to code) */
if (cl <= vcs / 2) {
zputc('\r', shout);
vcs = 0;
}
if (vcs < cl)
tc_rightcurs(cl);
else if (vcs > cl)
tc_leftcurs(vcs - cl);
vcs = cl;
if (cl != vcs)
singmoveto(cl);
}
/**/
@ -912,16 +900,17 @@ tcmultout(int cap, int multcap, int ct)
return 0;
}
/* ct: number of characters to move across */
/**/
static void
tc_rightcurs(int cl)
tc_rightcurs(int ct)
{
int ct, /* number of characters to move across */
int cl, /* ``desired'' absolute horizontal position */
i = vcs, /* cursor position after initial movements */
j;
char *t;
ct = cl - vcs;
cl = ct + vcs;
/* do a multright if we can - it's the most reliable */
if (tccan(TCMULTRIGHT)) {
@ -929,6 +918,13 @@ tc_rightcurs(int cl)
return;
}
/* do an absolute horizontal position if we can */
if (tccan(TCHORIZPOS)) {
tcoutarg(TCHORIZPOS, cl);
return;
}
/* XXX: should really check "it" in termcap and use / and % */
/* try tabs if tabs are non destructive and multright is not possible */
if (!oxtabs && tccan(TCNEXTTAB) && ((vcs | 7) < cl)) {
i = (vcs | 7) + 1;
@ -1137,21 +1133,19 @@ singmoveto(int pos)
{
if (pos == vcs)
return;
if (pos <= vcs / 2) {
/* choose cheapest movements for ttys without multiple movement capabilities -
do this now because it's easier (to code) */
if ((!tccan(TCMULTLEFT) || pos == 0) && (pos <= vcs / 2)) {
zputc('\r', shout);
vcs = 0;
}
if (pos < vcs) {
if (pos < vcs)
tc_leftcurs(vcs - pos);
vcs = pos;
}
if (pos > vcs) {
if (tcmultout(TCRIGHT, TCMULTRIGHT, pos - vcs))
vcs = pos;
else
while (pos > vcs) {
zputc(nbuf[0][vcs], shout);
vcs++;
}
}
else if (pos > vcs)
tc_rightcurs(pos - vcs);
vcs = pos;
}

View file

@ -3723,7 +3723,8 @@ addmatches(Cadata dat, char **argv)
}
}
if (!(dat->aflags & CAF_MATCH)) {
ms = dupstring(s);
ms = ((dat->aflags & CAF_QUOTE) ? dupstring(s) :
quotename(s, NULL));
lc = bld_parts(ms, sl, -1, NULL);
isexact = 0;
} else if (!(ms = comp_match(lpre, lsuf, s, cp, &lc,
@ -3734,7 +3735,7 @@ addmatches(Cadata dat, char **argv)
continue;
}
if (doadd) {
cm = add_match_data(isalt, ms, lc, dat->ipre, dat->ipre,
cm = add_match_data(isalt, ms, lc, dat->ipre, NULL,
dat->isuf, dat->pre, dat->prpre,
dat->ppre, dat->psuf, dat->suf,
bpl, bsl, dat->flags, isexact);

View file

@ -1521,9 +1521,14 @@ typeset_single(char *cname, char *pname, Param pm, int func,
zerrnam(cname, "%s: restricted", pname, 0);
return pm;
}
if (PM_TYPE(pm->flags) == PM_ARRAY && (on & PM_UNIQUE) &&
!(pm->flags & PM_READONLY & ~off))
uniqarray((*pm->gets.afn) (pm));
if ((on & PM_UNIQUE) && !(pm->flags & PM_READONLY & ~off)) {
Param apm;
if (PM_TYPE(pm->flags) == PM_ARRAY)
uniqarray((*pm->gets.afn) (pm));
else if (PM_TYPE(pm->flags) == PM_SCALAR && pm->ename &&
(apm = (Param) paramtab->getnode(paramtab, pm->ename)))
uniqarray((*apm->gets.afn) (apm));
}
pm->flags = (pm->flags | on) & ~off;
/* This auxlen/pm->ct stuff is a nasty hack. */
if ((on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | PM_INTEGER)) &&
@ -3647,7 +3652,7 @@ bin_ttyctl(char *name, char **argv, char *ops, int func)
int
bin_let(char *name, char **argv, char *ops, int func)
{
long val = 0;
zlong val = 0;
while (*argv)
val = matheval(*argv++);

View file

@ -304,3 +304,21 @@ zchdir(char *dir)
return currdir == -2 ? -1 : -2;
#endif
}
/*
* How to print out a 64 bit integer. This isn't needed (1) if longs
* are 64 bit, since ordinary %ld will work (2) if we couldn't find a
* 64 bit type anyway.
*/
/**/
#ifdef ZSH_64_BIT_TYPE
/**/
char *
output64(zlong val)
{
static char llbuf[DIGBUFSIZE];
convbase(llbuf, val, 0);
return llbuf;
}
/**/
#endif /* ZSH_64_BIT_TYPE */

View file

@ -311,7 +311,7 @@ cond_str(char **args, int num)
}
/**/
long
zlong
cond_val(char **args, int num)
{
char *s = args[num];

View file

@ -213,6 +213,78 @@ zfork(void)
return pid;
}
/*
* Allen Edeln gebiet ich Andacht,
* Hohen und Niedern von Heimdalls Geschlecht;
* Ich will list_pipe's Wirken kuenden
* Die aeltesten Sagen, der ich mich entsinne...
*
* In most shells, if you do something like:
*
* cat foo | while read a; do grep $a bar; done
*
* the shell forks and executes the loop in the sub-shell thus created.
* In zsh this traditionally executes the loop in the current shell, which
* is nice to have if the loop does something to change the shell, like
* setting parameters or calling builtins.
* Putting the loop in a sub-shell makes live easy, because the shell only
* has to put it into the job-structure and then treats it as a normal
* process. Suspending and interrupting is no problem then.
* Some years ago, zsh either couldn't suspend such things at all, or
* it got really messed up when users tried to do it. As a solution, we
* implemented the list_pipe-stuff, which has since then become a reason
* for many nightmares.
* Pipelines like the one above are executed by the functions in this file
* which call each other (and sometimes recursively). The one above, for
* example would lead to a function call stack roughly like:
*
* execlist->execpline->execcmd->execwhile->execlist->execpline
*
* (when waiting for the grep, ignoring execpline2 for now). At this time,
* zsh has build two job-table entries for it: one for the cat and one for
* the grep. If the user hits ^Z at this point (and jobbing is used), the
* shell is notified that the grep was suspended. The list_pipe flag is
* used to tell the execpline where it was waiting that it was in a pipeline
* with a shell construct at the end (which may also be a shell function or
* several other things). When zsh sees the suspended grep, it forks to let
* the sub-shell execute the rest of the while loop. The parent shell walks
* up in the function call stack to the first execpline. There it has to find
* out that it has just forked and then has to add information about the sub-
* shell (its pid and the text for it) in the job entry of the cat. The pid
* is passed down in the list_pipe_pid variable.
* But there is a problem: the suspended grep is a child of the parent shell
* and can't be adopted by the sub-shell. So the parent shell also has to
* keep the information about this process (more precisely: this pipeline)
* by keeping the job table entry it created for it. The fact that there
* are two jobs which have to be treated together is remembered by setting
* the STAT_SUPERJOB flag in the entry for the cat-job (which now also
* contains a process-entry for the whole loop -- the sub-shell) and by
* setting STAT_SUBJOB in the job of the grep-job. With that we can keep
* sub-jobs from being displayed and we can handle an fg/bg on the super-
* job correctly. When the super-job is continued, the shell also wakes up
* the sub-job. But then, the grep will exit sometime. Now the parent shell
* has to remember not to try to wake it up again (in case of another ^Z).
* It also has to wake up the sub-shell (which suspended itself immediately
* after creation), so that the rest of the loop is executed by it.
* But there is more: when the sub-shell is created, the cat may already
* have exited, so we can't put the sub-shell in the process group of it.
* In this case, we put the sub-shell in the process group of the parent
* shell and in any case, the sub-shell has to put all commands executed
* by it into its own process group, because only this way the parent
* shell can control them since it only knows the process group of the sub-
* shell. Of course, this information is also important when putting a job
* in the foreground, where we have to attach its process group to the
* controlling tty.
* All this is made more difficult because we have to handle return values
* correctly. If the grep is signaled, its exit status has to be propagated
* back to the parent shell which needs it to set the exit status of the
* super-job. And of course, when the grep is signaled (including ^C), the
* loop has to be stopped, etc.
* The code for all this is distributed over three files (exec.c, jobs.c,
* and signals.c) and none of them is a simple one. So, all in all, there
* may still be bugs, but considering the complexity (with race conditions,
* signal handling, and all that), this should probably be expected.
*/
/**/
int list_pipe = 0, simple_pline = 0;
@ -625,6 +697,13 @@ execlist(List list, int dont_change_job, int exiting)
static int donetrap;
int ret, cj;
int old_pline_level, old_list_pipe;
/*
* ERREXIT only forces the shell to exit if the last command in a &&
* or || fails. This is the case even if an earlier command is a
* shell function or other current shell structure, so we have to set
* noerrexit here if the sublist is not of type END.
*/
int oldnoerrexit = noerrexit;
cj = thisjob;
old_pline_level = pline_level;
@ -644,6 +723,8 @@ execlist(List list, int dont_change_job, int exiting)
/* Loop through code followed by &&, ||, or end of sublist. */
while (slist) {
if (!oldnoerrexit)
noerrexit = (slist->type != END);
switch (slist->type) {
case END:
/* End of sublist; just execute, ignoring status. */
@ -687,6 +768,8 @@ execlist(List list, int dont_change_job, int exiting)
}
sublist_done:
noerrexit = oldnoerrexit;
if (sigtrapped[SIGDEBUG])
dotrap(SIGDEBUG);
@ -761,13 +844,17 @@ execpline(Sublist l, int how, int last1)
coprocout = opipe[1];
fdtable[coprocin] = fdtable[coprocout] = 0;
}
/* This used to set list_pipe_pid=0 unconditionally, but in things
* like `ls|if true; then sleep 20; cat; fi' where the sleep was
* stopped, the top-level execpline() didn't get the pid for the
* sub-shell because it was overwritten. */
if (!pline_level++) {
list_pipe_job = newjob;
list_pipe_pid = 0;
nowait = 0;
}
list_pipe_pid = lastwj = 0;
if (pline_level == 1)
simple_pline = (l->left->type == END);
}
lastwj = 0;
execpline2(l->left, how, opipe[0], ipipe[1], last1);
pline_level--;
if (how & Z_ASYNC) {
@ -800,6 +887,7 @@ execpline(Sublist l, int how, int last1)
struct process *pn, *qn;
curjob = newjob;
DPUTS(!list_pipe_pid, "invalid list_pipe_pid");
addproc(list_pipe_pid, list_pipe_text);
for (pn = jobtab[jn->other].procs; pn; pn = pn->next)
@ -1588,7 +1676,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
closem(2);
#endif
if (how & Z_ASYNC) {
lastpid = (long) pid;
lastpid = (zlong) pid;
} else if (!jobtab[thisjob].stty_in_env && nonempty(cmd->vars)) {
/* search for STTY=... */
while (nonempty(cmd->vars))
@ -2548,7 +2636,7 @@ static int
execarith(Cmd cmd)
{
char *e;
long val = 0;
zlong val = 0;
if (isset(XTRACE))
fprintf(stderr, "%s((", prompt4 ? prompt4 : "");

View file

@ -30,18 +30,24 @@
#include "zsh.mdh"
#include "glob.pro"
#if defined(OFF_T_IS_64_BIT) && defined(__GNUC__)
# define ALIGN64 __attribute__((aligned(8)))
#else
# define ALIGN64
#endif
/* flag for CSHNULLGLOB */
typedef struct gmatch *Gmatch;
struct gmatch {
char *name;
long size;
off_t size ALIGN64;
long atime;
long mtime;
long ctime;
long links;
long _size;
off_t _size ALIGN64;
long _atime;
long _mtime;
long _ctime;
@ -97,13 +103,13 @@ typedef struct stat *Statptr; /* This makes the Ultrix compiler happy. Go figu
#define TT_KILOBYTES 2
#define TT_MEGABYTES 3
typedef int (*TestMatchFunc) _((struct stat *, long));
typedef int (*TestMatchFunc) _((struct stat *, off_t));
struct qual {
struct qual *next; /* Next qualifier, must match */
struct qual *or; /* Alternative set of qualifiers to match */
TestMatchFunc func; /* Function to call to test match */
long data; /* Argument passed to function */
off_t data ALIGN64; /* Argument passed to function */
int sense; /* Whether asserting or negating */
int amc; /* Flag for which time to test (a, m, c) */
int range; /* Whether to test <, > or = (as per signum) */
@ -244,7 +250,7 @@ insert(char *s, int checked)
if (gf_follow) {
if (!S_ISLNK(mode) || statfullpath(s, &buf2, 0))
memcpy(&buf2, &buf, sizeof(buf));
statted = 2;
statted |= 2;
mode = buf2.st_mode;
}
if (gf_listtypes || S_ISDIR(mode)) {
@ -268,11 +274,11 @@ insert(char *s, int checked)
range = qn->range;
amc = qn->amc;
units = qn->units;
if ((qn->sense & 2) && statted != 2) {
if ((qn->sense & 2) && !(statted & 2)) {
/* If (sense & 2), we're following links */
if (!S_ISLNK(buf.st_mode) || statfullpath(s, &buf2, 0))
memcpy(&buf2, &buf, sizeof(buf));
statted = 2;
statted |= 2;
}
bp = (qn->sense & 2) ? &buf2 : &buf;
/* Reject the file if the function returned zero *
@ -302,24 +308,29 @@ insert(char *s, int checked)
statfullpath(s, &buf, 1);
statted = 1;
}
if (statted != 2 && (gf_sorts & GS_LINKED)) {
if (!(statted & 2) && (gf_sorts & GS_LINKED)) {
if (statted) {
if (!S_ISLNK(buf.st_mode) || statfullpath(s, &buf2, 0))
memcpy(&buf2, &buf, sizeof(buf));
} else if (statfullpath(s, &buf2, 0))
statfullpath(s, &buf2, 1);
statted |= 2;
}
matchptr->name = news;
matchptr->size = buf.st_size;
matchptr->atime = buf.st_atime;
matchptr->mtime = buf.st_mtime;
matchptr->ctime = buf.st_ctime;
matchptr->links = buf.st_nlink;
matchptr->_size = buf2.st_size;
matchptr->_atime = buf2.st_atime;
matchptr->_mtime = buf2.st_mtime;
matchptr->_ctime = buf2.st_ctime;
matchptr->_links = buf2.st_nlink;
if (statted & 1) {
matchptr->size = buf.st_size;
matchptr->atime = buf.st_atime;
matchptr->mtime = buf.st_mtime;
matchptr->ctime = buf.st_ctime;
matchptr->links = buf.st_nlink;
}
if (statted & 2) {
matchptr->_size = buf2.st_size;
matchptr->_atime = buf2.st_atime;
matchptr->_mtime = buf2.st_mtime;
matchptr->_ctime = buf2.st_ctime;
matchptr->_links = buf2.st_nlink;
}
matchptr++;
if (++matchct == matchsz) {
@ -1102,10 +1113,10 @@ parsepat(char *str)
/* get number after qualifier */
/**/
static long
static off_t
qgetnum(char **s)
{
long v = 0;
off_t v = 0;
if (!idigit(**s)) {
zerr("number expected", NULL, 0);
@ -1119,10 +1130,10 @@ qgetnum(char **s)
/* get mode spec after qualifier */
/**/
static long
static zlong
qgetmodespec(char **s)
{
long yes = 0, no = 0, val, mask, t;
zlong yes = 0, no = 0, val, mask, t;
char *p = *s, c, how, end;
if ((c = *p) == '=' || c == Equals || c == '+' || c == '-' ||
@ -1163,7 +1174,7 @@ qgetmodespec(char **s)
case 't': val |= 01000; break;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
t = ((long) c - '0');
t = ((zlong) c - '0');
val |= t | (t << 3) | (t << 6);
break;
default:
@ -1186,7 +1197,7 @@ qgetmodespec(char **s)
val <<= 3;
} else {
t <<= 3;
val = (val << 3) | ((long) c - '0');
val = (val << 3) | ((zlong) c - '0');
}
p++;
}
@ -1212,7 +1223,7 @@ static int
gmatchcmp(Gmatch a, Gmatch b)
{
int i, *s;
long r = 0L;
off_t r = 0L;
for (i = gf_nsorts, s = gf_sortlist; i; i--, s++) {
switch (*s & ~GS_DESC) {
@ -1306,13 +1317,13 @@ glob(LinkList list, LinkNode np)
/* Real qualifiers found. */
int sense = 0; /* bit 0 for match (0)/don't match (1) */
/* bit 1 for follow links (2), don't (0) */
long data = 0; /* Any numerical argument required */
int (*func) _((Statptr, long));
off_t data = 0; /* Any numerical argument required */
int (*func) _((Statptr, off_t));
str[sl-1] = 0;
*s++ = 0;
while (*s && !colonmod) {
func = (int (*) _((Statptr, long)))0;
func = (int (*) _((Statptr, off_t)))0;
if (idigit(*s)) {
/* Store numeric argument for qualifier */
func = qualflags;
@ -3142,7 +3153,14 @@ matchonce(Comp c)
}
if (*pat == Inang) {
/* Numeric globbing. */
#ifdef ZSH_64_BIT_TYPE
/* zstrtol returns zlong anyway */
# define RANGE_CAST()
zlong t1, t2, t3;
#else
# define RANGE_CAST() (unsigned long)
unsigned long t1, t2, t3;
#endif
char *ptr, *saves = pptr, *savep = pat;
if (!idigit(*pptr))
@ -3161,18 +3179,18 @@ matchonce(Comp c)
* t1 = number supplied: must be positive, so use
* unsigned arithmetic.
*/
t1 = (unsigned long)zstrtol(pptr, &ptr, 10);
t1 = RANGE_CAST() zstrtol(pptr, &ptr, 10);
pptr = ptr;
/* t2 = lower limit */
if (idigit(*pat))
t2 = (unsigned long)zstrtol(pat, &ptr, 10);
t2 = RANGE_CAST() zstrtol(pat, &ptr, 10);
else
t2 = 0, ptr = pat;
if (*ptr != '-' || (not3 = (ptr[1] == Outang)))
/* exact match or no upper limit */
t3 = t2, pat = ptr + not3;
else /* t3 = upper limit */
t3 = (unsigned long)zstrtol(ptr + 1, &pat, 10);
t3 = RANGE_CAST() zstrtol(ptr + 1, &pat, 10);
DPUTS(*pat != Outang, "BUG: wrong internal range pattern");
pat++;
/*
@ -3191,6 +3209,7 @@ matchonce(Comp c)
}
}
continue;
#undef RANGE_CAST
}
/* itok(Meta) is zero */
DPUTS(itok(*pat), "BUG: matching tokenized character");
@ -3430,7 +3449,7 @@ remnulargs(char *s)
/**/
static int
qualdev(struct stat *buf, long dv)
qualdev(struct stat *buf, off_t dv)
{
return buf->st_dev == dv;
}
@ -3439,7 +3458,7 @@ qualdev(struct stat *buf, long dv)
/**/
static int
qualnlink(struct stat *buf, long ct)
qualnlink(struct stat *buf, off_t ct)
{
return (range < 0 ? buf->st_nlink < ct :
range > 0 ? buf->st_nlink > ct :
@ -3450,7 +3469,7 @@ qualnlink(struct stat *buf, long ct)
/**/
static int
qualuid(struct stat *buf, long uid)
qualuid(struct stat *buf, off_t uid)
{
return buf->st_uid == uid;
}
@ -3459,7 +3478,7 @@ qualuid(struct stat *buf, long uid)
/**/
static int
qualgid(struct stat *buf, long gid)
qualgid(struct stat *buf, off_t gid)
{
return buf->st_gid == gid;
}
@ -3468,7 +3487,7 @@ qualgid(struct stat *buf, long gid)
/**/
static int
qualisdev(struct stat *buf, long junk)
qualisdev(struct stat *buf, off_t junk)
{
return S_ISBLK(buf->st_mode) || S_ISCHR(buf->st_mode);
}
@ -3477,7 +3496,7 @@ qualisdev(struct stat *buf, long junk)
/**/
static int
qualisblk(struct stat *buf, long junk)
qualisblk(struct stat *buf, off_t junk)
{
return S_ISBLK(buf->st_mode);
}
@ -3486,7 +3505,7 @@ qualisblk(struct stat *buf, long junk)
/**/
static int
qualischr(struct stat *buf, long junk)
qualischr(struct stat *buf, off_t junk)
{
return S_ISCHR(buf->st_mode);
}
@ -3495,7 +3514,7 @@ qualischr(struct stat *buf, long junk)
/**/
static int
qualisdir(struct stat *buf, long junk)
qualisdir(struct stat *buf, off_t junk)
{
return S_ISDIR(buf->st_mode);
}
@ -3504,7 +3523,7 @@ qualisdir(struct stat *buf, long junk)
/**/
static int
qualisfifo(struct stat *buf, long junk)
qualisfifo(struct stat *buf, off_t junk)
{
return S_ISFIFO(buf->st_mode);
}
@ -3513,7 +3532,7 @@ qualisfifo(struct stat *buf, long junk)
/**/
static int
qualislnk(struct stat *buf, long junk)
qualislnk(struct stat *buf, off_t junk)
{
return S_ISLNK(buf->st_mode);
}
@ -3522,7 +3541,7 @@ qualislnk(struct stat *buf, long junk)
/**/
static int
qualisreg(struct stat *buf, long junk)
qualisreg(struct stat *buf, off_t junk)
{
return S_ISREG(buf->st_mode);
}
@ -3531,7 +3550,7 @@ qualisreg(struct stat *buf, long junk)
/**/
static int
qualissock(struct stat *buf, long junk)
qualissock(struct stat *buf, off_t junk)
{
return S_ISSOCK(buf->st_mode);
}
@ -3540,7 +3559,7 @@ qualissock(struct stat *buf, long junk)
/**/
static int
qualflags(struct stat *buf, long mod)
qualflags(struct stat *buf, off_t mod)
{
return mode_to_octal(buf->st_mode) & mod;
}
@ -3549,7 +3568,7 @@ qualflags(struct stat *buf, long mod)
/**/
static int
qualmodeflags(struct stat *buf, long mod)
qualmodeflags(struct stat *buf, off_t mod)
{
long v = mode_to_octal(buf->st_mode), y = mod & 07777, n = mod >> 12;
@ -3560,7 +3579,7 @@ qualmodeflags(struct stat *buf, long mod)
/**/
static int
qualiscom(struct stat *buf, long mod)
qualiscom(struct stat *buf, off_t mod)
{
return S_ISREG(buf->st_mode) && (buf->st_mode & S_IXUGO);
}
@ -3569,9 +3588,15 @@ qualiscom(struct stat *buf, long mod)
/**/
static int
qualsize(struct stat *buf, long size)
qualsize(struct stat *buf, off_t size)
{
unsigned long scaled = buf->st_size;
#if defined(LONG_IS_64_BIT) || defined(OFF_T_IS_64_BIT)
# define QS_CAST_SIZE()
off_t scaled = buf->st_size;
#else
# define QS_CAST_SIZE() (unsigned long)
unsigned long scaled = (unsigned long)buf->st_size;
#endif
switch (units) {
case TT_POSIX_BLOCKS:
@ -3588,16 +3613,17 @@ qualsize(struct stat *buf, long size)
break;
}
return (range < 0 ? scaled < (unsigned long) size :
range > 0 ? scaled > (unsigned long) size :
scaled == (unsigned long) size);
return (range < 0 ? scaled < QS_CAST_SIZE() size :
range > 0 ? scaled > QS_CAST_SIZE() size :
scaled == QS_CAST_SIZE() size);
#undef QS_CAST_SIZE
}
/* time in required range? */
/**/
static int
qualtime(struct stat *buf, long days)
qualtime(struct stat *buf, off_t days)
{
time_t now, diff;

View file

@ -112,6 +112,7 @@ newhashtable(int size, char const *name, PrintTableStats printinfo)
ht->hsize = size;
ht->ct = 0;
ht->scan = NULL;
ht->scantab = NULL;
return ht;
}
@ -361,6 +362,10 @@ scanhashtable(HashTable ht, int sorted, int flags1, int flags2, ScanFunc scanfun
{
struct scanstatus st;
if (ht->scantab) {
ht->scantab(ht, scanfunc, scanflags);
return;
}
if (sorted) {
int i, ct = ht->ct;
VARARR(HashNode, hnsorttab, ct);

View file

@ -972,7 +972,7 @@ hend(void)
zfree(chwords, chwordlen*sizeof(short));
chline = NULL;
histactive = 0;
if (isset(SHAREHISTORY) || isset(INCREMENTALAPPENDHISTORY))
if (isset(SHAREHISTORY) || isset(INCAPPENDHISTORY))
savehistfile(hf, 1, HFILE_USE_OPTIONS | HFILE_FAST);
unlockhistfile(hf); /* It's OK to call this even if we aren't locked */
return !(flag & HISTFLAG_NOEXEC || errflag);
@ -1778,7 +1778,7 @@ savehistfile(char *fn, int err, int writeflags)
he = hist_ring->down;
}
if (writeflags & HFILE_USE_OPTIONS) {
if (isset(APPENDHISTORY) || isset(INCREMENTALAPPENDHISTORY)
if (isset(APPENDHISTORY) || isset(INCAPPENDHISTORY)
|| isset(SHAREHISTORY))
writeflags |= HFILE_APPEND | HFILE_SKIPOLD;
else
@ -1883,7 +1883,7 @@ lockhistfile(char *fn, int keep_trying)
char *tmpfile, *lockfile;
tmpfile = zalloc(len + 10 + 1);
sprintf(tmpfile, "%s.%ld", fn, mypid);
sprintf(tmpfile, "%s.%ld", fn, (long)mypid);
if ((fd = open(tmpfile, O_RDWR|O_CREAT|O_EXCL, 0644)) >= 0) {
write(fd, "0\n", 2);
close(fd);

View file

@ -414,7 +414,7 @@ init_shout(void)
static char *tccapnams[TC_COUNT] = {
"cl", "le", "LE", "nd", "RI", "up", "UP", "do",
"DO", "dc", "DC", "ic", "IC", "cd", "ce", "al", "dl", "ta",
"md", "so", "us", "me", "se", "ue"
"md", "so", "us", "me", "se", "ue", "ch"
};
/* Initialise termcap */
@ -583,8 +583,8 @@ setupvals(void)
zoptarg = ztrdup("");
zoptind = 1;
ppid = (long) getppid();
mypid = (long) getpid();
ppid = (zlong) getppid();
mypid = (zlong) getpid();
term = ztrdup("");
/* The following variable assignments cause zsh to behave more *

View file

@ -406,7 +406,7 @@ stuff(char *fn)
{
FILE *in;
char *buf;
int len;
off_t len;
if (!(in = fopen(unmeta(fn), "r"))) {
zerr("can't open %s", fn, 0);

View file

@ -175,8 +175,23 @@ update_job(Job jn)
jn->ty = (struct ttyinfo *) zalloc(sizeof(struct ttyinfo));
gettyinfo(jn->ty);
}
if (jn->stat & STAT_STOPPED)
if (jn->stat & STAT_STOPPED) {
if (jn->stat & STAT_SUBJOB) {
/* If we have `cat foo|while read a; grep $a bar;done'
* and have hit ^Z, the sub-job is stopped, but the
* super-job may still be running, waiting to be stopped
* or to exit. So we have to send it a SIGSTOP. */
int i;
for (i = 1; i < MAXJOB; i++)
if ((jobtab[i].stat & STAT_SUPERJOB) &&
jobtab[i].other == job) {
killpg(jobtab[i].gleader, SIGSTOP);
break;
}
}
return;
}
} else { /* job is done, so remember return value */
lastval2 = val;
/* If last process was run in the current shell, keep old status
@ -202,14 +217,27 @@ update_job(Job jn)
if (mypgrp != pgrp && inforeground &&
(jn->gleader == pgrp || (pgrp > 1 && kill(-pgrp, 0) == -1))) {
if (list_pipe) {
/*
* Oh, dear, we're right in the middle of some confusion
* of shell jobs on the righthand side of a pipeline, so
* it's death to call attachtty() just yet. Mark the
* fact in the job, so that the attachtty() will be called
* when the job is finally deleted.
*/
jn->stat |= STAT_ATTACH;
if (pgrp > 1 && kill(-pgrp, 0) == -1) {
attachtty(mypgrp);
/* check window size and adjust if necessary */
adjustwinsize(0);
} else {
/*
* Oh, dear, we're right in the middle of some confusion
* of shell jobs on the righthand side of a pipeline, so
* it's death to call attachtty() just yet. Mark the
* fact in the job, so that the attachtty() will be called
* when the job is finally deleted.
*/
jn->stat |= STAT_ATTACH;
}
/* If we have `foo|while true; (( x++ )); done', and hit
* ^C, we have to stop the loop, too. */
if ((val & 0200) && inforeground == 1) {
breaks = loops;
errflag = 1;
inerrflush();
}
} else {
attachtty(mypgrp);
/* check window size and adjust if necessary */
@ -765,8 +793,17 @@ waitjob(int job, int sig)
}
if (!p) {
jn->stat &= ~STAT_SUPERJOB;
if (WIFEXITED(jn->procs->status))
jn->gleader = mypgrp;
/* This deleted the job too early if the parent
shell waited for a command in a list that will
be executed by the sub-shell (e.g.: if we have
`ls|if true;then sleep 20;cat;fi' and ^Z the
sleep, the rest will be executed by a sub-shell,
but the parent shell gets notified for the
sleep.
deletejob(sj); */
kill(sj->other, SIGCONT);
deletejob(sj);
}
curjob = jn - jobtab;
}

View file

@ -42,7 +42,7 @@ int lastbase;
static char *ptr;
static long yyval;
static zlong yyval;
static LV yylval;
static int mlevel = 0;
@ -409,14 +409,14 @@ static int sp = -1; /* stack pointer */
struct mathvalue {
LV lval;
long val;
zlong val;
};
static struct mathvalue *stack;
/**/
static void
push(long val, LV lval)
push(zlong val, LV lval)
{
if (sp == STACKSZ - 1)
zerr("stack overflow", NULL, 0);
@ -428,7 +428,7 @@ push(long val, LV lval)
/**/
static long
static zlong
getcvar(LV s)
{
char *t;
@ -440,8 +440,8 @@ getcvar(LV s)
/**/
static long
setvar(LV s, long v)
static zlong
setvar(LV s, zlong v)
{
if (s == -1 || s >= lvc) {
zerr("lvalue required", NULL, 0);
@ -456,7 +456,7 @@ setvar(LV s, long v)
/**/
static int
notzero(long a)
notzero(zlong a)
{
if (a == 0) {
zerr("division by zero", NULL, 0);
@ -496,7 +496,7 @@ notzero(long a)
void
op(int what)
{
long a, b, c;
zlong a, b, c;
LV lv;
if (sp < 0) {
@ -569,39 +569,39 @@ op(int what)
break;
case LES:
pop2();
pushv((long)(a < b));
pushv((zlong)(a < b));
break;
case LEQ:
pop2();
pushv((long)(a <= b));
pushv((zlong)(a <= b));
break;
case GRE:
pop2();
pushv((long)(a > b));
pushv((zlong)(a > b));
break;
case GEQ:
pop2();
pushv((long)(a >= b));
pushv((zlong)(a >= b));
break;
case DEQ:
pop2();
pushv((long)(a == b));
pushv((zlong)(a == b));
break;
case NEQ:
pop2();
pushv((long)(a != b));
pushv((zlong)(a != b));
break;
case DAND:
pop2();
pushv((long)(a && b));
pushv((zlong)(a && b));
break;
case DOR:
pop2();
pushv((long)(a || b));
pushv((zlong)(a || b));
break;
case DXOR:
pop2();
pushv((long)((a && !b) || (!a && b)));
pushv((zlong)((a && !b) || (!a && b)));
break;
case QUEST:
pop3();
@ -658,15 +658,15 @@ op(int what)
break;
case DANDEQ:
pop2lv();
set((long)(a && b));
set((zlong)(a && b));
break;
case DOREQ:
pop2lv();
set((long)(a || b));
set((zlong)(a || b));
break;
case DXOREQ:
pop2lv();
set((long)((a && !b) || (!a && b)));
set((zlong)((a && !b) || (!a && b)));
break;
case COMMA:
pop2();
@ -725,18 +725,18 @@ bop(int tk)
/**/
static long
static zlong
mathevall(char *s, int prek, char **ep)
{
int t0;
int xlastbase, xnoeval, xunary, xlvc;
char *xptr;
long xyyval;
zlong xyyval;
LV xyylval;
char **xlvals = 0;
int xsp;
struct mathvalue *xstack = 0;
long ret;
zlong ret;
xlastbase = xnoeval = xunary = xlvc = xyyval = xyylval = xsp = 0;
xptr = NULL;
@ -789,11 +789,11 @@ mathevall(char *s, int prek, char **ep)
/**/
long
zlong
matheval(char *s)
{
char *junk;
long x;
zlong x;
int xmtok = mtok;
if (!*s)
@ -807,10 +807,10 @@ matheval(char *s)
/**/
long
zlong
mathevalarg(char *s, char **ss)
{
long x;
zlong x;
int xmtok = mtok;
x = mathevall(s, ARGPREC, ss);

View file

@ -96,7 +96,7 @@ static int h_m[1025], h_push, h_pop, h_free;
#endif
#define H_ISIZE sizeof(long)
#define H_ISIZE sizeof(zlong)
#define HEAPSIZE (8192 - H_ISIZE)
#define HEAP_ARENA_SIZE (HEAPSIZE - sizeof(struct heap))
#define HEAPFREE (16384 - H_ISIZE)
@ -500,8 +500,9 @@ ztrdup(const char *s)
/*
Below is a simple segment oriented memory allocator for systems on
which it is better than the system's one. Memory is given in blocks
aligned to an integer multiple of sizeof(long) (4 bytes on most machines,
but 8 bytes on e.g. a dec alpha). Each block is preceded by a header
aligned to an integer multiple of sizeof(zlong) (4 bytes on most machines,
but 8 bytes on e.g. a dec alpha; it will be 8 bytes if we are using
long long's or equivalent). Each block is preceded by a header
which contains the length of the data part (in bytes). In allocated
blocks only this field of the structure m_hdr is senseful. In free
blocks the second field (next) is a pointer to the next free segment
@ -561,22 +562,26 @@ ztrdup(const char *s)
struct m_shdr {
struct m_shdr *next; /* next one on free list */
#ifdef ZSH_64_BIT_TYPE
/* dummy to make this 64-bit aligned */
struct m_shdr *dummy;
#endif
};
struct m_hdr {
long len; /* length of memory block */
zlong len; /* length of memory block */
struct m_hdr *next; /* if free: next on free list
if block of small blocks: next one with
small blocks of same size*/
struct m_shdr *free; /* if block of small blocks: free list */
long used; /* if block of small blocks: number of used
zlong used; /* if block of small blocks: number of used
blocks */
};
/* alignment for memory blocks */
#define M_ALIGN (sizeof(long))
#define M_ALIGN (sizeof(zlong))
/* length of memory header, length of first field of memory header and
minimal size of a block left free (if we allocate memory and take a
@ -585,7 +590,7 @@ struct m_hdr {
the free list) */
#define M_HSIZE (sizeof(struct m_hdr))
#define M_ISIZE (sizeof(long))
#define M_ISIZE (sizeof(zlong))
#define M_MIN (2 * M_ISIZE)
/* a pointer to the last free block, a pointer to the free list (the blocks
@ -621,9 +626,9 @@ static char *m_high, *m_low;
#define M_SNUM 50
#define M_SLEN(M) ((M)->len / M_SNUM)
#define M_SBLEN(S) ((S) * M_SNUM + sizeof(struct m_shdr *) + \
sizeof(long) + sizeof(struct m_hdr *))
sizeof(zlong) + sizeof(struct m_hdr *))
#define M_BSLEN(S) (((S) - sizeof(struct m_shdr *) - \
sizeof(long) - sizeof(struct m_hdr *)) / M_SNUM)
sizeof(zlong) - sizeof(struct m_hdr *)) / M_SNUM)
#define M_NSMALL 8
static struct m_hdr *m_small[M_NSMALL];
@ -1198,8 +1203,9 @@ bin_mem(char *name, char **argv, char *ops, int func)
if (m == mf)
buf[0] = '\0';
else if (m == ms)
sprintf(buf, "%ld %ld %ld", M_SNUM - ms->used, ms->used,
(m->len - sizeof(struct m_hdr)) / M_SNUM + 1);
sprintf(buf, "%ld %ld %ld", (long)(M_SNUM - ms->used),
(long)ms->used,
(long)(m->len - sizeof(struct m_hdr)) / M_SNUM + 1);
else {
for (i = 0, b = buf, c = (char *)&m->next; i < 20 && i < m->len;
@ -1210,7 +1216,7 @@ bin_mem(char *name, char **argv, char *ops, int func)
printf("%d\t%d\t%ld\t%ld\t%s\t%ld\t%s\n", ii,
(m == mf) ? fi++ : ui++,
(long)m, m->len,
(long)m, (long)m->len,
(m == mf) ? "free" : ((m == ms) ? "small" : "used"),
(m == mf) ? (f += m->len) : (u += m->len),
buf);
@ -1231,7 +1237,8 @@ bin_mem(char *name, char **argv, char *ops, int func)
printf("%ld\t", (long)i * M_ISIZE);
for (ii = 0, m = m_small[i]; m; m = m->next) {
printf("(%ld/%ld) ", M_SNUM - m->used, m->used);
printf("(%ld/%ld) ", (long)(M_SNUM - m->used),
(long)m->used);
if (!((++ii) & 7))
printf("\n\t");
}

View file

@ -1224,8 +1224,8 @@ addparamdef(Paramdef d)
pm->level = 0;
pm->u.data = d->var;
pm->sets.ifn = (void (*)(Param, long)) d->set;
pm->gets.ifn = (long (*)(Param)) d->get;
pm->sets.ifn = (void (*)(Param, zlong)) d->set;
pm->gets.ifn = (zlong (*)(Param)) d->get;
pm->unsetfn = (void (*)(Param, int)) d->unset;
return 0;

View file

@ -45,15 +45,6 @@ char opts[OPT_SIZE];
/**/
HashTable optiontab;
typedef struct optname *Optname;
struct optname {
HashNode next; /* next in hash chain */
char *nam; /* hash data */
int flags;
int optno; /* option number */
};
/* The canonical option name table */
#define OPT_CSH EMULATE_CSH
@ -73,6 +64,10 @@ struct optname {
#define defset(X) (!!((X)->flags & emulation))
/*
* Note that option names should usually be fewer than 20 characters long
* to avoid formatting problems.
*/
static struct optname optns[] = {
{NULL, "allexport", 0, ALLEXPORT},
{NULL, "alwayslastprompt", OPT_ALL, ALWAYSLASTPROMPT},
@ -137,7 +132,7 @@ static struct optname optns[] = {
{NULL, "hup", OPT_EMULATE|OPT_ZSH, HUP},
{NULL, "ignorebraces", OPT_EMULATE|OPT_SH, IGNOREBRACES},
{NULL, "ignoreeof", 0, IGNOREEOF},
{NULL, "incrementalappendhistory",0, INCREMENTALAPPENDHISTORY},
{NULL, "incappendhistory", 0, INCAPPENDHISTORY},
{NULL, "interactive", OPT_SPECIAL, INTERACTIVE},
{NULL, "interactivecomments", OPT_EMULATE|OPT_BOURNE, INTERACTIVECOMMENTS},
{NULL, "ksharrays", OPT_EMULATE|OPT_BOURNE, KSHARRAYS},
@ -443,6 +438,17 @@ emulate(const char *zsh_name, int fully)
{
char ch = *zsh_name;
if (!strcmp("su", zsh_name)) {
/* We haven't set up the paramtable yet, so just use zgetenv */
char *ptr = zgetenv("SHELL");
if (ptr && *ptr) {
zsh_name = ptr;
if ((ptr = strrchr(zsh_name, '/')))
zsh_name = ptr+1;
ch = *zsh_name;
} else
ch = 'z';
}
if (ch == 'r')
ch = zsh_name[1];

View file

@ -74,7 +74,7 @@ char *argzero, /* $0 */
*zsh_name; /* $ZSH_NAME */
/**/
long lastval, /* $? */
zlong lastval, /* $? */
mypid, /* $$ */
lastpid, /* $! */
columns, /* $COLUMNS */
@ -334,7 +334,7 @@ copyparamtable(HashTable ht, char *name)
static unsigned numparamvals;
/**/
static void
void
scancountparams(HashNode hn, int flags)
{
++numparamvals;
@ -346,7 +346,7 @@ static Comp scancomp;
static char **paramvals;
/**/
static void
void
scanparamvals(HashNode hn, int flags)
{
struct value v;
@ -572,6 +572,8 @@ createparam(char *name, int flags)
gethashnode2(paramtab, name) :
paramtab->getnode(paramtab, name));
DPUTS(oldpm && oldpm->level > locallevel,
"BUG: old local parameter not deleteed");
if (oldpm && oldpm->level == locallevel) {
if (!(oldpm->flags & PM_UNSET) || (oldpm->flags & PM_SPECIAL)) {
oldpm->flags &= ~PM_UNSET;
@ -704,13 +706,13 @@ isident(char *s)
static char **garr;
/**/
static long
getarg(char **str, int *inv, Value v, int a2, long *w)
static zlong
getarg(char **str, int *inv, Value v, int a2, zlong *w)
{
int num = 1, word = 0, rev = 0, ind = 0, down = 0, l, i, ishash;
int beg = 0, hasbeg = 0;
char *s = *str, *sep = NULL, *t, sav, *d, **ta, **p, *tt;
long r = 0;
zlong r = 0;
Comp c;
ishash = (v->pm && PM_TYPE(v->pm->flags) == PM_HASHED);
@ -872,7 +874,7 @@ getarg(char **str, int *inv, Value v, int a2, long *w)
return 0;
if (!a2 && *tt != ',')
*w = (long)(s - t) - 1;
*w = (zlong)(s - t) - 1;
return (a2 ? s : d + 1) - t;
} else if (!v->isarr && !word) {
@ -973,7 +975,7 @@ getarg(char **str, int *inv, Value v, int a2, long *w)
r++;
for (i = 0; (t = findword(&d, sep)) && *t; i++)
if (!--r) {
r = (long)(t - s + (a2 ? -1 : 1));
r = (zlong)(t - s + (a2 ? -1 : 1));
if (!a2 && *tt != ',')
*w = r + strlen(ta[i]) - 2;
return r;
@ -1051,7 +1053,7 @@ getindex(char **pptr, Value v)
v->b = -1;
s += 2;
} else {
long we = 0, dummy;
zlong we = 0, dummy;
a = getarg(&s, &inv, v, 0, &we);
@ -1216,7 +1218,7 @@ char *
getstrvalue(Value v)
{
char *s, **ss;
static char buf[(sizeof(long) * 8) + 4];
static char buf[(sizeof(zlong) * 8) + 4];
if (!v)
return hcalloc(1);
@ -1314,7 +1316,7 @@ getarrvalue(Value v)
}
/**/
long
zlong
getintvalue(Value v)
{
if (!v || v->isarr)
@ -1330,7 +1332,7 @@ getintvalue(Value v)
static void
setstrvalue(Value v, char *val)
{
char buf[(sizeof(long) * 8) + 4];
char buf[(sizeof(zlong) * 8) + 4];
if (v->pm->flags & PM_READONLY) {
zerr("read-only variable: %s", v->pm->nam, 0);
@ -1414,7 +1416,7 @@ setstrvalue(Value v, char *val)
/**/
static void
setintvalue(Value v, long val)
setintvalue(Value v, zlong val)
{
char buf[DIGBUFSIZE];
@ -1429,7 +1431,7 @@ setintvalue(Value v, long val)
switch (PM_TYPE(v->pm->flags)) {
case PM_SCALAR:
case PM_ARRAY:
sprintf(buf, "%ld", val);
convbase(buf, val, 0);
setstrvalue(v, ztrdup(buf));
break;
case PM_INTEGER:
@ -1508,7 +1510,7 @@ setarrvalue(Value v, char **val)
/* Retrieve an integer parameter */
/**/
long
zlong
getiparam(char *s)
{
Value v;
@ -1681,7 +1683,7 @@ sethparam(char *s, char **val)
/**/
Param
setiparam(char *s, long val)
setiparam(char *s, zlong val)
{
Value v;
char *t = s;
@ -1794,7 +1796,7 @@ stdunsetfn(Param pm, int exp)
/* Function to get value of an integer parameter */
/**/
static long
static zlong
intgetfn(Param pm)
{
return pm->u.val;
@ -1804,7 +1806,7 @@ intgetfn(Param pm)
/**/
static void
intsetfn(Param pm, long x)
intsetfn(Param pm, zlong x)
{
pm->u.val = x;
}
@ -1859,7 +1861,7 @@ arrsetfn(Param pm, char **x)
/* Function to get value of an association parameter */
/**/
static HashTable
HashTable
hashgetfn(Param pm)
{
return pm->u.hash;
@ -1872,7 +1874,7 @@ static int delunset;
/* Function to set value of an association parameter */
/**/
static void
void
hashsetfn(Param pm, HashTable x)
{
if (pm->u.hash && pm->u.hash != x) {
@ -1941,10 +1943,10 @@ nullsetfn(Param pm, char *x)
* containing the integer value. */
/**/
long
zlong
intvargetfn(Param pm)
{
return *((long *)pm->u.data);
return *((zlong *)pm->u.data);
}
/* Function to set value of generic special integer *
@ -1953,9 +1955,9 @@ intvargetfn(Param pm)
/**/
void
intvarsetfn(Param pm, long x)
intvarsetfn(Param pm, zlong x)
{
*((long *)pm->u.data) = x;
*((zlong *)pm->u.data) = x;
}
/* Function to set value of any ZLE-related integer *
@ -1964,9 +1966,9 @@ intvarsetfn(Param pm, long x)
/**/
void
zlevarsetfn(Param pm, long x)
zlevarsetfn(Param pm, zlong x)
{
long *p = (long *)pm->u.data;
zlong *p = (zlong *)pm->u.data;
*p = x;
if (p == &lines || p == &columns)
@ -2086,7 +2088,7 @@ uniqarray(char **x)
/* Function to get value of special parameter `#' and `ARGC' */
/**/
long
zlong
poundgetfn(Param pm)
{
return arrlen(pparams);
@ -2095,7 +2097,7 @@ poundgetfn(Param pm)
/* Function to get value for special parameter `RANDOM' */
/**/
long
zlong
randomgetfn(Param pm)
{
return rand() & 0x7fff;
@ -2105,7 +2107,7 @@ randomgetfn(Param pm)
/**/
void
randomsetfn(Param pm, long v)
randomsetfn(Param pm, zlong v)
{
srand((unsigned int)v);
}
@ -2113,7 +2115,7 @@ randomsetfn(Param pm, long v)
/* Function to get value for special parameter `SECONDS' */
/**/
long
zlong
secondsgetfn(Param pm)
{
return time(NULL) - shtimer.tv_sec;
@ -2123,7 +2125,7 @@ secondsgetfn(Param pm)
/**/
void
secondssetfn(Param pm, long x)
secondssetfn(Param pm, zlong x)
{
shtimer.tv_sec = time(NULL) - x;
shtimer.tv_usec = 0;
@ -2163,7 +2165,7 @@ usernamesetfn(Param pm, char *x)
/* Function to get value for special parameter `UID' */
/**/
long
zlong
uidgetfn(Param pm)
{
return getuid();
@ -2183,7 +2185,7 @@ uidsetfn(Param pm, uid_t x)
/* Function to get value for special parameter `EUID' */
/**/
long
zlong
euidgetfn(Param pm)
{
return geteuid();
@ -2203,7 +2205,7 @@ euidsetfn(Param pm, uid_t x)
/* Function to get value for special parameter `GID' */
/**/
long
zlong
gidgetfn(Param pm)
{
return getgid();
@ -2223,7 +2225,7 @@ gidsetfn(Param pm, gid_t x)
/* Function to get value for special parameter `EGID' */
/**/
long
zlong
egidgetfn(Param pm)
{
return getegid();
@ -2241,7 +2243,7 @@ egidsetfn(Param pm, gid_t x)
}
/**/
long
zlong
ttyidlegetfn(Param pm)
{
struct stat ttystat;
@ -2345,7 +2347,7 @@ lcsetfn(Param pm, char *x)
/* Function to get value for special parameter `HISTSIZE' */
/**/
long
zlong
histsizegetfn(Param pm)
{
return histsiz;
@ -2355,7 +2357,7 @@ histsizegetfn(Param pm)
/**/
void
histsizesetfn(Param pm, long v)
histsizesetfn(Param pm, zlong v)
{
if ((histsiz = v) <= 2)
histsiz = 2;
@ -2365,7 +2367,7 @@ histsizesetfn(Param pm, long v)
/* Function to get value for special parameter `ERRNO' */
/**/
long
zlong
errnogetfn(Param pm)
{
return errno;
@ -2626,11 +2628,11 @@ delenv(char *x)
}
/**/
static void
convbase(char *s, long v, int base)
void
convbase(char *s, zlong v, int base)
{
int digs = 0;
unsigned long x;
zulong x;
if (v < 0)
*s++ = '-', v = -v;
@ -2774,7 +2776,11 @@ printparamnode(HashNode hn, int printflags)
break;
case PM_INTEGER:
/* integer */
#ifdef ZSH_64_BIT_TYPE
fputs(output64(p->gets.ifn(p)), stdout);
#else
printf("%ld", p->gets.ifn(p));
#endif
break;
case PM_ARRAY:
/* array */

View file

@ -51,7 +51,7 @@ extern int tputs _((char *cp, int affcnt, int (*outc) (int)));
# define WRITE_ARG_2_T char *
#endif
#if defined(__hpux) && defined(_HPUX_SOURCE)
#if defined(__hpux) && defined(_HPUX_SOURCE) && !defined(_XPG4_EXTENDED)
# define SELECT_ARG_2_T int *
#else
# define SELECT_ARG_2_T fd_set *

View file

@ -99,6 +99,8 @@ stringsubst(LinkList list, LinkNode node, int ssub)
while (!errflag && *str) {
if ((qt = *str == Qstring) || *str == String) {
if (str[1] == Inpar) {
if (!qt)
mult_isarr = 1;
str++;
goto comsub;
} else if (str[1] == Inbrack) {
@ -249,6 +251,7 @@ singsub(char **s)
* The mult_isarr variable is used by paramsubst() to tell if it yields *
* an array. */
/**/
static int mult_isarr;
/**/
@ -282,6 +285,8 @@ multsub(char **s, char ***a, int *isarr, char *sep)
}
*s = sepjoin(r, NULL);
mult_isarr = omi;
if (isarr)
*isarr = 0;
return 0;
}
if (l)
@ -666,7 +671,7 @@ get_intarg(char **s)
{
char *t = get_strarg(*s + 1);
char *p, sav;
long ret;
zlong ret;
if (!*t)
return -1;
@ -719,7 +724,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
char *sep = NULL, *spsep = NULL;
char *premul = NULL, *postmul = NULL, *preone = NULL, *postone = NULL;
char *replstr = NULL; /* replacement string for /orig/repl */
long prenum = 0, postnum = 0;
zlong prenum = 0, postnum = 0;
int copied = 0;
int arrasg = 0;
int eval = 0;
@ -751,7 +756,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
} else if (*s == '(' || *s == Inpar) {
char *t, sav;
int tt = 0;
long num;
zlong num;
int escapes = 0;
int klen;
#define UNTOK(C) (itok(C) ? ztokens[(C) - Pound] : (C))
@ -1678,13 +1683,13 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
static char *
arithsubst(char *a, char **bptr, char *rest)
{
char *s = *bptr, *t, buf[DIGBUFSIZE];
char *b = buf;
long v;
char *s = *bptr, *t;
char buf[DIGBUFSIZE], *b = buf;
zlong v;
singsub(&a);
v = matheval(a);
sprintf(buf, "%ld", v);
convbase(buf, v, 0);
t = *bptr = (char *)ncalloc(strlen(*bptr) + strlen(buf) + strlen(rest) + 1);
t--;
while ((*++t = *s++));

View file

@ -27,12 +27,6 @@
*
*/
#ifdef __hpux
# define _INCLUDE_POSIX_SOURCE 1
# define _INCLUDE_XOPEN_SOURCE 1
# define _INCLUDE_HPUX_SOURCE 1
#endif
#ifdef sinix
# define _XPG_IV 1
#endif
@ -401,9 +395,10 @@ struct timezone {
#endif
/* DIGBUFSIZ is the length of a buffer which can hold the -LONG_MAX-1 *
* (or with ZSH_64_BIT_TYPE maybe -LONG_LONG_MAX-1) *
* converted to printable decimal form including the sign and the *
* terminating null character. Below 0.30103 > lg 2. */
#define DIGBUFSIZE ((int)(((sizeof(long) * 8) - 1) * 0.30103) + 3)
#define DIGBUFSIZE ((int)(((sizeof(zlong) * 8) - 1) * 0.30103) + 3)
/* If your stat macros are broken, we will *
* just undefine them. */
@ -609,3 +604,12 @@ extern short ospeed;
#ifndef O_NOCTTY
# define O_NOCTTY 0
#endif
#ifdef _LARGEFILE_SOURCE
#ifdef HAVE_FSEEKO
#define fseek fseeko
#endif
#ifdef HAVE_FTELLO
#define ftell ftello
#endif
#endif

View file

@ -134,7 +134,7 @@ zerrnam(const char *cmd, const char *fmt, const char *str, int num)
fmt++;
}
if (unset(SHINSTDIN) && lineno)
fprintf(stderr, " [%ld]\n", lineno);
fprintf(stderr, " [%ld]\n", (long)lineno);
else
putc('\n', stderr);
fflush(stderr);
@ -1096,15 +1096,15 @@ skipparens(char inpar, char outpar, char **s)
return level;
}
/* Convert string to long. This function (without the z) *
* is contained in the ANSI standard C library, but a lot *
* of them seem to be broken. */
/* Convert string to zlong (see zsh.h). This function (without the z) *
* is contained in the ANSI standard C library, but a lot of them seem *
* to be broken. */
/**/
long
zlong
zstrtol(const char *s, char **t, int base)
{
long ret = 0;
zlong ret = 0;
int neg;
while (inblank(*s))

View file

@ -31,6 +31,7 @@ compctlreadptr
cond_match
cond_str
cond_val
convbase
coprocin
coprocout
countlinknodes
@ -45,6 +46,7 @@ deletehashtable
deleteparamdefs
deletewrapper
domatch
dosetopt
doshfunc
down_histent
dputs
@ -52,6 +54,7 @@ dquotedztrdup
dummy_list
dupstring
dupstrpfx
dupstruct
dyncat
emptyhashtable
endparamscope
@ -71,6 +74,7 @@ findcmd
firsthist
freearray
freeheap
freestruct
getaparam
gethashnode
gethashnode2
@ -79,7 +83,9 @@ getintvalue
getiparam
getkeystring
getlinknode
getpermtext
getshfunc
getsignum
getsparam
getstrvalue
gettempname
@ -92,6 +98,8 @@ gotwordptr
hasam
hashcmd
hasher
hashgetfn
hashsetfn
hasspecial
haswilds
hcalloc
@ -156,10 +164,13 @@ noop_function
noop_function_int
old_heaps
optiontab
optlookup
opts
output64
paramtab
parbegin
parend
parse_string
parsereg
parsestr
path
@ -171,6 +182,7 @@ ppid
prefork
prepromptfns
printif
printparamnode
printqt
promptexpand
pushheap
@ -179,6 +191,7 @@ pwd
quietgetevent
quietgethist
quotedzputs
realparamtab
refreshptr
remlpaths
remnulargs
@ -189,11 +202,13 @@ restoredir
reswdtab
retflag
runshfunc
scancountparams
scanhashtable
setaparam
sethparam
setlimits
setsparam
settrap
settyinfo
sfcontext
shfunctab
@ -211,6 +226,7 @@ startparamscope
stdunsetfn
stophist
stopmsg
strgetfn
strinbeg
strinend
strpfx

View file

@ -38,6 +38,21 @@
/* A few typical macros */
#define minimum(a,b) ((a) < (b) ? (a) : (b))
/*
* Our longest integer type: will be a 64 bit either if long already is,
* or if we found some alternative such as long long.
* Currently we only define this to be longer than a long if --enable-lfs
* was given. That enables internal use of 64-bit types even if
* no actual large file support is present.
*/
#ifdef ZSH_64_BIT_TYPE
typedef ZSH_64_BIT_TYPE zlong;
typedef unsigned ZSH_64_BIT_TYPE zulong;
#else
typedef long zlong;
typedef unsigned long zulong;
#endif
/* math.c */
typedef int LV;
@ -228,6 +243,7 @@ typedef struct linklist *LinkList;
typedef struct hashnode *HashNode;
typedef struct hashtable *HashTable;
typedef struct optname *Optname;
typedef struct reswd *Reswd;
typedef struct alias *Alias;
typedef struct param *Param;
@ -685,6 +701,7 @@ typedef int (*CompareFunc) _((const char *, const char *));
/* type of function that is passed to *
* scanhashtable or scanmatchtable */
typedef void (*ScanFunc) _((HashNode, int));
typedef void (*ScanTabFunc) _((HashTable, ScanFunc, int));
typedef void (*PrintTableStats) _((HashTable));
@ -710,6 +727,7 @@ struct hashtable {
ScanFunc enablenode; /* pointer to function to enable a node */
FreeNodeFunc freenode; /* pointer to function to free a node */
ScanFunc printnode; /* pointer to function to print a node */
ScanTabFunc scantab; /* pointer to function to scan table */
#ifdef HASHTABLE_INTERNAL_MEMBERS
HASHTABLE_INTERNAL_MEMBERS /* internal use in hashtable.c */
@ -729,6 +747,15 @@ struct hashnode {
* reserved words. */
#define DISABLED (1<<0)
/* node in shell option table */
struct optname {
HashNode next; /* next in hash chain */
char *nam; /* hash data */
int flags;
int optno; /* option number */
};
/* node in shell reserved word hash table (reswdtab) */
struct reswd {
@ -868,14 +895,14 @@ struct param {
void *data; /* used by special parameter functions */
char **arr; /* value if declared array (PM_ARRAY) */
char *str; /* value if declared string (PM_SCALAR) */
long val; /* value if declared integer (PM_INTEGER) */
zlong val; /* value if declared integer (PM_INTEGER) */
HashTable hash; /* value if declared assoc (PM_HASHED) */
} u;
/* pointer to function to set value of this parameter */
union {
void (*cfn) _((Param, char *));
void (*ifn) _((Param, long));
void (*ifn) _((Param, zlong));
void (*afn) _((Param, char **));
void (*hfn) _((Param, HashTable));
} sets;
@ -883,7 +910,7 @@ struct param {
/* pointer to function to get value of this parameter */
union {
char *(*cfn) _((Param));
long (*ifn) _((Param));
zlong (*ifn) _((Param));
char **(*afn) _((Param));
HashTable (*hfn) _((Param));
} gets;
@ -1155,7 +1182,7 @@ enum {
HUP,
IGNOREBRACES,
IGNOREEOF,
INCREMENTALAPPENDHISTORY,
INCAPPENDHISTORY,
INTERACTIVE,
INTERACTIVECOMMENTS,
KSHARRAYS,
@ -1298,7 +1325,8 @@ struct ttyinfo {
#define TCALLATTRSOFF 21
#define TCSTANDOUTEND 22
#define TCUNDERLINEEND 23
#define TC_COUNT 24
#define TCHORIZPOS 24
#define TC_COUNT 25
#define tccan(X) (tclen[X])
@ -1381,6 +1409,9 @@ struct heap {
struct heap *next; /* next one */
size_t used; /* bytes used from the heap */
struct heapstack *sp; /* used by pushheap() to save the value used */
#ifdef ZSH_64_BIT_TYPE
size_t dummy; /* Make sure sizeof(heap) is a multiple of 8 */
#endif
#define arena(X) ((char *) (X) + sizeof(struct heap))
};

View file

@ -233,3 +233,26 @@
/* Define to 1 if you want to use dynamically loaded modules on HPUX 10 */
#undef HPUXDYNAMIC
/* Define to `unsigned long' if <sys/types.h> doesn't define. */
#undef ino_t
/*
* Definitions used when a long is less than eight byte, to try to
* provide some support for eight byte operations.
*
* Note that ZSH_64_BIT_TYPE, OFF_T_IS_64_BIT, INO_T_IS_64_BIT do *not* get
* defined if long is already 64 bits, since in that case no special handling
* is required.
*/
/* Define to 1 if long is 64 bits */
#undef LONG_IS_64_BIT
/* Define to a 64 bit type if there is one, but long is shorter */
#undef ZSH_64_BIT_TYPE
/* Define to 1 if off_t is 64 bit (for large file support) */
#undef OFF_T_IS_64_BIT
/* Define to 1 if ino_t is 64 bit (for large file support) */
#undef INO_T_IS_64_BIT

7
aclocal.m4 vendored
View file

@ -27,9 +27,12 @@ ac_save_CFLAGS="$CFLAGS"
# breaks some systems' header files.
# AIX -qlanglvl=ansi
# Ultrix and OSF/1 -std1
# HP-UX -Aa -D_HPUX_SOURCE
# HP-UX -Ae or -Aa -D_HPUX_SOURCE
# SVR4 -Xc
for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" -Xc
# For HP-UX, we try -Ae first; this turns on ANSI but also extensions,
# as well as defining _HPUX_SOURCE, and we can then use long long.
# We keep the old version for backward compatibility.
for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" -Xc
do
CFLAGS="$ac_save_CFLAGS $ac_arg"
AC_TRY_COMPILE(

View file

@ -38,15 +38,14 @@ ac_set=''
ac_shellvars='CPPFLAGS LDFLAGS LIBS'
for ac_shellvar in $ac_shellvars; do
case $ac_shellvar in
CPPFLAGS) ac_lfsvar=LFS_CFLAGS ac_lfs64var=LFS64_CFLAGS ;;
*) ac_lfsvar=LFS_$ac_shellvar ac_lfs64var=LFS64_$ac_shellvar ;;
CPPFLAGS) ac_lfsvar=LFS_CFLAGS ;;
*) ac_lfsvar=LFS_$ac_shellvar ;;
esac
eval test '"${'$ac_shellvar'+set}"' = set && ac_set=$ac_shellvar
(getconf $ac_lfsvar) >/dev/null 2>&1 || { ac_result=no; break; }
ac_getconf=`getconf $ac_lfsvar`
ac_getconf64=`getconf $ac_lfs64var`
ac_getconfs=$ac_getconfs$ac_getconf\ $ac_getconf64
eval ac_test_$ac_shellvar="\$ac_getconf\ \$ac_getconf64"
ac_getconfs=$ac_getconfs$ac_getconf
eval ac_test_$ac_shellvar="\$ac_getconf"
done
case "$ac_result$ac_getconfs" in
yes) ac_result=no ;;
@ -60,11 +59,51 @@ AC_MSG_RESULT($ac_result)
case $ac_result in
yes)
for ac_shellvar in $ac_shellvars; do
eval $ac_shellvar=\$ac_test_$ac_shellvar
case "`eval echo $ac_shellvar-\\\$ac_test_$ac_shellvar`" in
CPPFLAGS*-D_LARGEFILE_SOURCE*) eval $ac_shellvar=\$ac_test_$ac_shellvar
;;
CPPFLAGS*)
eval $ac_shellvar="\"-D_LARGEFILE_SOURCE \$ac_test_$ac_shellvar\""
;;
*) eval $ac_shellvar=\$ac_test_$ac_shellvar
esac
done ;;
esac
])
dnl
dnl zsh_64_BIT_TYPE
dnl Check whether the first argument works as a 64-bit type.
dnl If there is a non-zero second argument, we just assume it works
dnl when we're cross compiling. This is to allow a type to be
dnl specified directly as --enable-lfs="long long".
dnl Sets zsh_cv_64_bit_type to the first argument if the test worked,
dnl `no' otherwise. Be careful testing this, as it may produce
dnl two words `long long' on an unquoted substitution.
dnl This macro does not produce messages as it may be run several times
dnl before finding the right type.
dnl
AC_DEFUN(zsh_64_BIT_TYPE,
[AC_TRY_RUN([
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
main()
{
$1 foo = 0;
return sizeof($1) != 8;
}
], zsh_cv_64_bit_type="$1", zsh_cv_64_bit_type=no,
[if test x$2 != x ; then
zsh_cv_64_bit_type="$1"
else
zsh_cv_64_bit_type=no
fi])
])
dnl
dnl zsh_SYS_DYNAMIC_BROKEN
dnl Check whether static/shared library linking is broken.

View file

@ -97,6 +97,12 @@ AC_ARG_ENABLE(zsh-hash-debug,
AC_DEFINE(ZSH_HASH_DEBUG)
fi])
dnl Do you want large file support, if available (mostly Solaris)?
dnl Currently this is only partially implemented.
undefine([lfs])dnl
AC_ARG_ENABLE(lfs,
[ --enable-lfs turn on support for large files])
dnl Pathnames for global zsh scripts
undefine([zshenv])dnl
AC_ARG_ENABLE(etcdir,
@ -206,7 +212,9 @@ AC_PROG_CC
dnl Check for large file support (Solaris).
dnl This needs to be done early to get the stuff into the flags.
if test "x$enable_lfs" != x; then
zsh_LARGE_FILE_SUPPORT
fi
dnl if the user hasn't specified CFLAGS, then
dnl if compiler is gcc, then use -O2 and some warning flags
@ -325,7 +333,7 @@ if test $zsh_cv_c_broken_signed_to_unsigned_casting = yes; then
fi
dnl Checking if the compiler supports variable-length arrays
AC_CACHE_CHECK(if the compiler supports variable-lenth arrays,
AC_CACHE_CHECK(if the compiler supports variable-length arrays,
zsh_cv_c_variable_length_arrays,
[AC_TRY_COMPILE([int foo();], [int i[foo()];],
zsh_cv_c_variable_length_arrays=yes,
@ -511,10 +519,66 @@ dnl --------------
AC_TYPE_SIGNAL
AC_TYPE_PID_T
AC_TYPE_OFF_T
AC_CHECK_TYPE(ino_t, unsigned long)
AC_TYPE_MODE_T
AC_TYPE_UID_T
AC_TYPE_SIZE_T
dnl ------------------------------------------------
dnl Check size of long and try to find a 64-bit type
dnl ------------------------------------------------
dnl AC_CHECK_SIZEOF is no good, because we need the result here,
dnl and that doesn't seem to define a shell parameter.
AC_CACHE_CHECK(if long is 64 bits, zsh_cv_long_is_64_bit,
[AC_TRY_RUN([int main() { return sizeof(long) < 8; }],
zsh_cv_long_is_64_bit=yes,
zsh_cv_long_is_64_bit=no,
zsh_cv_long_is_64_bit=no)])
if test $zsh_cv_long_is_64_bit = yes; then
AC_DEFINE(LONG_IS_64_BIT)
elif test "x$enable_lfs" != x; then
AC_CACHE_CHECK(if compiler has a 64 bit type, zsh_cv_64_bit_type,
[if test "x$enable_lfs" != xyes; then
zsh_64_BIT_TYPE(${enable_lfs})
else
zsh_64_BIT_TYPE(long long)
if test "$zsh_cv_64_bit_type" = no; then
zsh_64_BIT_TYPE(quad_t)
fi
fi
])
if test "$zsh_cv_64_bit_type" != no; then
AC_DEFINE_UNQUOTED(ZSH_64_BIT_TYPE, $zsh_cv_64_bit_type)
AC_CACHE_CHECK(if off_t is 64 bit, zsh_cv_off_t_is_64_bit,
[AC_TRY_RUN([
#include <sys/types.h>
main() { return sizeof(off_t) < 8; }
],
zsh_cv_off_t_is_64_bit=yes,
zsh_cv_off_t_is_64_bit=no,
zsh_cv_off_t_is_64_bit=no)])
if test $zsh_cv_off_t_is_64_bit = yes; then
AC_DEFINE(OFF_T_IS_64_BIT)
fi
AC_CACHE_CHECK(if ino_t is 64 bit, zsh_cv_ino_t_is_64_bit,
[AC_TRY_RUN([
#include <sys/types.h>
main() { return sizeof(ino_t) < 8; }
],
zsh_cv_ino_t_is_64_bit=yes,
zsh_cv_ino_t_is_64_bit=no,
zsh_cv_ino_t_is_64_bit=no)])
if test $zsh_cv_ino_t_is_64_bit = yes; then
AC_DEFINE(INO_T_IS_64_BIT)
fi
fi
fi
dnl Check for sigset_t. Currently I'm looking in
dnl <sys/types.h> and <signal.h>. Others might need
dnl to be added.
@ -641,7 +705,8 @@ AC_CHECK_FUNCS(memcpy memmove \
sigblock sigsetmask sigrelse sighold killpg sigaction getrlimit \
sigprocmask setuid seteuid setreuid setresuid setsid strerror \
nis_list initgroups fchdir cap_get_proc readlink nice \
getgrgid getgrnam getpwent getpwnam getpwuid setpgrp)
getgrgid getgrnam getpwent getpwnam getpwuid setpgrp \
fseeko ftello)
dnl ---------------
dnl CHECK FUNCTIONS
@ -1253,6 +1318,7 @@ zsh version : ${VERSION}
host operating system : ${host_cpu}-${host_vendor}-${host_os}
source code location : ${srcdir}
compiler : ${CC}
preprocessor flags : ${CPPFLAGS}
executable compiler flags : ${CFLAGS}"
if test "$dynamic" = yes; then
echo "\

View file

@ -1080,3 +1080,52 @@ pws: 6257: rewrite 6240 for any old builtin structure after the pipeline
pws: 6258: yet another attempt at the same problem
pws: 6259: second version of compinstall
pws-19
pws: 6263: incrementalappendhistory -> incappendhistory
pws: 6284, should have been in 6269: changes to large file support
pws: 6271: make sure -D_LARGEFILE_SOURCE is defined any time there are
other -D's for large file support
pws: 6272: correct even more mistakes some bozo (guess who) made with
rlim_t: put back RLIM_T_IS_UNSIGNED code.
Tatsuo Furukawa: 6273: don't need to defined _POSIX* flags specially on HPUX
Tatsuo Furukawa: 6274: updated form of zle_refresh patch
Sven: 6278: fix ${$(foo)...} to produce an array
Sven: 6283: compadd -U didn't quote characters properly
Sven: 6285: tty/job handling when executing some command in current shell
code within RHS of pipeline
pws: 6290: parameter module uses global scope, $parameters gets
unreadonlied, gcc warning
pws: 6291: zftp only checks for system type after login.
pws: 6294: typeset -U MANPATH performs uniqueness test straight away
Sven: 6298: (mult_isarr) ${*:-word} didn't use the default word
pws: 6299: if called as su* or -su*, zsh doesn't do sh emulation
Sven: 6301: expanded ignored prefix ignored for testing
Sven: 6302: more list_pipe intricacies
Tanaka Akira: 6303: _path_files: find files after symbolic link
pws: 6307, 6312: wider support for 64-bit integers on 32-bit architectures
pws: 6313: fix 6299 to use $SHELL to decide emulation
pws: 6314: in something like `{ false; } || true', errexit shouldn't be
used at all on the left of the ||
pws: unposted: updated some .distfiles