git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Eric Blake <ebb9@byu.net>
To: Alex Riesen <raa.lkml@gmail.com>
Cc: Liu Yubao <yubao.liu@gmail.com>, git@vger.kernel.org
Subject: Re: [PATCH] remove unnecessary loop
Date: Tue, 08 May 2007 06:17:11 -0600	[thread overview]
Message-ID: <46406A47.7050400@byu.net> (raw)
In-Reply-To: <81b0412b0705080208x3713cbc1y3c870383b586c877@mail.gmail.com>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Alex Riesen on 5/8/2007 3:08 AM:
> This does not "test again" if lstat returns 0. If lstat returns 0
> (file stat info
> obtained) the open is not even called. Besides, cygwin lies not only about
> .exe but also about .lnk files.
> 
> P.S. Somehow I have the feeling that even if it is a stupidity in cygwin
> they will not fix it (nor will they admit it is a bug).

It is a limitation of cygwin, and the cygwin developers will admit it; but
they will also stand behind calling it a feature rather than a bug due to
the attempts to make cygwin behave more like Linux in spite of Window's
insistence on file suffixes.  The cygwin port of coreutils has to do
similar stat() tricks to reverse engineer some of the .exe magic present
in cygwin.  However, it is possible to override the magic without
resorting to a full-blown open(), via careful use of additional stat()s or
readlink()s (trailing . is not legal in Windows, and on cygwin is only
legal on managed mounts, so stat("foo.") will fail when stat("foo")
succeeds if the reason stat("foo") succeeded was due only to the existence
of foo.exe):

/* Return -1 if PATH not found, 0 if PATH spelled correctly, and 1 if PATH
   had ".exe" automatically appended by cygwin.  Don't change errno.  */
int
cygwin_spelling (char const *path)
{
  char path_exact[PATH_MAX + 9];
  int saved_errno = errno;
  int result = 0; /* Start with assumption that PATH is okay.  */
  int len = strlen (path);

  if (! path || ! *path || len > PATH_MAX)
    /* PATH will cause EINVAL or ENAMETOOLONG, treat it as non-existing.  */
    return -1;
  if (path[len - 1] == '.' || path[len-1] == '/')
    /* Don't change spelling if there is a trailing `.' or `/'.  */
    return 0;
  if (readlink (path, NULL, 0) < 0)
    { /* PATH is not a symlink.  */
      if (errno == EINVAL)
	{ /* PATH exists.  Appending trailing `.' exposes whether it is
	     PATH or PATH.exe for normal disk files, but also check appending
	     trailing `.exe' to be sure on virtual/managed directories.  */
	  strcat (strcpy (path_exact, path), ".");
	  if (access (path_exact, F_OK) < 0)
	    { /* PATH. does not exist.  */
	      strcat (path_exact, "exe");
	      if (access (path_exact, F_OK) == 0)
		/* But PATH.exe does, so append .exe.  */
		result = 1;
	    }
	}
      else
	/* PATH does not exist.  */
	result = -1;
    }
  else
    { /* PATH is a symlink.  Appending trailing `.lnk' exposes whether
	 it is PATH.lnk or PATH.exe.lnk; but does not help with
	 old-style symlinks where it was just PATH and the system
	 attribute set.  */
      strcat (strcpy (path_exact, path), ".lnk");
      if (readlink (path_exact, NULL, 0) < 0)
	{
	  strcat (strcpy (path_exact, path), ".exe.lnk");
	  if (readlink (path_exact, NULL, 0) == 0)
	    result = 1;
	}
    }

  errno = saved_errno;
  return result;
}


In the upcoming cygwin 1.7.0, you can set CYGWIN=transparent_exe which
will cause ENOENT when dealing with any explicit .exe.  When enabled, that
will make it impossible to have both foo and foo.exe in the current
directory, and make it so that stat can never lie - stat("foo.exe") will
fail, and if stat("foo") succeeds, you no longer care if it succeeded
because of the Windows file foo or because of foo.exe, because the .exe is
transparent to cygwin.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGQGpH84KuGfSFAYARAsCdAKCmqdgsppPY0MhxDWZ6QQxXExn2gwCeLN39
Zl3sRk/0IkkHkIyjf4RpAAA=
=rQrT
-----END PGP SIGNATURE-----

  parent reply	other threads:[~2007-05-08 12:15 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-08  3:18 [PATCH] remove unnecessary loop Liu Yubao
2007-05-08  4:49 ` Liu Yubao
2007-05-08  5:05   ` Junio C Hamano
2007-05-08  9:08   ` Alex Riesen
2007-05-08 10:13     ` Jan Hudec
2007-05-08 12:38       ` Alex Riesen
2007-05-08 12:17     ` Eric Blake [this message]
2007-05-08  9:39   ` Jan Hudec
2007-05-09  1:03     ` Liu Yubao

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=46406A47.7050400@byu.net \
    --to=ebb9@byu.net \
    --cc=git@vger.kernel.org \
    --cc=raa.lkml@gmail.com \
    --cc=yubao.liu@gmail.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 NNTP newsgroup(s).