Finding where an executable was run

Mark Dionne md at io.UUCP
Sat May 21 15:13:27 AEST 1988


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



More information about the Comp.unix.wizards mailing list