friedl@mtndew.UUCP (Stephen J. Friedl) (06/08/90)
Hi folks, We have an application where a background daemon sometimes has to run a user-supplied program with my arguments, and I am trying to find a good way to do it. I don't want to use system(3) because I want to have control over the fork/exec chain (I catch SIGCLD) and I just don't like using system anyway. Execv works great if I'm running a binary, but it doesn't like to run shell scripts directly (this is Sys V). To get around this I try the following: i = 0; argv[i++] = "/bin/sh"; argv[i++] = userprog; argv[i++] = myarg_1; argv[i++] = myarg_2; argv[i++] = you_get_the_idea; argv[i++] = NULL; execv(argv[1], argv+1); execv(argv[0], argv+0); error("cannot run userprog %s (errno = %d)", userprog, errno); Here I try to run the user's program directly, and if it doesn't work then I try running with with a shell. The problem is that this looks too easy. I have thought about this from a handful of directions and it seems to be workable. Because the first argument is a filename, I don't have to worry about the string containing scam characters such a ! or ; or others. I provide the other args and presumably I trust myself :-). Does anybody see anything wrong with this? Steve -- Stephen J. Friedl, KA8CMY / Software Consultant / Tustin, CA / 3B2-kind-of-guy +1 714 544 6561 / friedl@mtndew.Tustin.CA.US / {uunet,attmail}!mtndew!friedl "I will defend to your death my right to my opinion" - me
limes@ouroborous.Sun.COM (Greg Limes) (06/09/90)
In article <438@mtndew.UUCP> friedl@mtndew.UUCP (Stephen J. Friedl) writes: > i = 0; > argv[i++] = "/bin/sh"; > argv[i++] = userprog; > > execv(argv[1], argv+1); > execv(argv[0], argv+0); > error("cannot run userprog %s (errno = %d)", userprog, errno); what if "userprog" is a CSH script, or a PERL script, or an AWK script, or ... [you get the idea] Of course, if your system does not support scripts for anything other than /bin/sh this should work OK. You might also want to adjust this a bit, so the user's .profile is not read into the shell [speeds up startup]: i = 0; argv[i++] = "/bin/sh"; argv[i++] = "-"; argv[i++] = userprog; execv(argv[2], argv+2); execv(argv[0], argv+0); error("cannot run userprog %s (errno = %d)", userprog, errno); DISCLAIMER: I rarely work under System V, so my point of view may be a little off base; SunOS 4.1 may be "the bridge to SysVr4", but it still gives me all the goodies that I am all to accustomed to :-) without warning me when something ain't SysV'ish. -- Greg Limes limes@sun.com ...!sun!limes 73327,2473 CGDB02A [choose one] A Fool and his Money are soon Partying ...
martin@mwtech.UUCP (Martin Weitzel) (06/09/90)
In article <438@mtndew.UUCP> friedl@mtndew.UUCP (Stephen J. Friedl) writes: [needs to exec a user supplied program, but has to avoid "system"] > Execv works great if I'm running a binary, but it doesn't >like to run shell scripts directly (this is Sys V). To get around >this I try the following: Use "execvp". The "p" stands not only for pathname search, but also will invoke a shell if the supplied program is in reality a script. Eventually you may want to set PATH with `putenv' to make execvp search the desired directories (only). Small flame concerning choice of groups: How about a *first* try with comp.unix.questions - you can have allways a second try with c.u.w, but experience shows you may well receive the attention of a wizard in c.u.q. At most make a crosspost but leave followups to c.u.q. I felt tempted to redirect followups, but as I don't appreciate to have threads pop up "out of nothing" I left it here. -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83
guy@auspex.auspex.com (Guy Harris) (06/12/90)
>You might also want to adjust this a bit, so the user's .profile >is not read into the shell [speeds up startup]: Nope. You must be assuming that a lot of "#! /bin/sh" headers have "#! /bin/sh -" because the author didn't want ".profile" sourced, presumably along lines similar to "#! /bin/csh -f". That's not what the "-" does; it just makes sure that, if the name of the script begins with "-" (e.g., because somebody's trying to break your set-UID shell script - yes, there are other problems with set-UID shell scripts, but...), the shell does *not* treat it as a flag argument. In that regard, it's similar to the "-b" flag in the C shell. The Bourne shell sources ".profile" *only* for login shells (just as the C shell sources ".login" only for login shells - the "-f" in "#! /bin/csh -bf" is there to prevent it from sourcing your ".cshrc").
leo@ehviea.ine.philips.nl (Leo de Wit) (06/12/90)
In article <3449@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes: |>You might also want to adjust this a bit, so the user's .profile |>is not read into the shell [speeds up startup]: | |Nope. You must be assuming that a lot of "#! /bin/sh" headers have |"#! /bin/sh -" because the author didn't want ".profile" sourced, |presumably along lines similar to "#! /bin/csh -f". | |That's not what the "-" does; it just makes sure that, if the name of |the script begins with "-" (e.g., because somebody's trying to break |your set-UID shell script - yes, there are other problems with set-UID |shell scripts, but...), the shell does *not* treat it as a flag |argument. In that regard, it's similar to the "-b" flag in the C shell. | |The Bourne shell sources ".profile" *only* for login shells (just as the |C shell sources ".login" only for login shells - the "-f" in |"#! /bin/csh -bf" is there to prevent it from sourcing your ".cshrc"). Nope. For the man page for 'sh': Invocation. If the first character of argument zero is -, commands are read from $HOME/.profile, if such a file exists. In fact this documentation is not right either, since .profile is read (in the current directory instead of $HOME). Login shells are started with - prepended to the basename of their name as argv[0], so they will read $HOME/.profile. From the csh man page: Argument list processing If argument 0 to the shell is `-' then this is a login shell. What it should say: if argv[0] of the shell starts with a '-', it is treated as a login shell: $HOME/.login is sourced (cause that is what happens). Leo.
guy@auspex.auspex.com (Guy Harris) (06/14/90)
>|The Bourne shell sources ".profile" *only* for login shells (just as the >|C shell sources ".login" only for login shells - the "-f" in >|"#! /bin/csh -bf" is there to prevent it from sourcing your ".cshrc"). > >Nope. For the man page for 'sh': > > Invocation. > If the first character of argument zero is -, commands are > read from $HOME/.profile, if such a file exists. I consider "login shell" basically short for "shell with the first character of argument zero a '-'" (which means that any shell fired up by "login" is a login shell, but so are shells fired up by e.g. "su" when run with the appropriate flag). I considered the more detailed explanation unnecessary and extraneous in this case....
meissner@osf.org (Michael Meissner) (06/14/90)
In article <3459@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes: | >|The Bourne shell sources ".profile" *only* for login shells (just as the | >|C shell sources ".login" only for login shells - the "-f" in | >|"#! /bin/csh -bf" is there to prevent it from sourcing your ".cshrc"). | > | >Nope. For the man page for 'sh': | > | > Invocation. | > If the first character of argument zero is -, commands are | > read from $HOME/.profile, if such a file exists. | | I consider "login shell" basically short for "shell with the first | character of argument zero a '-'" (which means that any shell fired up | by "login" is a login shell, but so are shells fired up by e.g. "su" | when run with the appropriate flag). I considered the more detailed | explanation unnecessary and extraneous in this case.... On the same thread, I sometimes want to create a login shell when I'm not logging in, and not all shell's have a -login switch like bash does. You can get around this by symlinking the appropriate shell to -<shell> in your executable directory, ie: lrwxrwxr-x 1 meissner 19 Jun 2 14:11 -ksh -> /usr/bin/ksh lrwxrwxr-x 1 meissner 7 May 16 15:13 -sh -> /bin/sh lrwxrwxr-x 1 meissner 8 May 16 15:13 -sh5 -> /bin/sh5 -- Michael Meissner email: meissner@osf.org phone: 617-621-8861 Open Software Foundation, 11 Cambridge Center, Cambridge, MA Catproof is an oxymoron, Childproof is nearly so
dik@cwi.nl (Dik T. Winter) (06/15/90)
In article <3459@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes: > > Invocation. > > If the first character of argument zero is -, commands are > > read from $HOME/.profile, if such a file exists. > > I consider "login shell" basically short for "shell with the first > character of argument zero a '-'" (which means that any shell fired up > by "login" is a login shell, but so are shells fired up by e.g. "su" > when run with the appropriate flag). I considered the more detailed > explanation unnecessary and extraneous in this case.... It is indeed extraneous in the context; but I think your position is flawed. Try: PATH=$PATH:. ln -s /bin/sh -sh -sh Now, when you consider this to be a login shell, it becomes another matter, but I think that it is non-intuitive naming. -- dik t. winter, cwi, amsterdam, nederland dik@cwi.nl
guy@auspex.auspex.com (Guy Harris) (06/16/90)
>It is indeed extraneous in the context; but I think your position is flawed. >Try: > PATH=$PATH:. > ln -s /bin/sh -sh > -sh >Now, when you consider this to be a login shell, it becomes another matter, >but I think that it is non-intuitive naming. If somebody really wants to do that, they presumably know what they're doing. The majority of shells invoked with "-" at the front of argv[0] are almost certainly shells fired up from logins, and the second most common set of such shells are fired up from "su"s with the appropriate arguments; I considered the exceptions to be rare enough that confusion from saying "login shell" rather than "shell fired up with '-' in front of its first argument" to be unlikely enough that it wasn't worth using the longer phrase and then explaining that "login" fires shells up with "-" in front of the first argument....