Thread overview
[Issue 2429] New: std.stream.File incorrect flag parsing and sharing mode
Oct 24, 2008
d-bugmail
Nov 27, 2008
d-bugmail
Nov 27, 2008
d-bugmail
Dec 08, 2008
d-bugmail
Jan 24, 2009
d-bugmail
Jan 24, 2009
d-bugmail
Jun 23, 2009
Walter Bright
October 24, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2429

           Summary: std.stream.File incorrect flag parsing and sharing mode
           Product: D
           Version: 1.037
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: jason@spashett.com


In stream.d parseMode is incorrect/inconsistent for windows platforms.

Firstly the share mode is not set to FILE_SHARE_READ in the case when the file is opened for writing. This make it impossible to view log files while they are written to.

Second it is possible to specify combinations of FileMode options which will override each others behaviour and create a mixture.

Hence it's possible to 'fix' the sharing option but opening a file with: FileMode.OutNew |  FileMode.In to enable sharing even though the file will never be read from.

I can't see any indication that this things are by design, and perhaps the windows sharing mode should always include READ and WRITE sharing to be more portable. Either that or allow sharing flags in the file mode.



private void parseMode(int mode,
                         out int access,
                         out int share,
                         out int createMode) {
    version (Win32) {
      if (mode & FileMode.In) {
        access |= GENERIC_READ;
        share |= FILE_SHARE_READ;
        createMode = OPEN_EXISTING;
      }
      if (mode & FileMode.Out) {
        access |= GENERIC_WRITE;
        createMode = OPEN_ALWAYS; // will create if not present
      }
      if ((mode & FileMode.OutNew) == FileMode.OutNew) {
        createMode = CREATE_ALWAYS; // resets file
      }
    }


-- 

November 27, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2429





------- Comment #1 from jason@spashett.com  2008-11-27 17:15 -------
I have tested, and reviwed the new parseMode function.

It is now possible to open for read (e.g. tail -f) a file that is being written to by a d program using FileMode.Out

Unfortunatly it's still not possible to open a file for read, that is being written to by another process.

for example:
In dos window #1:
C:\temp>copy /y con test.txt

In dos window #2:
C:\temp>test.exe
Error: Cannot open or create file 'test.txt'

test.d
---------------------
import std.stream;
import std.stdio;
void main()
{
        auto f = new File("test.txt", FileMode.In);
        char[] s;
        s = readln();
}
---------------------


Again, changing the first line in main to:
auto f = new File("test.txt", FileMode.In | FileMode.Out);

is a workaround, but I feel isn't correct as I am not opening it for write access. The workaround causes the sharing mode to be FILE_SHARE_READ | FILE_SHARE_WRITE

I belive, reasonably, that the share mode should always have these two flags set no matter what the FileMode is, read or write, so that there are no sharing confilicts on windows.

It is sometimes useful to write to a file with one process, while reading from it with another process. Read/write races or conflicts may occur, but that is up to the user to deal with.


-- 

November 27, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2429





------- Comment #2 from jason@spashett.com  2008-11-27 17:51 -------
NOTES -

C:\temp>copy /y con test.txt
text <- text must be typed first for the file to be opened.


FileMode.OutNew has the same problem. No sharing mode at all is set in this mode.

Linux/posix systems:

I am fairly sure that the unix code should also have a "share" (really permission bits) mode of 666 (and not 660), read and write for all occasions. The processes current umask is then automatically applied to restrict the actual permission bits. [ the "share" mode, or in actually the mode bits passed to std.c.linux.linux.open only apply when creating files ]

Linux example:
$umask
0022 (on my system - typical) allows permissions of 655 (rwxr-xr-x) or "less"
normal file creation asks for 666 (everything except execute bit & other
special permissions) yeilding:
$echo test > test.txt
$ls -l test.txt
-rw-r--r-- 1 user user 5 2008-11-27 23:39 test.txt

which is correct.


With D (Incorrect):
$rm test.txt
./test
ls -l test.txt
-rw-r----- 1 user user 5 2008-11-27 23:39 test.txt

read is missing from "others" permission, and so would write be if the umask was 0020 or similar.

test.d
------------------------------------------
import std.stream;
import std.stdio;

void main()
{
        auto f = new File("test.txt", FileMode.OutNew);
        char[] s;
        s = readln();
}
------------------------------------------


-- 

December 08, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2429


bugzilla@digitalmars.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED




------- Comment #3 from bugzilla@digitalmars.com  2008-12-08 00:54 -------
Fixed in DMD 1.037 and 2.021


-- 

January 24, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2429





------- Comment #4 from jason@spashett.com  2009-01-24 06:33 -------
Created an attachment (id=287)
 --> (http://d.puremagic.com/issues/attachment.cgi?id=287&action=view)
Patch to fix 2429, created against  v1.039

Windows:
Patch to always set windows share mode to read / write. This allows two
programs to read and or write the same file.
Linux:
Patch for Linux to always set permission bits to 666 as it traditional. IO mode
should have no bearing whatsoever on permissions.


-- 

January 24, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2429


jason@spashett.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|FIXED                       |




------- Comment #5 from jason@spashett.com  2009-01-24 06:39 -------
Please see my patch above.

For Windows:

The share mode should always be READ and WRITE, otherwise it's impossible to open the same file for read and write in two (dmd compiled) processes. Examples where this is desirable is databases/bloom filters other shared data. Behavior to conform as other compilers/std libraries on this platform.

For Linux:

The permissions, or (share) variable should alwyas be set to 666. File mode (i.e. read or write) should have no bearing whatsoever on file permissions. unix umask should be used instead to change these properties. Behavior to conform as other compilers/libries on this platform.


-- 

June 23, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2429


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|                            |FIXED




--- Comment #6 from Walter Bright <bugzilla@digitalmars.com>  2009-06-23 01:06:05 PDT ---
Fixed in DMD 1.046 and 2.031

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------