Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent handling of symlinks created by Unix.symlink and Cygwin's "ln -s" #7517

Closed
vicuna opened this issue Apr 18, 2017 · 4 comments
Closed

Comments

@vicuna
Copy link

vicuna commented Apr 18, 2017

Original bug ID: 7517
Reporter: sawfish
Assigned to: @dra27
Status: resolved (set by @dra27 on 2017-04-19T09:20:18Z)
Resolution: won't fix
Priority: normal
Severity: feature
Platform: MinGW-w64
OS: Windows
OS Version: 7
Version: 4.04.0
Category: otherlibs
Related to: #7518

Bug description

Ocamlbuild does not handle symbolic links correctly on Cygwin (at least when built with the MinGW-w64 cross-compiler). And as far as I debugged it, the problems seem to be partly related to the Unix module.

The attached example creates a symlink, once using Unix.symlink and a second time using Cygwin's "ln -s" shell command.
In both cases, the link is examined afterwards using Unix.lstat and Unix.readlink. While these functions work mostly as expected on the symlink that is created using Unix.symlink, they fail on the symbolic link created by Cygwin's "ln -s" command.

As Ocamlbuild internally sometimes accesses symbolic links that it previously created by issuing shell commands like "ln -s", this inconsistency severly breaks OCamlbuild on a Cygwin/MinGW-w64 environment.

Another issue is the output of Unix.readlink which seems to contain some garbage prefix before the actual link destination.

Steps to reproduce

Compile the attached example in a Cygwin/MinGW64 environment and execute it in a Cygwin shell that has Administrator rights. The latter are needed to allow the process to create symbolic links.

Additional information

On my machine, the output of the test looks as follows:

$ ./symlink_test.native
Symbolic link atrocity on Cygwin and Win32...
Sys.os_type = Win32, Unix.has_symlink = true

Running test by creating symbolic links with Unix.symlink:
Creating symlink using Unix.symlink from D:\cygwin64\home\z002rwsm\ob_test\linktest --> D:\cygwin64\home\z002rwsm\ob_test\linktest.dst
Trying to read link information back...
Unix.lstat D:\cygwin64\home\z002rwsm\ob_test\linktest yields S_LNK
Unix.readlink D:\cygwin64\home\z002rwsm\ob_test\linktest yields ??\D:\cygwin64\home\z002rwsm\ob_test\linktest.dst
Removing symbolic link D:\cygwin64\home\z002rwsm\ob_test\linktest

Running test by creating symbolic links using Cygwin's ln shell command:
Creating symlink using cygwin's ln -s from D:\cygwin64\home\z002rwsm\ob_test\linktest --> D:\cygwin64\home\z002rwsm\ob_test\linktest.dst
Trying to read link information back...
Unix.lstat D:\cygwin64\home\z002rwsm\ob_test\linktest yields S_REG
Unix_error during Unix.readlink D:\cygwin64\home\z002rwsm\ob_test\linktest: Invalid argument
Removing symbolic link D:\cygwin64\home\z002rwsm\ob_test\linktest

File attachments

@vicuna
Copy link
Author

vicuna commented Apr 19, 2017

Comment author: @dra27

Unix.readlink should be stripping the NT Object Manager Dos Device prefix (the ??) and that is definitely a bug in the handling of absolute symbolic links.

Thank you for the detailed report and test, but the rest of this is expected behaviour, not a bug. Cygwin symlinks are nothing to do with Windows and consequently nothing to do with a native Windows port of OCaml. Fundamentally, mingw-compiled ocamlbuild should not be trying to use Cygwin commands with a mingw or msvc-based compiler, however you can mitigate the problem by running with CYGWIN=winsymlinks:native or CYGWIN=winsymlinks:nativestrict to cause ln -s to use native symlinks rather than its file-based shim.

The Windows ports will benefit from cross-compilation as and when it lands because we will then be able to build a true Cygwin/mingw ocaml cross-compiler - i.e. where ocamlopt (and ocamlbuild) are Cygwin applications outputting native Windows executables. However, I do not anticipate any point where the native Windows versions of the Unix library will be capable of reading Cygwin symbolic links.

@vicuna vicuna closed this as completed Apr 19, 2017
@vicuna
Copy link
Author

vicuna commented Apr 19, 2017

Comment author: @dra27

I've opened a separate issue reporting the unwanted prefix coming from Unix.readlink. I don't propose fixing that at this stage in the 4.05 dev cycle.

@vicuna
Copy link
Author

vicuna commented Apr 19, 2017

Comment author: @gasche

If I understand correctly, this means that we need an ocamlbuild-side solution to this issue, right? I guess that one solution would be to use OCaml code instead of shell calls to create those symlinks -- but it would only work on recent OCaml versions.

@vicuna
Copy link
Author

vicuna commented Apr 19, 2017

Comment author: @dra27

Prior to 4.03.0 this would have been completely broken/impossible, unless ocamlbuild was also doing readlink via a script.

Windows 10 now permits a configuration option where symlinks can be created without needing admin rights - it's becoming realistic just to require the winsymlinks:native option (incidentally, ocamlbuild could choose to set this specifically when it invokes ln -s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants