Path: utzoo!attcan!uunet!decwrl!nsc!voder!pyramid!moliver From: moliver@pyrshadow (Mike Oliver) Newsgroups: comp.lang.c Subject: Re: how do I exec() a script Message-ID: <117963@pyramid.pyramid.com> Date: 27 Jun 90 19:57:44 GMT Sender: daemon@pyramid.pyramid.com Reply-To: moliver@shadow.pyramid.com (Mike Oliver) Followup-To: comp.unix.questions Organization: Pyramid Technology Corp., Mountain View, CA Lines: 103 This really isn't (an answer to) a C question; followups have been redirected to comp.unix.questions. In article <661@kps.UUCP> llj@kps.se (Leif Ljung /DP) writes: >I have a program that I want to do a general exec(2) sometimes >executing a binary program, sometimes a shell-script preferably >using PATH. >Say I have the program `prog' - if this is a script I add the >'#! /bin/sh' at the top. Can I exec(2) that? No. I don't have a problem doing this. I don't know how you're managing the PATH variable, but if you provide the coorect relative path of the target file you can exec() it regardless of whether it's a program or an interpreter script. There's a tiny demo program on the end of this post - you might want to compare it against your code. My favourite way to get this wrong is to forget that *argv[0] in the exec() call should be the name of the executable, usually the same as the path that you supply as the first parameter to exec(). If you're still stuck after that, mail me your code and I'll see if I can find what might be causing the problem. >The system is a Pyramid running BSD4.3. Meaning that it's running OSx and you're working in the ucb universe ? If you're building in the att universe you should be aware that the ability to exec() a script is configurable, and it defaults to being disabled. Don't ask me why, I don't know. This hinges on the universe that your program was built under, not on the universe in which it runs. Check your makefile to make sure the build isn't running under att. If that's the case you'll get an "Exec format error" when you try to exec a script. Demo program and sample script are below, hit "n" if you've had enough already. --- 8< ------ 8< ------ 8< ------ 8< ------ 8< ------ 8< ------ 8< --- /* This program will exec() its first argument, passing any * additional arguments to the exec()'d program. * * Try "a.out /bin/ls -l" for starters. Then try the script * below, which will print "hello world" and then print its * arguments. */ #include #include main( argc, argv ) int argc; char **argv; { extern char **environ; union wait waitstatus; char *cmdpath; if ( argc < 2 ) { /* Not enough info on the command line. */ fprintf( stderr, "%s: %s [args ...]\n", argv[0], argv[0] ); exit( -1 ); } switch ( fork() ) { case 0: /* This is the child */ cmdpath = *(++argv); (void) execve( cmdpath, argv, environ ); perror( "child ... execve() failed" ); break; case -1: /* This is the parent, and the fork failed */ perror( argv[0] ); break; default: /* This is the parent, the fork() worked */ fprintf( stdout, "parent ... deceased PID is %d\n", wait( &waitstatus ) ); fprintf( stdout, " ... status is %d\n", waitstatus.w_status ); break; } } --- 8< ------ 8< ------ 8< ------ 8< ------ 8< ------ 8< ------ 8< --- #! /bin/sh # Simple script, just says "hello world" and then prints its arguments. echo "hello world" echo $* --- 8< ------ 8< ------ 8< ------ 8< ------ 8< ------ 8< ------ 8< --- Cheers, Mike. moliver@pyramid.com {allegra,decwrl,hplabs,munnari,sun,utai,uunet}!pyramid!moliver