From: Takashi Yano <takashi.yano@nifty.ne.jp>
To: cygwin@cygwin.com
Subject: Re: Cygwin's execlp() does not work with an empty $PATH element
Date: Mon, 27 Jun 2022 20:16:36 +0900 [thread overview]
Message-ID: <20220627201636.46f55975dc6485a7d3f5ee27@nifty.ne.jp> (raw)
In-Reply-To: <DM8PR09MB7095965E449CC03DEE772338A5B69@DM8PR09MB7095.namprd09.prod.outlook.com>
On Sun, 26 Jun 2022 15:09:34 +0000
"Lavrentiev, Anton \(NIH/NLM/NCBI\) \[C\] wrote:
> An empty PATH element (":xxx" or "xxx::xxx" or "xxx:") is to be considered as the current directory (from the very first days of Unix).
>
> However, Cygwin does not seem to obey the rule.
>
> Consider the following simple C program:
>
> $ cat hello.c
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
>
> int main(int argc, const char* argv[])
> {
> if (argc < 2) {
> const char* prog = strrchr(argv[0], '/');
> if (!prog++)
> prog = argv[0];
> execlp(prog, prog, "Hello", NULL); // execute just by the program name
> perror("exec");
> return 1;
> }
> printf("%s\n", argv[1]);
> return 0;
> }
>
> Now compare the execution on Linux and Cygwin:
>
> Linux:
>
> $ gcc -Wall -o hello hello.c
> $ hello
> bash: hello: command not found
> $ ./hello
> exec: No such file or directory
> $ PATH=".:$PATH" ./hello
> Hello
> $ PATH=":$PATH" ./hello
> Hello
> $ PATH="${PATH}:" ./hello
> Hello
>
> Cygwin:
>
> $ gcc -Wall -o hello hello.c
> $ hello
> -bash: hello: command not found
> $ ./hello
> exec: No such file or directory
> $ PATH=".:$PATH" ./hello
> Hello
> $ PATH=":$PATH" ./hello
> exec: No such file or directory
> $ PATH="${PATH}:" ./hello
> exec: No such file or directory
>
> As you can see, the execution failed when an empty PATH element was added on Cygwin
> (yet it was perfectly fine on Linux).
How about the following patch?
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index e0f1247e1..8fe9d089f 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -118,8 +118,10 @@ find_exec (const char *name, path_conv& buf, const char *search,
the name of an environment variable. */
if (strchr (search, '/'))
*stpncpy (tmp, search, NT_MAX_PATH - 1) = '\0';
- else if (has_slash || isdrive (name) || !(path = getenv (search)) || !*path)
+ else if (has_slash || isdrive (name))
goto errout;
+ else if (!(path = getenv (search)) || !*path)
+ strcpy (tmp, "."); /* Search the current directory when PATH is absent */
else
*stpncpy (tmp, path, NT_MAX_PATH - 1) = '\0';
@@ -134,7 +136,9 @@ find_exec (const char *name, path_conv& buf, const char *search,
already tried that. */
if ((opt & FE_CWD) && (tmp_path[0] == '\0'
|| (tmp_path[0] == '.' && tmp_path[1] == '\0')))
- continue;
+ goto next;
+ else if (tmp_path[0] == '\0') /* An empty path means the current dir. */
+ eotmp = stpcpy (tmp_path, ".");
*eotmp++ = '/';
stpcpy (eotmp, name);
@@ -146,7 +150,7 @@ find_exec (const char *name, path_conv& buf, const char *search,
if ((suffix = perhaps_suffix (tmp_path, buf, err1, opt)) != NULL)
{
if (buf.has_acls () && check_file_access (buf, X_OK, true))
- continue;
+ goto next;
/* Overwrite potential symlink target with original path.
See comment preceeding this method. */
buf.set_posix (tmp_path);
@@ -154,8 +158,13 @@ find_exec (const char *name, path_conv& buf, const char *search,
goto out;
}
+next:
+ if (*path == '\0')
+ break;
+ if (*path == ':')
+ path++;
}
- while (*path && *++path);
+ while (true);
errout:
/* Couldn't find anything in the given path.
--
Takashi Yano <takashi.yano@nifty.ne.jp>
next prev parent reply other threads:[~2022-06-27 11:17 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-26 15:09 Lavrentiev, Anton (NIH/NLM/NCBI) [C]
2022-06-26 16:26 ` Lavrentiev, Anton (NIH/NLM/NCBI) [C]
2022-06-27 11:16 ` Takashi Yano [this message]
2022-06-27 12:15 ` Takashi Yano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220627201636.46f55975dc6485a7d3f5ee27@nifty.ne.jp \
--to=takashi.yano@nifty.ne.jp \
--cc=cygwin@cygwin.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).