mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-01 03:50:28 +08:00
199359f062
* libc/stdlib/abort.c: changed description: uses "raise" instead of "getpid" and "kill"; added: uses "write" and "_exit". Also included unistd.h for "_exit" prototype. * libc/stdlib/system.c: included unistd.h for "execve" prototype, reent.h for "_fork_r" and "_wait_r" prototypes. (do_system): changed extern char *environ[] to POSIX-friendly extern char **environ. * libc/stdlib/wctomb_r.c: included string.h for "strlen" and "strcmp" prototypes. * libc/stdlib/remove.c: included reent.h for "_unlink_r" prototype. * libc/reent/execr.c: included sys/wait.h for "wait" prototype. * libc/reent/fstatr.c: included sys/stat.h for "fstat" prototype. * libc/reent/openr.c: included fcntl.h for "open" prototype. * libc/reent/signalr.c: included signal.h for "kill" prototype, unistd.h for "getpid" prototype. * libc/reent/statr.c: included sys/stat.h for "stat" prototype. * libc/reent/timer.c: included sys/time.h for "gettimeofday" prototype. * libc/unix/getut.c (utmpname): removed local, incorrect "strdup" prototype. Also included stdlib.h for "abort", string.h for "strdup" and "strncmp" prototypes. * libc/unix/getlogin.c: included string.h for "strncmp", "memset", and "strncpy", unistd.h for "read" and "close" prototypes. * libc/posix/execvp.c: included string.h for "strchr", "strlen", and "strcat" prototypes.
90 lines
1.8 KiB
C
90 lines
1.8 KiB
C
/* 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 <string.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 && buf[strlen(buf) - 1] != '/')
|
|
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;
|
|
}
|