Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0005429OCamlotherlibspublic2011-12-15 11:112017-03-15 11:20
Assigned To 
StatusresolvedResolutionwon't fix 
PlatformPCOSWindowsOS VersionXP SP3 32 bits
Product Version3.12.1 
Target VersionundecidedFixed in Version 
Summary0005429: Unix.stat behaves differently on win32 and linux
DescriptionThe following snippet will fail with ENOENT on win32/msvc but succeed on linux.

  let () =
    Unix.mkdir "somedir" 0o755;
    ignore (Unix.stat "somedir");

    (* Will fail on win32/msvc *)
    ignore (Unix.stat "somedir/");
    Unix.rmdir "somedir";

TagsNo tags attached.
Attached Files? file icon [^] (1,411 bytes) 2011-12-21 16:04 [Show Content]

- Relationships
related to 0004549closed Filename.dirname is not handling multiple / on Unix 
has duplicate 0004159resolvedshinwell MinGW: Unix.stat works on "directory" but not on "directory/", works on Linux 

-  Notes
gasche (administrator)
2011-12-15 11:15

I'm not sure I understand why this is a bug. "somedir/" is a legal path on Unix (which is generally lenient regarding trailing directory separators), while it does not on Windows.

I don't see what other behavior you could hope with this. If you want your code to be robust, you must not use hardcoded separators but Filename.concat or Filename.dir_sep: [^]

Could you be more explicit in what behavior you expect?
ripoche (reporter)
2011-12-15 11:41

I think it depends of the intended goal of the Unix library.

If it is to stay as close to unix semantics as possible, then it should be fixed.
If it is to provide the thinnest layer possible, then maybe it should not.

In the light of all the work done to correctly handle file, pipes and sockets on Windows, it seems to me that unix semantics is the goal, hence this bug.

As a side note, ruby 1.8.2 handles this case gracefully.
ripoche (reporter)
2011-12-15 11:45

Also, I stumbled upon this while porting some OCaml software on win32/msvc. Had it been in my code, I would have worked around it.
ripoche (reporter)
2011-12-15 11:53

Python 2.7.2 also handles this case gracefully.
protz (manager)
2011-12-21 11:29

It's the usual discussion: as you start implementing workarounds like this, you become part of the problem, and not part of the solution. Encouraging people to write unix paths with the expectation that it will work out-of-the-box on Win32 is, imho, not a good thing.

What kind of solution do you suggest? Parsing a path as a unix-one under windows just to remove the trailing slash sounds like quite the hack...
ripoche (reporter)
2011-12-21 15:52
edited on: 2011-12-21 16:07

Regarding portability between win32 and posix, I'm sure most would agree that python, and to a lesser extent ruby, do a decent job.

They do work around the issue, simply because in their eyes it makes sense as "systems programming languages" (whatever that means). If they didn't then they would have the same issues we face now.

I glanced at their sources and here is how they do it:

* python doesn't use the C runtime and goes straight to the win32 api (CreateFile + GetFileInformationByHandle) which also allows them to follow ntfs links when appropriate (stat vs lstat).

* ruby doesn't use the C runtime either: it duplicates the path, replaces all slashes with backslashes and isolates 3 cases: UNC paths (\\\myshare\mysubdir), drive roots (c:\) and neither. Depending on the case, it may append a '.' to the path, remove a trailing '\' or leave it as is before calling FindFirstFile (with GetFileAttributes as a fallback).

ripoche (reporter)
2011-12-21 16:04

It certainly is more complicated than I originally thought...
doligez (administrator)
2017-03-15 11:20

I find @protz's argument convincing, and I don't think we want to reimplement the C runtime (or standard library) like python and ruby do.

- Issue History
Date Modified Username Field Change
2011-12-15 11:11 ripoche New Issue
2011-12-15 11:15 gasche Note Added: 0006308
2011-12-15 11:15 gasche Assigned To => gasche
2011-12-15 11:15 gasche Status new => feedback
2011-12-15 11:41 ripoche Note Added: 0006311
2011-12-15 11:41 ripoche Status feedback => assigned
2011-12-15 11:45 ripoche Note Added: 0006312
2011-12-15 11:52 gasche Assigned To gasche =>
2011-12-15 11:52 gasche Status assigned => acknowledged
2011-12-15 11:53 ripoche Note Added: 0006313
2011-12-15 11:55 gasche Relationship added related to 0004549
2011-12-21 11:29 protz Note Added: 0006431
2011-12-21 15:52 ripoche Note Added: 0006462
2011-12-21 16:04 ripoche File Added:
2011-12-21 16:04 ripoche Note Added: 0006463
2011-12-21 16:06 ripoche Note Edited: 0006462 View Revisions
2011-12-21 16:07 ripoche Note Edited: 0006462 View Revisions
2012-07-10 11:50 doligez Target Version => 4.01.0+dev
2012-07-11 16:16 doligez Relationship added has duplicate 0004159
2012-07-31 13:36 doligez Target Version 4.01.0+dev => 4.00.1+dev
2012-09-14 23:46 doligez Target Version 4.00.1+dev => 4.01.0+dev
2013-07-29 14:33 doligez Target Version 4.01.0+dev => 4.01.1+dev
2014-05-25 20:20 doligez Target Version 4.01.1+dev => 4.02.0+dev
2014-07-30 23:08 doligez Target Version 4.02.0+dev => 4.02.1+dev
2014-09-04 00:25 doligez Target Version 4.02.1+dev => undecided
2014-09-24 20:04 doligez Target Version undecided => 4.03.0+dev / +beta1
2016-03-24 12:01 doligez Target Version 4.03.0+dev / +beta1 => 4.03.1+dev
2016-12-07 16:49 shinwell Category OCaml general => OCaml otherlibs
2017-02-16 14:00 doligez Target Version 4.03.1+dev => undecided
2017-02-23 16:42 doligez Category OCaml otherlibs => otherlibs
2017-03-15 11:20 doligez Note Added: 0017670
2017-03-15 11:20 doligez Status acknowledged => resolved
2017-03-15 11:20 doligez Resolution open => won't fix

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker