Subject: shell scripts in emulation
To: None <tech-kern@netbsd.org>
From: Emmanuel Dreyfus <manu@netbsd.org>
List: tech-kern
Date: 10/06/2002 18:19:47
Hi all

I'm trying to fix this problem:
$ cat a.sh                                           
#!/bin/sh
./b.sh

$ cat b.sh  
#!/bin/sh
uname -s

$ /emul/irix/bin/sh ./a.sh
NetBSD

Of course I expected this to display 'IRIX' (uname(2) is correctly
emulated)

Reading a ktrace, we can see this:
   221 sh       CALL  fork
   222 sh       EMUL  "irix o32"
   221 sh       RET   fork 222/0xde
   221 sh       CALL  waitsys(0,0xde,0x7fffe790,0x87,0)
   222 sh       RET   fork 0
   222 sh       CALL  getpid
   222 sh       RET   getpid 222/0xde
   222 sh       CALL  break(0x10104f80)
   222 sh       RET   break 0
   222 sh       CALL  execve(0x10104c74,0x10104868,0x10104870)
   222 sh       NAMI  "./b.sh"
   222 sh       NAMI  "/bin/sh"
   222 sh       EMUL  "netbsd"
   222 sh       RET   execve JUSTRETURN

a.sh is ran by /emul/irix/bin/sh, this is what I wanted. But when b.sh
is launched, the altenate path check is used for the executable (b.sh),
but not for the interpreter, resulting in b.sh being executed by
NetBSD's /bin/sh.

I tried to fix this in sys/kern/exec_script.c:
Index: exec_script.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/exec_script.c,v
retrieving revision 1.30
diff -r1.30 exec_script.c
55a56,57
> #include <compat/common/compat_util.h>
> 
202a205,211
> 
>       /* If we are running a non native emulation, check alternate path */
>       if (epp->ep_esch->es_emul && epp->ep_esch->es_emul->e_path)
>               if ((emul_find(p, NULL, epp->ep_esch->es_emul->e_path, 
>                   shellname, &epp->ep_ndp->ni_dirp, 
>                   CHECK_ALT_FL_EXISTS)) != 0)
>                       epp->ep_ndp->ni_dirp = shellname;

But this does not work, because the exec package has a NULL es_emul at
that time. 

Anyone has a better idea?

While we are there, what about introducing a ENOINTERP error or
something like this to report when the interpreter is missing?

-- 
Emmanuel Dreyfus
manu@netbsd.org