Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Date: 01 Apr 2003 18:15:20 -0500 Message-Id: From: Daniel Villeneuve To: cygwin AT cygwin DOT com Subject: 1.3.22-1: execvp in libc.a seems different from newlib/libc/posix Reply-to: danielv AT ad-opt DOT com X-OriginalArrivalTime: 01 Apr 2003 23:15:21.0477 (UTC) FILETIME=[913C5350:01C2F8A4] Hi, I'm still working on the problem related to using execvp to call a program through a relative symbolic link. I have installed the latest release of cygwin (1.3.22-1) available today. I use the following test environment: - create a directory d2 on a network share, containing two programs; - create a sibling directory d1, containing a relative symbolic link to one of the two previous programs in d2; - call execvp (using a C program or with Perl) with PATH=d1:d2:$PATH. With that setup, I am faced with the odd fact that the symbolic link in d1 is not seen/used by execvp. I have downloaded the cygwin source distribution, found the execvp.c file in newlib/libc/posix, and compiled a version of this file in my test environment, which I have put in a library called -ldv. Surprise: when linking with my version of execvp, everything works fine. If I interpose -lc (or -lcygwin) before my library, the program no longer works. Could it be that the objects in libc.a or libcygwin.a are not in sync with the source, or something like that? My environment test is provided in post-scriptum. -- Daniel # Edit this path to point to a non-existent directory on a # network share. network_dir=/home/danielv/tmp [ -d $network_dir ] || mkdir $network_dir cd $network_dir rm -rf callfoo* lib* d1 d2 # create an object containing the definition of execvp, # taken from src/newlib/libc/posix/execvp.c cat >myexecvp.c <<'EOF' #include <_ansi.h> #include #include #include #include #include #include #define PATH_DELIM ':' /* * Copy string, until c or 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, '/') ) return execv (file, argv); 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; } EOF gcc -o myexecvp.o -c myexecvp.c ar cr libdv.a myexecvp.o rm myexecvp.o cat >callfoo.c <<'EOF' #include #include int main(void) { char *argv[] = { "foo", NULL }; execvp("foo", argv); perror("callfoo"); exit(EXIT_FAILURE); } EOF gcc -o callfoo1 callfoo.c gcc -o callfoo2 callfoo.c -L$network_dir -ldv gcc -o callfoo3 callfoo.c -L$network_dir -lc -ldv # create two subdirectories that will be prepended to the PATH mkdir d1 d2 # create two programs that echo a string cat >d2/print.c <<'EOF' #include int main(int argc, char **argv) { printf("%s\n", NAME); return 0; } EOF gcc -DNAME='"foo"' -o d2/foo d2/print.c gcc -DNAME='"bar"' -o d2/bar d2/print.c # create a relative symlink from d1/foo to d2/bar, sooner in the path ln -s ../d2/bar d1/foo # ln -s $network_dir/d2/bar.sh d1/foo.sh # call foo through execvp, with the symlink sooner in the PATH echo 'next lines should all be "bar"' PATH=d1:d2:$PATH ./callfoo1 PATH=d1:d2:$PATH ./callfoo2 PATH=d1:d2:$PATH ./callfoo3 # first one calls execvp PATH=d1:d2:$PATH perl -e 'exec "foo"' # second one calls the shell because of $ PATH=d1:d2:$PATH perl -e 'exec "foo \$EMPTY"' -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/