diff options
author | Christopher Faylor <me@cgf.cx> | 2000-02-17 19:39:52 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2000-02-17 19:39:52 +0000 |
commit | 8a0efa53e44919bcf5ccb1d3353618a82afdf8bc (patch) | |
tree | 68c3dbf3f2c6fd5d49777def9914d77b5cd4589d /newlib/libc/posix/execvp.c | |
parent | 1fd5e000ace55b323124c7e556a7a864b972a5c4 (diff) | |
download | cygnal-8a0efa53e44919bcf5ccb1d3353618a82afdf8bc.tar.gz cygnal-8a0efa53e44919bcf5ccb1d3353618a82afdf8bc.tar.bz2 cygnal-8a0efa53e44919bcf5ccb1d3353618a82afdf8bc.zip |
import newlib-2000-02-17 snapshot
Diffstat (limited to 'newlib/libc/posix/execvp.c')
-rw-r--r-- | newlib/libc/posix/execvp.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/newlib/libc/posix/execvp.c b/newlib/libc/posix/execvp.c new file mode 100644 index 000000000..6957f61b2 --- /dev/null +++ b/newlib/libc/posix/execvp.c @@ -0,0 +1,88 @@ +/* execvp.c */ + +/* This and the other exec*.c files in this directory require + the target to provide the _execve syscall. */ + +#include <_ansi.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <ctype.h> + +#ifdef __CYGWIN32__ +static char path_delim; +#define PATH_DELIM path_delim +#else +#define PATH_DELIM ':' +#endif + +/* + * Copy string, until c or <nul> is encountered. + * NUL-terminate the destination string (s1). + */ + +static char * +_DEFUN (strccpy, (s1, s2, c), + char *s1 _AND + char *s2 _AND + char c) +{ + char *dest = s1; + + while (*s2 && *s2 != c) + *s1++ = *s2++; + *s1 = 0; + + return dest; +} + +int +_DEFUN (execvp, (file, argv), + _CONST char *file _AND + char * _CONST argv[]) +{ + char *path = getenv ("PATH"); + char buf[MAXNAMLEN]; + + /* If $PATH doesn't exist, just pass FILE on unchanged. */ + if (!path) + return execv (file, argv); + + /* If FILE contains a directory, don't search $PATH. */ + if (strchr (file, '/') +#ifdef __CYGWIN32__ + || strchr (file, '\\') +#endif + ) + return execv (file, argv); + +#ifdef __CYGWIN32__ + /* If a drive letter is passed, the path is still an absolute one. + Technically this isn't true, but Cygwin is currently defined so + that it is. */ + if ((isalpha (file[0]) && file[1] == ':') + || file[0] == '\\') + return execv (file, argv); +#endif + +#ifdef __CYGWIN32__ + path_delim = cygwin_posix_path_list_p (path) ? ':' : ';'; +#endif + + while (*path) + { + strccpy (buf, path, PATH_DELIM); + /* An empty entry means the current directory. */ + if (*buf != 0) + strcat (buf, "/"); + strcat (buf, file); + if (execv (buf, argv) == -1 && errno != ENOENT) + return -1; + while (*path && *path != PATH_DELIM) + path++; + if (*path == PATH_DELIM) + path++; /* skip over delim */ + } + + return -1; +} |