Bug 17302 - FileStream/io-layer errors out when using file descriptor 0.
Summary: FileStream/io-layer errors out when using file descriptor 0.
Status: NEW
Alias: None
Product: Class Libraries
Classification: Mono
Component: mscorlib (show other bugs)
Version: master
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2014-01-17 17:12 UTC by Jonathan Pryor
Modified: 2014-01-17 17:13 UTC (History)
1 user (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments

Description Jonathan Pryor 2014-01-17 17:12:26 UTC
Mono's io-layer errors out if a program "just happens" to be dealing with file descriptor 0.

Consider the following (broken?) program:

  using System;
  using System.IO;
  using System.Runtime.InteropServices;

  class Test {
    [DllImport ("msvcrt.dll")]
    static extern int close (int fd);

    [DllImport ("msvcrt.dll")]
    static extern int open (string path, int flag, int mode);

    public static void  Main ()
    {
      Console.Error.WriteLine ("In.Handle={0}",
          ((FileStream) ((StreamReader) Console.In).BaseStream).Handle);
      Console.In.Close ();
      int r = close (0);
      Console.Error.WriteLine ("close(0)={0}", r);

      using (var f = File.OpenRead ("fd0.cs")) {
        if (f.Handle != IntPtr.Zero)
          Console.Error.WriteLine ("Invalid test; never mind!");
        Console.Error.WriteLine ("f.Handle={0}", f.Handle);
      }
    }
  }

The above program does two things of consequence:

1. Assuming that Console.In is file descriptor 0 (usually true for Unixy systems...), it _closes_ it. Twice. For good measure. This ensure that file descriptor 0 is closed.

2. It opens a new file.

Normal open(2) semantics are that it will use the lowest file descriptor value possible. Since we ensure that file descriptor 0 is closed, (2) (the `File.OpenRead()` statement) will use file descriptor 0.

Note: (2) requires that a file named "fd0.cs" be located in the same directory. Modify as appropriate.

We verify that FileStream.Handle is 0 on the created FileStream.

Given all the above, what's the problem? It crashes:

> In.Handle=0
> close(0)=0
> f.Handle=0
> 
> Unhandled Exception:
> System.IO.IOException: Invalid parameter
>   at System.IO.FileStream.Dispose (Boolean disposing) [0x000eb] in /private/tmp/source/bockbuild-xamarin/profiles/mono-mac-xamarin/build-root/mono-3.2.5/mcs/class/corlib/System.IO/FileStream.cs:934 
>   at System.IO.Stream.Close () [0x00000] in /private/tmp/source/bockbuild-xamarin/profiles/mono-mac-xamarin/build-root/mono-3.2.5/mcs/class/corlib/System.IO/Stream.cs:113 
>   at System.IO.Stream.Dispose () [0x00000] in /private/tmp/source/bockbuild-xamarin/profiles/mono-mac-xamarin/build-root/mono-3.2.5/mcs/class/corlib/System.IO/Stream.cs:100 
>   at Test.Main () [0x00000] in <filename unknown>:0 

Furthermore, where it crashes is in the FileStream.Dispose() call when closing "fd0.cs".

Expected behavior: no crash.

Note You need to log in before you can comment on or make changes to this bug.