Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: /usr/bin/script annoyance



In the last episode (Sep 16), Ken Lareau said:
>> Oh weird.  I just looked at the source to typescript under FreeBSD,
>> and it reads in part:
>>
>>	char *shell;
>>
>>	shell = getenv("SHELL");
>>	if (shell == NULL)
>>		shell = _PATH_BSHELL;
>>
>>	execl(shell, "sh", "-i", NULL);
>>
>> So argv[0] is "sh", and it's entering /bin/sh compatibility mode. 
>> This is almost _exactly_ the problem Paul Lew reported to the zsh
>> list on Aug 11 (mailinglist article archive/latest/4298).  Both Bart
>> Schaefer and zefram posted ugly workarounds :)
> 
> Hmm... I did a 'truss' on the 'script <file>' command and dumped it
> to a file, and here's what I see when it calls the shell:
> 
>   execve("/software/bin/zsh", 0xEFFFF918, 0xEFFFFA60)  argc = 2
> 
> Of course I have no idea what the 2nd and 3rd arguments are to the
> execve command, but it would seem to me that it should start up as a
> regular zsh shell, no?  (Please tell me if I'm missing something
> blatently obvious here.)

The prototype for the execve syscall is usually

execve(const char *path, char *const argv[], char *const envp[])

and the string that determines sh compatibility mode for zsh is not
'path', but 'argv[0]'.  If you were to run script under dbx and break
on the execve call, I'd bet anything that the contents of the string at
0xEFFFF918 is "sh".

Zefram's solution to this problem is the shortest:

> Alternatively, set your SHELL to be the executable of this program:
>
>        extern char **environ;
>        int main(int argc, char **argv)
>        {
>            if(argc != 0)
>                argv[0] = "zsh";
>            execve("/usr/local/bin/zsh", argv, environ);
>            _exit(1);
>        }

That'll guarantee that zsh gets called as "zsh".

	-Dan Nelson
	dnelson@xxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author