This is the mail archive of the cygwin mailing list for the Cygwin project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Directory existence prevents .exe execution

Igor Peshansky wrote:
On Wed, 16 Apr 2008, Luke Kendall wrote:

We have the Ici scripting language installed on Windows.  Ici expects a
directory called "ici" to exist alongside, where various libraries are
installedd to provide extra functionality.

Unfortunately, under Cygwin, if w try to run the command "ici" we get
the error "ici: command not found", because Cygwin chooses to try to
execute the directory instead of the .exe:

This behavior (preferring the unadorned file name to the .exe) has been in existence for a while (at least a year).
Interesting. Do you mean that exec() prefers the unadorned file name to the .exe? Or do you mean bash or something else changed to prefer the unadorned name? From what you say below, I think you mean bash changed.

  We relied on the old behavior by
having a script and a .exe with the same name (and expecting the .exe to
be invoked on Windows/Cygwin).  I remember we've had to work around this
issue when the change happened, by prepending the following to our script:

[ -x "$0.exe" ] && exec "$0.exe" "$@"

Our olden approach, maybe 5-10 years ago, we wrote a script that examined the 1st line of some target script to generate a C program (that was compiled to a .exe of the same name) that invoked the named interpreter on the target script. This was needed for U/Win. Then we changed over to Cygwin and discovered we didn't need to do this: Cygwin supported #! magic. But some time ago it stopped working in this corner case and I finally got around to asking about it.

To follow the approach you took for your case, we could convert all our ici scripts to shell scripts and um, what, set ICI to either /opt/bin/ici or /opt/bin/ici.exe depending on whether we detect the script is on Windows and then:

exec $ICI -f - "$@" <<'some-eof-mark'

But that wouldn't work, would it, since we'd still have to backslash escape any backtic character in the script? Shudder.
$ /opt/bin/ici /cygdrive/x/bin/script/cfnhdr
bash: /opt/bin/ici: is a directory
$ ls -ld /opt/bin/ici
drwxr-xr-x 1 luke Domain Users 0 Oct 17  2005 /opt/bin/ici
$ ls -ld /opt/bin/ici.*
-rwxr-xr-x 1 luke Domain Users 233503 Apr 18  2000 /opt/bin/ici.dll
-rwxr-xr-x 1 luke Domain Users  24576 Jan 29  2003 /opt/bin/ici.exe

I tried naming the ici directory Ici but it made no difference.

Try also CYGWIN="$CYGWIN check_case:strict" (while the code is still in the DLL) or managed mounts... The latter won't work unless ici.exe is a Cygwin program.

Thanks for the suggestion, but it didn't help:

$ echo $CYGWIN
$ CYGWIN="$CYGWIN check_case:strict"
$ ici -help
bash: ici: command not found
$ /opt/bin/ici -help
bash: /opt/bin/ici: is a directory
$ whiches ici
$ type ici
bash: type: ici: not found
$ which ici
ici: Command not found.
$ CYGWIN=nobinmode
$ ici -help
bash: ici: command not found
$ /opt/bin/ici -help
bash: /opt/bin/ici: is a directory

The directory /opt/bin is mounted like so:
$ mount
\\samba\syncopt\\bin on /opt/bin type system (textmode,exec)

Using binmode doesn't help. Is this a bug, that bash tries to execute a
directory even when there's an executable (with an implicit .exe suffix,
naturally) of the same name in existence ?

No, this is expected behavior (if you search through bash release
announcements, you should be able to see the exact point at which the
change happened).
I had a look, but couldn't find the release notes. Do you mean, the release notes for each of the bash updates announced on the mailing list? Or do you mean the full release notes - if so, any idea where I'd find them?

I looked at the release notes for all the mailing list announcements for bash over the last few years, and searched for "unadorned" and "exec". Sorry for asking.
If not, can anyone suggest a workaround?

Other than renaming the directory or using a wrapper script, no.

I can't just append a .exe to the #!/opt/bin/ici shell wrapper since
then the scripts wouldn't run from Unix.

How do these scripts *ever* run from Unix? Unix would definitely not be aware of the .exe suffix, and would always attempt to execute /opt/bin/ici, which, as you say, is a directory. Do you have a /opt/bin/ici script as well?

No, ici on Unix looks elsewhere for its libraries, since it can't use such a simple system as having the directory alongside the .exe with the same name but the suffix stripped, for obvious reasons.
In any case, whatever solution you use to make it work from Unix should
work on Cygwin as well.

True. We can modify the ici source to also have a directory search path for the libraries, and move the ici directory somewhere else that's off the PATH search path, and that will solve this problem.

I guess that's what we'll do.

But we'll then have the problem that Windows native compiled ici won't be able to open any named scripts that aren't given with Windows pathnames, not Cygwin ones. Fair enough, it's just like any other native Windows application in that respect.

And we could compile up a version under Cygwin for use in Cygwin.
Is there a bash option that controls this, maybe (I couldn't see one)?

There is no bash option to control this, AFAIK.
Okay, thanks Igor.


Unsubscribe info:
Problem reports:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]