[Mono-bugs] [Bug 490002] New: IS_PORTABILITY_DRIVE && IS_PORTABILITY_CASE has unexpected effects
bugzilla_noreply at novell.com
bugzilla_noreply at novell.com
Sat Mar 28 03:04:04 EDT 2009
https://bugzilla.novell.com/show_bug.cgi?id=490002
Summary: IS_PORTABILITY_DRIVE && IS_PORTABILITY_CASE has
unexpected effects
Classification: Mono
Product: Mono: Runtime
Version: unspecified
Platform: Other
OS/Version: Other
Status: NEW
Severity: Normal
Priority: P5 - None
Component: io-layer
AssignedTo: lupus at novell.com
ReportedBy: matthew.flaschen at gatech.edu
QAContact: mono-bugs at lists.ximian.com
Found By: ---
Created an attachment (id=282680)
--> (https://bugzilla.novell.com/attachment.cgi?id=282680)
Tests opening an existing file called C:\foo
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.7)
Gecko/2009030422 Ubuntu/8.04 (hardy) Firefox/3.0.7
http://www.mono-project.com/IOMap says that MONO_IOMAP=drive strips drive name
from pathnames. I would have expected that to mean that accessing and/or
modifying C:\foo always results in an attempt to access and/or create /foo.
This would usually throw an error on GNU/Linux, but it makes conceptual sense
to me, as both are usually the root of the main drive.
However, it turns out (I originally discovered this issue in NUnit's runtime,
but a much simpler test is attached) it doesn't work quite like that. When
/accessing/ C:/ foo without O_CREAT (e.g. with FileMode.Open) MONO_IOMAP=drive
does what I expects. It fails with System.IO.FileNotFoundException when /foo
does not exist, and writes to the file when it exists and is writable. To
verify this works as expected run:
sudo rm -f /foo; sudo touch /foo; sudo chmod a+w /foo; MONO_IOMAP=drive
/root_file_oe.exe
However, MONO_IOMAP=drive alone does not rewrite attempts to create a file,
such as with FileMode.Create. That means you get a C:\foo in the current
directory. See mono_iomap_drive.txt which was created with:
rm -f ./C:\\foo; MONO_IOMAP=drive strace root_file.exe > mono_iomap_drive.txt
2>&1
Also note ./C:\\foo is created
The strangest part, though is that MONO_IOMAP=all does rewrite such attempts.
So the same program run with MONO_IOMAP=all does attempt to create /foo,
typically resulting in a System.UnauthorizedAccessException (unless of course /
is writable). See mono_iomap_all.txt which was created with:
sudo rm /foo; MONO_IOMAP=all strace root_file.exe > mono_iomap_all.txt 2>&1
The reason can be seen in the source
(http://anonsvn.mono-project.com/viewvc/trunk/mono/mono/utils/mono-io-portability.c?view=log&pathrev=130455)
though it definitely wasn't obvious. last_exists is false when _wapi_open
(http://anonsvn.mono-project.com/viewvc/trunk/mono/mono/io-layer/io-portability.c?revision=122961&view=markup&pathrev=130455)
calls mono_portability_find_file, because O_CREAT was sent (meaning the OS is
allowed to create the file). The first two places where
mono_portability_find_file returns a non-null pathname both require last_exist
to be true (corresponding with O_CREAT not being set). After those two
returns, it returns NULL if !(IS_PORTABILITY_CASE). Otherwise, if case
refactoring /is/ allowed, it goes into an entirely new set of case-insensitive
logic which eventually results in it creating /foo because /foo=/foo
(case-insensitive path comparison)
Of course, if only IS_PORTABILITY_CASE is set, then it won't drop the drive
letter, so it still creates ./C:/foo
So the only way to get it to create files in the root is to use MONO_IOMAP=all.
I don't know what The Right Thing To Do is. It seems sort of reasonable to
only fallback to /foo when creation is not allowed. But if so, it should
/still/ not create /foo when IS_PORTABILITY_CASE is set. It would be simpler
and probably more in line with the docs to always create /foo if
MONO_IOMAP=drive is set
I created two short test programs (referred to above), root_file.cs and
root_file_oe.cs. root_file.cs attempts to create a file, while root_file_oe
attempts to open an existing file.
I hope this is report is helpful. Let me know if you need any additional info.
Reproducible: Always
Steps to Reproduce:
1.
2.
3.
--
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
More information about the mono-bugs
mailing list