Path: utzoo!attcan!uunet!mcsun!unido!mikros!mwtech!martin From: martin@mwtech.UUCP (Martin Weitzel) Newsgroups: comp.lang.c Subject: Re: how do I exec() a script Message-ID: <823@mwtech.UUCP> Date: 29 Jun 90 09:22:50 GMT References: <661@kps.UUCP> <1990Jun27.225015.1956@virtech.uucp> Reply-To: martin@mwtech.UUCP (Martin Weitzel) Organization: MIKROS Systemware, Darmstadt/W-Germany Lines: 86 In article <1990Jun27.225015.1956@virtech.uucp> cpcahil@virtech.UUCP (Conor P. Cahill) writes: >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. > >The correct way to do this (one that will work on systems that understand >the "#!" and those that don't) is as follows: Though I usually appreciate Conors experience and good advice, I must object this time: > place "#!/bin/sh" as the first line for the program. Well, there are some good arguments in favor for a first line that starts with a colon (:) in shell scripts. At least this helps in some (IMHO brain damaged) C shells that consider every text file which starts with a hash (#) to be a C-shell script. (I've had some discussions in the past, if it was "legal" for the bourne shell to add #-comments, after the C-shell "invented" them and obviously claimed exclusive rights to use them ...) > in the code that you wish to exec the program do the following: > > execvp("prog",argv); /* argv is setup accordingly */ > > /* > * if we get here, prog was not executed by the kernel, > * so this system doesn't understand "#!" and we must call > * the shell ourselves > */ Wrong: At least in SysV(%) for which I can check this out right now, the facts are that execvp() executes a shell if the given file name turns out to be a text file with appropriate x-bits set. THIS DOESN'T DEPEND ON THE FIRST LINE OF THE TEXT-FILE! Behavior differs with "execv()", which will not only do *no* path search, but also never execute a text file, regardless of what the first line contains (I'm aware the latter was not what Conor claimed). %: If memory serves, behaviour was the same in SysIII-derived XENIX. > arg_str[0] = '\0'; > for(i=0; argv[i] != NULL; i++) > strcat(arg_str,argv[i]); WRONG (forgets to embed blanks or some other IFS-seperator) and DANGEROUS - at least you should count the length of your arguments and allocate space for arg_str dynamically. (I hope that it was not meant this way: As I exec anyway, I may leave total desaster behind me :-).) > > sh_argv[0] = "sh"; > sh_argv[1] = "-c"; > sh_argv[2] = arg_str; > sh_argv[3] = (char *)0; > execvp("sh",sh_argv); > >-c is used so sh will use PATH to find the program. Yes, but this is only *one* of the effects of "-c". Anotherone is that the shell fully re-interprets the arguments. If this is desirable or not will generally depend on the problem, but as the method here was used as substitute for exec-ing a script from the kernel, the behaviour will differ (Again IMHO; I have no such kernel here to check this, but I would be surprised if the kernel had not only mechanisms to exec the program given in the first line, but also to interpret args.) >NOTE: I did not compile or test the above code, your milage may vary. *If* we do so many things manually here, why not open the file, read the first line and exec a given program in case of #!prog in the way UCB-derivates do it in the kernel? Any volunteers to write (and compile and test!!) such code? You should call it something like "ucb_exec" and make the same functions available that are normaly provided by exec. This should not be more than one day work for any halfway experienced C-programmer. -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83