zsh-workers
 help / color / mirror / code / Atom feed
* what is hackzero?
@ 1996-03-30  6:45 Richard J. Coleman
  1996-03-30  7:13 ` Zefram
  0 siblings, 1 reply; 3+ messages in thread
From: Richard J. Coleman @ 1996-03-30  6:45 UTC (permalink / raw)
  To: zsh-workers

Does anyone know what the global variable hackzero
is for?  Offhand I can't figure out what bin_fg is
doing with it.

rc



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: what is hackzero?
  1996-03-30  6:45 what is hackzero? Richard J. Coleman
@ 1996-03-30  7:13 ` Zefram
  1996-03-30 19:33   ` Barton E. Schaefer
  0 siblings, 1 reply; 3+ messages in thread
From: Zefram @ 1996-03-30  7:13 UTC (permalink / raw)
  To: Richard J. Coleman; +Cc: zsh-workers

>Does anyone know what the global variable hackzero
>is for?  Offhand I can't figure out what bin_fg is
>doing with it.

% grep hackzero *
builtin.c:	    strcpy(hackzero, *argv);
globals.h:EXTERN char *hackzero;
init.c:    hackzero = argzero = *argv;

Looks like the shell can write into its argv[0].  Here's the code:

/**/
int
bin_fg(char *name, char **argv, char *ops, int func)
{
    int job, lng, firstjob = -1, retval = 0;

    if (ops['Z']) {
	if (*argv)
	    strcpy(hackzero, *argv);
	return 0;
    }

Okay, "jobs -Z foo" can set the shell's argv[0].  This works (try it),
and is undocumented.  It's a bit dangerous, as exceeding the length of
the actual argv[0] is easy and causes undefined behaviour.  It does in
fact cause trouble on some Unices if the length differs at all.

Note that argzero can't be used in place of hackzero, because it's only
a copy of argv[0].  And as argzero is what $0 refers to, $0 is
unaffected by the jobs -Z thing.

I think it's actually a potentially useful feature, as it allows a
long-running zsh script to change its name, in the manner of some
daemons.  (Actually, it should be just about possible to implement
init(8) in zsh... frightening, isn't it?)

Does someone here know enough about modifying argv to advise how this
could be modified to work better?

-zefram



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: what is hackzero?
  1996-03-30  7:13 ` Zefram
@ 1996-03-30 19:33   ` Barton E. Schaefer
  0 siblings, 0 replies; 3+ messages in thread
From: Barton E. Schaefer @ 1996-03-30 19:33 UTC (permalink / raw)
  To: Zefram, Richard J. Coleman, zsh-workers

On Mar 30,  7:13am, Zefram wrote:
} Subject: Re: what is hackzero?
}
} >Does anyone know what the global variable hackzero
} >is for?  Offhand I can't figure out what bin_fg is
} >doing with it.
} 
} Looks like the shell can write into its argv[0].
} 
} Okay, "jobs -Z foo" can set the shell's argv[0].  This works (try it),
} and is undocumented.  It's a bit dangerous, as exceeding the length of
} the actual argv[0] is easy and causes undefined behaviour.  It does in
} fact cause trouble on some Unices if the length differs at all.
} 
} Does someone here know enough about modifying argv to advise how this
} could be modified to work better?

I believe this is the only way to do it that ever makes the new string
visible outside the executable, because process table readers like "ps"
use the standard kernel process data structures to extract the arguments.
(On some UNIX flavors, a copy of the arguments is maintained for use by
"ps" et. al., so there's no way to hide the original arguments on those.)

My kernel hacking is a few years' rusty, but a peek at linux sources
shows the following to be not far wrong:

Typically, all the argument strings are packed together, separated by
a single '\0' string-terminator (this may vary for systems with pointer
alignment constraints).  Elements of the argv array then point to the
beginning of each string within that block.

A typical "ps" would get the original address of argv[0] and the length
of the block from the kernel data structure, and then just spit out that
many bytes as the arguments (replacing embedded '\0' terminators with
spaces).  So if you copy a shorter string over any argument, you may
still see remnants of the longer string in the "ps" output.  I'm pretty
sure BSD 4.[23] works (worked?) this way.  So you can't reliably change
argv[0] by changing the pointer, because "ps" doesn't look at the value
of argv[0] in process space, it looks at the original value in the kernel
process table.

If the layout of the args is more complex, "ps" has to know a little more
about how to find each one, so changing the pointer argv[0] might work,
or it might just make things worse.

In the BSD 4.2-ish case, you can scribble whatever you like out as far as
the total length of all the strings (as long as nothing in your program
ever wants to access argv[n] again).

Z-Mail overwrites some if its arguments as it parses them, to convert
from GNU-ish full words into old-UNIX-ish single letters.  On Linux,
you get this:

zmail -echo -shell -folder /dev/null -exec 'sh "ps xww | grep zm"'
zmail -E    -S     -f      /dev/null -exec sh "ps xww | grep zm"

So the arguments aren't copied, but the kernel is maintaining a pointer
and length of each one somewhere outside the process, and "ps" uses that.

But on IRIX4, the original arguments are copy-preserved by the kernel:

zmail -echo -shell -folder /dev/null -exec 'sh "ps -f -u schaefer | grep zm"'
zmail -echo -shell -folder /dev/null -exec sh "ps -f -u schaefer | grep zm"

And on SunOS 4.1.3, the overwritten args are lost completely, because
changing (in this case, incrementing) argv[n] actually does change where
"ps" reads the strings from -- but note that the kernel still knows what
the original argv[0] was, so "ps" adds it in parens:

zmail -echo -shell -folder /dev/null -exec 'sh "ps xww | grep zm"'
 /dev/null -exec sh "ps xww | grep zm" (zmail)

In short, it's a useful hack in some cases, but whether (or how) it works
is hopelessly dependent on the kernel implementation.

-- 
Bart Schaefer                     Vice President, Technology, Z-Code Software
schaefer@z-code.com                  Division of NCD Software Corporation
http://www.well.com/www/barts



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~1996-03-30 19:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1996-03-30  6:45 what is hackzero? Richard J. Coleman
1996-03-30  7:13 ` Zefram
1996-03-30 19:33   ` Barton E. Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).