www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 2429] New: std.stream.File incorrect flag parsing and sharing mode

reply d-bugmail puremagic.com writes:
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
      }
    }


-- 
Oct 24 2008
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2429






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:

C:\temp>copy /y con test.txt


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. 


-- 
Nov 27 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2429






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();
}
------------------------------------------


-- 
Nov 27 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2429


bugzilla digitalmars.com changed:

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





Fixed in DMD 1.037 and 2.021


-- 
Dec 07 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2429






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.


-- 
Jan 24 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2429


jason spashett.com changed:

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





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.


-- 
Jan 24 2009
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2429


Walter Bright <bugzilla digitalmars.com> changed:

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





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: -------
Jun 23 2009