Problem with execvp and shell scripts

The execvp call will fail and return ENOEXEC (Exec format error)
if the file given is a shell script instead of an executable. The
man page for execvp states it should work, and one would expect
shell scripts to work. Here is a simple test case:

-------------- test_script
#!/bin/sh

echo “Test script called”
exit 0

--------------- x.c
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <process.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

main()
{
int pid, ret, status;
char *dargv[10];

if ((pid = fork()) != 0) {
/* Parent /
if (pid == -1) {
perror(“fork”);
exit(1);
}
while (pid != wait(&status))
;
} else {
/
Child */
dargv[0] = “./test_script”;
dargv[1] = NULL;
printf(“Child: About to execvp test_script\n”);
execvp(dargv[0], dargv);
perror(“execvp”);
exit(1);
}
printf(“Parent done\n”);
}


Save test_script to a file of that name, chmod a+x and then compile x.c.

Here is the output I get:
$ ./x
Child: About to execvp test_script
execvp: Exec format error
Parent done
$ ls -l test_script
-rwxrwxr-x 1 sue db 45 Aug 13 12:48 test_script

I discovered this problem when attempting to use the ‘exec’ command in
Tcl8.3.2, but it is not Tcl related, as the above program illustrates.

I would eagerly like a workaround for this. Thanks!

Sue LoVerso
sue@sleepycat.com

Didn’t you get my email about this? The kernel doesn’t have
a #! loader.

I asked about why, and nobody could come up with a good reason,
so I hope that it will be added in the near future.

For now, the only workaround is to add “/bin/sh”, “-c”
to the beginning of your args.

Susan LoVerso <sue@loverso.southborough.ma.us> wrote:

The execvp call will fail and return ENOEXEC (Exec format error)
if the file given is a shell script instead of an executable. The
man page for execvp states it should work, and one would expect
shell scripts to work. Here is a simple test case:

-------------- test_script
#!/bin/sh

echo “Test script called”
exit 0

--------------- x.c
#include <errno.h
#include <stdio.h
#include <string.h
#include <process.h
#include <sys/types.h
#include <sys/wait.h
#include <unistd.h

main()
{
int pid, ret, status;
char *dargv[10];

if ((pid = fork()) != 0) {
/* Parent /
if (pid == -1) {
perror(“fork”);
exit(1);
}
while (pid != wait(&status))
;
} else {
/
Child */
dargv[0] = “./test_script”;
dargv[1] = NULL;
printf(“Child: About to execvp test_script\n”);
execvp(dargv[0], dargv);
perror(“execvp”);
exit(1);
}
printf(“Parent done\n”);
}


Save test_script to a file of that name, chmod a+x and then compile x.c.

Here is the output I get:
$ ./x
Child: About to execvp test_script
execvp: Exec format error
Parent done
$ ls -l test_script
-rwxrwxr-x 1 sue db 45 Aug 13 12:48 test_script

I discovered this problem when attempting to use the ‘exec’ command in
Tcl8.3.2, but it is not Tcl related, as the above program illustrates.

I would eagerly like a workaround for this. Thanks!

Sue LoVerso
sue@sleepycat.com


cburgess@qnx.com

You aren’t first one to ask Colin, and when I did they did not have any
answer either and still it was not fixed since then (about year ago).
Hopefully your mighty powers will change that :wink:

  • igor

Colin Burgess wrote:

Didn’t you get my email about this? The kernel doesn’t have
a #! loader.

I asked about why, and nobody could come up with a good reason,
so I hope that it will be added in the near future.

For now, the only workaround is to add “/bin/sh”, “-c”
to the beginning of your args.

Susan LoVerso <> sue@loverso.southborough.ma.us> > wrote:
The execvp call will fail and return ENOEXEC (Exec format error)
if the file given is a shell script instead of an executable. The
man page for execvp states it should work, and one would expect
shell scripts to work. Here is a simple test case:

-------------- test_script
#!/bin/sh

echo “Test script called”
exit 0

--------------- x.c
#include <errno.h
#include <stdio.h
#include <string.h
#include <process.h
#include <sys/types.h
#include <sys/wait.h
#include <unistd.h

main()
{
int pid, ret, status;
char *dargv[10];

if ((pid = fork()) != 0) {
/* Parent /
if (pid == -1) {
perror(“fork”);
exit(1);
}
while (pid != wait(&status))
;
} else {
/
Child */
dargv[0] = “./test_script”;
dargv[1] = NULL;
printf(“Child: About to execvp test_script\n”);
execvp(dargv[0], dargv);
perror(“execvp”);
exit(1);
}
printf(“Parent done\n”);
}


Save test_script to a file of that name, chmod a+x and then compile x.c.

Here is the output I get:
$ ./x
Child: About to execvp test_script
execvp: Exec format error
Parent done
$ ls -l test_script
-rwxrwxr-x 1 sue db 45 Aug 13 12:48 test_script

I discovered this problem when attempting to use the ‘exec’ command in
Tcl8.3.2, but it is not Tcl related, as the above program illustrates.

I would eagerly like a workaround for this. Thanks!

Sue LoVerso
sue@sleepycat.com


cburgess@qnx.com