brian@bucc2.UUCP (05/16/88)
> /* Written 4:25 pm May 11, 1988 by sun.uucp!limes in bucc2:comp.unix.wiza */ > In article <4527@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes: > >If exec() would pass this value to the executed program, say as > >argv[-1], then a program could reliably know its own name, and apply a > >simple transformation to it to find its data files (e.g. for program > >"XXXXXX/foo", its data files are found in "XXXXXX/lib/foo/whatever"). > > In Turbo-C, Borland passes the complete path name of the program > executed as argv[0]. This may be specific to Turbo-C, or may be > general across MS-DOS. Are there any programs that this would break? I believe this is general to MS-DOS, since Microsoft C does the same thing. It is annoying when you want to use the program name in error messages, like: fprintf(stderr, "%s: %s\n", argv[0], errmsg); Not only do you get the full pathname, but it's probably in uppercase as well... ............................................................................... When the going gets weird, the weird turn pro. Brian Michael Wendt UUCP: {cepu,ihnp4,uiucdcs,noao}!bradley!brian Bradley University ARPA: cepu!bradley!brian@seas.ucla.edu (309) 677-2230 ICBM: 40 40' N 89 34' W
gordon@sneaky.UUCP (05/18/88)
> The convention used by ksh-i is to put the full pathname used to exec a file > in the environment variable "_". This makes a lot of sense to me, and seems > as good an example of prior art as anything else out there. It is also cleaner > than most of the suggestions we've seen so far in this discussion, not > requiring any change to the kernel or the C calling conventions. Great. Now all the programs that use one of the forms of "exec" have to fiddle with the environment (remove the old value of $_, if present, and add a new one). Either that, or you change the exec*() family of library interface routines (you don't really want this in the kernel, do you?) to do it for you, and relink *EVERYTHING*. (Does anyone REALLY want exec*() to call malloc()? Anyone got a good alternative?) If you just put the code in the shells (remember, uucico is a commonly used shell), then I would expect mass confusion when /bin/cc is invoked and $_ comes out as "/bin/make". Or maybe it ends up undefined. There are lots of programs out there that don't use a shell if the command is simple enough to parse and exec by itself. Gordon L. Burditt ...!ihnp4!sys1!sneaky!gordon
md@io.UUCP (Mark Dionne) (05/20/88)
I believe system V is different from BSD: argv[0] is always the full path name of the executable. -- ...!mit-eddie!ileaf!md Mark Dionne, Interleaf ...!sun!sunne!ileaf!md Ten Canal Park, Cambridge, MA 02141 (617) 577-9813 x5551
dg@lakart.UUCP (David Goodenough) (05/20/88)
Net-people:
I am wrong - I am wrong - I am wrong - I admit it. I have had more
mail telling me this than you can shake a stick at. Two points:
A) Valid objection: with a path == ( . /bin /usr/bin /usr/local )
I get into trouble. This is a real problem, because it happens
whenever I fire up something that is not a full path, or not in
the current directory (i.e. /bin/cat).
B) Less often a problem, but still irritating - things like csh / sh / getty
whose argv[0] is something real weird (e.g. - -u or whatever). This
rarely happens for user programs, except when doing a su perhaps.
An interesting notion :-)
On BSD 4.3, most binaries are demand page loaded. This means that the
"text image" is very closely linked to the executable (Let's forget
shell scripts for a moment :-). Does this mean that the kernel's
process tables have some reference to the filesystem and inode number
of the executable, because if so you could do a real neato job with
find - popen("find /filesystem -inum %d", "r"); :-) :-) :-)
--
dg@lakart.UUCP - David Goodenough +---+
| +-+-+
....... !harvard!adelie!cfisun!lakart!dg +-+-+ |
+---+
guy@gorodish.Sun.COM (Guy Harris) (05/21/88)
> I believe system V is different from BSD: argv[0] is always > the full path name of the executable. OK, time for some reality: argv[0] is always whatever the process that started up the program in question passed via the argument list. This could be the full path name of the executable. It could be the last component of that path name. It could be the first 10 words of the Magna Carta. It could be anything the program doing the "exec*" call wanted it to be. Thus, it's not a question of which version of the OS you're running. It's a question of what program fired up the executable. I tried it under: the "previous" version of the Korn shell (i.e., pre-"ksh-i" - we don't have "ksh-i" *sigh*); it does not pass the full path name of the executable, but passes the name you typed (assuming no aliases, etc.). The SunOS 4.0 Bourne shell, based on the S5R3.1 Bourne shell; it does not pass the full path name of the executable, but passes the name you typed. The SunOS 4.0 C shell, based on the 4.3BSD C shell; it does not pass the full path name of the executable, but passes the name you typed. The 4.3BSD Bourne shell, based on the V7 Bourne shell; it does not pass the full path name of the executable, but passes the name you typed. The 4.3BSD C shell; it does not pass the full path name of the executable, but passes the name you typed. The System V Release 3.1 Bourne shell; it does not pass the full path name of the executable, but passes the name you typed. I think there seems to be a pattern here....
wswietse@eutrc3.UUCP (Wietse Venema) (05/21/88)
In article <611@io.UUCP> md@marvin.UUCP (Mark Dionne) writes: >I believe system V is different from BSD: argv[0] is always >the full path name of the executable. No, with SysV, argv[0] is the command, just as in BSD. You are confusing MS-DOS with SysV UNIX. -- uucp: mcvax!eutrc3!wswietse | Eindhoven University of Technology bitnet: wswietse@heithe5 | Dept. of Mathematics and Computer Science surf: tuerc5::wswietse | Eindhoven, The Netherlands.
aglew@urbsdc.Urbana.Gould.COM (05/21/88)
> "This would make lots of application programs easier to > install; you just copy it into somewhere on your PATH and it > will run." > >If an application uses this scheme to find its associated files, some >useful Unix idioms cease to work. For example, say that "rn" lives in >/usr/news, but I don't want /usr/news in my PATH (too many nasty >commands are also there). At present I can put a link to /usr/news/rn >in a directory that is in my path (e.g., my local bin). With the >proposed scheme, that would cause rn to look in my_local_bin/lib/* for >its data files instead of in /usr/news/lib/*. > > -=- Andrew Klossner (decvax!tektronix!tekecs!andrew) [UUCP] Easy enough to do a readlink(), if you have used a symlink to place the command on your path.
md@io.UUCP (Mark Dionne) (05/21/88)
I previously wrote: > I believe system V is different from BSD: argv[0] is always > the full path name of the executable. As several people have pointed out, I was either wrong or overgeneralizing. Sorry. I based this belief on what I was told when a "get_exec_name" routine we wrote was ported (by others) to AIX on an IBM RT. I don't have access to an RT right now, so I can't verify it. Here's a routine for finding the pathname of an executable. It might not be perfect, but it illustrates a couple of twists: watch out for directories, and watch out for "." and ".." #include <sys/file.h> #include <sys/types.h> #include <sys/stat.h> #define PATHSIZE 256 GetExecName(argv0, buf) char* argv0; char* buf; /* pathname returnes in this buffer */ { char *path; char *getenv(), *getwd(), *getPathElement(); if (*argv0 == '/') { strcpy( buf, argv0 ); return(0); } if (*argv0 == '.' && *(argv0+1) == '/') { strcpy(buf, argv0 + 2); goto found; } if (*argv0 == '.' && *(argv0+1) == '.' && *(argv0+2) == '/' ) { strcpy(buf, argv0); goto found; } path = getenv("PATH"); while(path != 0) { path = getPathElement(path, buf); if (*buf == '\0') continue; /* ignore empty components (::) */ strcat(buf, "/"); strcat(buf, argv0); if (access(buf, X_OK) == 0) { /* watch out for directories that happen to match */ if((get_file_mode(buf) & S_IFMT) == S_IFDIR) continue; /* Got it. Now if it is not absolute, just prepend cwd */ if (*buf != '/') { char tmpbuf[PATHSIZE]; found: strcpy(tmpbuf, buf); if ( getwd(buf) == 0 ) break; strcat(buf, "/"); strcat( buf, tmpbuf ); } return(0); } } /* Not found */ *buf = 0; return(-1); } long get_file_mode( path) char* path; { struct stat stats; if ( stat( path, &stats) < 0 ) return ( -1 ); return ( stats.st_mode ); } /* Strip off first element of path into buf. Returns new path. */ char *getPathElement( path, buf ) register char *path; register char *buf; { while ( (*buf = *path++) != '\0' ) { if (*buf == ':') { *buf = '\0'; return(path); } ++buf; } return(0); } #include <stdio.h> main(argc, argv, envp) int argc; char **argv; char **envp; { char buf[PATHSIZE]; printf("Argv[0] : %s\n", argv[0]); printf("Return value: %d\n", GetExecName(argv[0], buf)); printf("Exec name: %s\n", buf); } -- ...!mit-eddie!ileaf!md Mark Dionne, Interleaf ...!sun!sunne!ileaf!md Ten Canal Park, Cambridge, MA 02141 (617) 577-9813 x5551