2007-12-13 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / Mono.Posix / Mono.Unix / UnixStream.cs
index 5e6316757bd9869415a92bd90a4558d677365a59..d5d16676b8deb45fae11a1b79b8cbd899c91e446 100644 (file)
@@ -4,7 +4,9 @@
 // Authors:
 //   Jonathan Pryor (jonpryor@vt.edu)
 //
-// (C) 2004-2005 Jonathan Pryor
+// (C) 2004-2006 Jonathan Pryor
+// (C) 2007 Novell, Inc.
+//
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -52,13 +54,13 @@ namespace Mono.Unix {
                        this.fileDescriptor = fileDescriptor;
                        this.owner = ownsHandle;
                        
-                       long offset = Syscall.lseek (fileDescriptor, 0, SeekFlags.SEEK_CUR);
+                       long offset = Native.Syscall.lseek (fileDescriptor, 0, Native.SeekFlags.SEEK_CUR);
                        if (offset != -1)
                                canSeek = true;
-                       long read = Syscall.read (fileDescriptor, IntPtr.Zero, 0);
+                       long read = Native.Syscall.read (fileDescriptor, IntPtr.Zero, 0);
                        if (read != -1)
                                canRead = true;
-                       long write = Syscall.write (fileDescriptor, IntPtr.Zero, 0);
+                       long write = Native.Syscall.write (fileDescriptor, IntPtr.Zero, 0);
                        if (write != -1)
                                canWrite = true;  
                }
@@ -100,7 +102,7 @@ namespace Mono.Unix {
                                AssertNotDisposed ();
                                if (!CanSeek)
                                        throw new NotSupportedException ("The stream does not support seeking");
-                               long pos = Syscall.lseek (fileDescriptor, 0, SeekFlags.SEEK_CUR);
+                               long pos = Native.Syscall.lseek (fileDescriptor, 0, Native.SeekFlags.SEEK_CUR);
                                if (pos == -1)
                                        UnixMarshal.ThrowExceptionForLastError ();
                                return (long) pos;
@@ -110,19 +112,6 @@ namespace Mono.Unix {
                        }
                }
 
-               [CLSCompliant (false)]
-               [Obsolete ("Use Protection")]
-               public FilePermissions Permissions {
-                       get {
-                               RefreshStat ();
-                               return (FilePermissions) stat.st_mode;
-                       }
-                       set {
-                               int r = Syscall.fchmod (fileDescriptor, value);
-                               UnixMarshal.ThrowExceptionForLastErrorIf (r);
-                       }
-               }
-
                [CLSCompliant (false)]
                public Native.FilePermissions Protection {
                        get {
@@ -140,7 +129,7 @@ namespace Mono.Unix {
                public FileTypes FileType {
                        get {
                                int type = (int) Protection;
-                               return (FileTypes) (type & (int) FileTypes.AllTypes);
+                               return (FileTypes) (type & (int) UnixFileSystemInfo.AllFileTypes);
                        }
                        // no set as fchmod(2) won't accept changing the file type.
                }
@@ -161,11 +150,11 @@ namespace Mono.Unix {
                public FileSpecialAttributes FileSpecialAttributes {
                        get {
                                int attrs = (int) Protection;
-                               return (FileSpecialAttributes) (attrs & (int) FileSpecialAttributes.AllAttributes);
+                               return (FileSpecialAttributes) (attrs & (int) UnixFileSystemInfo.AllSpecialAttributes);
                        }
                        set {
                                int perms = (int) Protection;
-                               perms &= (int) ~FileSpecialAttributes.AllAttributes;
+                               perms &= (int) ~UnixFileSystemInfo.AllSpecialAttributes;
                                perms |= (int) value;
                                Protection = (Native.FilePermissions) perms;
                        }
@@ -189,6 +178,7 @@ namespace Mono.Unix {
 
                private void RefreshStat ()
                {
+                       AssertNotDisposed ();
                        int r = Native.Syscall.fstat (fileDescriptor, out stat);
                        UnixMarshal.ThrowExceptionForLastErrorIf (r);
                }
@@ -203,98 +193,8 @@ namespace Mono.Unix {
                        AdviseFileAccessPattern (pattern, 0, 0);
                }
 
-               [Obsolete ("Use AdviseFileAccessPattern (FileAccessPattern.Normal, offset, len)")]
-               public void AdviseNormalAccess (long offset, long len)
-               {
-                       UnixFile.AdviseNormalAccess (fileDescriptor, offset, len);
-               }
-
-               [Obsolete ("Use AdviseFileAccessPattern (FileAccessPattern.Normal)")]
-               public void AdviseNormalAccess ()
-               {
-                       UnixFile.AdviseNormalAccess (fileDescriptor);
-               }
-
-               [Obsolete ("Use AdviseFileAccessPattern (FileAccessPattern.Sequential, offset, len)")]
-               public void AdviseSequentialAccess (long offset, long len)
-               {
-                       UnixFile.AdviseSequentialAccess (fileDescriptor, offset, len);
-               }
-
-               [Obsolete ("Use AdviseFileAccessPattern (FileAccessPattern.Sequential)")]
-               public void AdviseSequentialAccess ()
-               {
-                       UnixFile.AdviseSequentialAccess (fileDescriptor);
-               }
-
-               [Obsolete ("Use AdviseFileAccessPattern (FileAccessPattern.Random, offset, len)")]
-               public void AdviseRandomAccess (long offset, long len)
-               {
-                       UnixFile.AdviseRandomAccess (fileDescriptor, offset, len);
-               }
-
-               [Obsolete ("Use AdviseFileAccessPattern (FileAccessPattern.Random)")]
-               public void AdviseRandomAccess ()
-               {
-                       UnixFile.AdviseRandomAccess (fileDescriptor);
-               }
-
-               [Obsolete ("Use AdviseFileAccessPattern (FileAccessPattern.UseSoon, offset, len)")]
-               public void AdviseNeedAccess (long offset, long len)
-               {
-                       UnixFile.AdviseNeedAccess (fileDescriptor, offset, len);
-               }
-
-               [Obsolete ("Use AdviseFileAccessPattern (FileAccessPattern.UseSoon)")]
-               public void AdviseNeedAccess ()
-               {
-                       UnixFile.AdviseNeedAccess (fileDescriptor);
-               }
-
-               [Obsolete ("Use AdviseFileAccessPattern (FileAccessPattern.WillNotUse, offset, len)")]
-               public void AdviseNoAccess (long offset, long len)
-               {
-                       UnixFile.AdviseNoAccess (fileDescriptor, offset, len);
-               }
-
-               [Obsolete ("Use AdviseFileAccessPattern (FileAccessPattern.WillNotUse)")]
-               public void AdviseNoAccess ()
-               {
-                       UnixFile.AdviseNoAccess (fileDescriptor);
-               }
-
-               [Obsolete ("Use AdviseFileAccessPattern (FileAccessPattern.UseOnce, offset, len)")]
-               public void AdviseOnceAccess (long offset, long len)
-               {
-                       UnixFile.AdviseOnceAccess (fileDescriptor, offset, len);
-               }
-
-               [Obsolete ("Use AdviseFileAccessPattern (FileAccessPattern.UseOnce)")]
-               public void AdviseOnceAccess ()
-               {
-                       UnixFile.AdviseOnceAccess (fileDescriptor);
-               }
-
                public override void Flush ()
                {
-                       int r = Native.Syscall.fsync (fileDescriptor);
-
-                       if (r == -1) {
-                               Native.Errno e = Native.Stdlib.GetLastError ();
-
-                               // From the man page:
-                               //  EROFS, EINVAL:
-                               //    fd is bound to a special file which does not support
-                               //    synchronization.
-                               // Sockets are such a file, and since Close() calls Flush(), and we
-                               // want to support manually opened sockets, we shouldn't generate an
-                               // exception for these errors.
-                               if (e == Native.Errno.EROFS || e == Native.Errno.EINVAL) {
-                                       return;
-                               }
-
-                               UnixMarshal.ThrowExceptionForError (e);
-                       }
                }
 
                public override unsafe int Read ([In, Out] byte[] buffer, int offset, int count)
@@ -304,10 +204,13 @@ namespace Mono.Unix {
                        if (!CanRead)
                                throw new NotSupportedException ("Stream does not support reading");
                                 
+                       if (buffer.Length == 0)
+                               return 0;
+
                        long r = 0;
                        fixed (byte* buf = &buffer[offset]) {
                                do {
-                                       r = Syscall.read (fileDescriptor, buf, (ulong) count);
+                                       r = Native.Syscall.read (fileDescriptor, buf, (ulong) count);
                                } while (UnixMarshal.ShouldRetrySyscall ((int) r));
                        }
                        if (r == -1)
@@ -337,10 +240,13 @@ namespace Mono.Unix {
                        if (!CanRead)
                                throw new NotSupportedException ("Stream does not support reading");
                                 
+                       if (buffer.Length == 0)
+                               return 0;
+
                        long r = 0;
                        fixed (byte* buf = &buffer[offset]) {
                                do {
-                                       r = Syscall.pread (fileDescriptor, buf, (ulong) count, fileOffset);
+                                       r = Native.Syscall.pread (fileDescriptor, buf, (ulong) count, fileOffset);
                                } while (UnixMarshal.ShouldRetrySyscall ((int) r));
                        }
                        if (r == -1)
@@ -356,14 +262,14 @@ namespace Mono.Unix {
                        if (offset > int.MaxValue)
                                throw new ArgumentOutOfRangeException ("offset", "too large");
                                        
-                       SeekFlags sf = SeekFlags.SEEK_CUR;
+                       Native.SeekFlags sf = Native.SeekFlags.SEEK_CUR;
                        switch (origin) {
-                               case SeekOrigin.Begin:   sf = SeekFlags.SEEK_SET; break;
-                               case SeekOrigin.Current: sf = SeekFlags.SEEK_CUR; break;
-                               case SeekOrigin.End:     sf = SeekFlags.SEEK_END; break;
+                               case SeekOrigin.Begin:   sf = Native.SeekFlags.SEEK_SET; break;
+                               case SeekOrigin.Current: sf = Native.SeekFlags.SEEK_CUR; break;
+                               case SeekOrigin.End:     sf = Native.SeekFlags.SEEK_END; break;
                        }
 
-                       long pos = Syscall.lseek (fileDescriptor, offset, sf);
+                       long pos = Native.Syscall.lseek (fileDescriptor, offset, sf);
                        if (pos == -1)
                                UnixMarshal.ThrowExceptionForLastError ();
                        return (long) pos;
@@ -379,7 +285,7 @@ namespace Mono.Unix {
                        
                        int r;
                        do {
-                               r = Syscall.ftruncate (fileDescriptor, value);
+                               r = Native.Syscall.ftruncate (fileDescriptor, value);
                        } while (UnixMarshal.ShouldRetrySyscall (r));
                        UnixMarshal.ThrowExceptionForLastErrorIf (r);
                }
@@ -391,10 +297,13 @@ namespace Mono.Unix {
                        if (!CanWrite)
                                throw new NotSupportedException ("File Descriptor does not support writing");
 
+                       if (buffer.Length == 0)
+                               return;
+
                        long r = 0;
                        fixed (byte* buf = &buffer[offset]) {
                                do {
-                                       r = Syscall.write (fileDescriptor, buf, (ulong) count);
+                                       r = Native.Syscall.write (fileDescriptor, buf, (ulong) count);
                                } while (UnixMarshal.ShouldRetrySyscall ((int) r));
                        }
                        if (r == -1)
@@ -409,10 +318,13 @@ namespace Mono.Unix {
                        if (!CanWrite)
                                throw new NotSupportedException ("File Descriptor does not support writing");
 
+                       if (buffer.Length == 0)
+                               return;
+
                        long r = 0;
                        fixed (byte* buf = &buffer[offset]) {
                                do {
-                                       r = Syscall.pwrite (fileDescriptor, buf, (ulong) count, fileOffset);
+                                       r = Native.Syscall.pwrite (fileDescriptor, buf, (ulong) count, fileOffset);
                                } while (UnixMarshal.ShouldRetrySyscall ((int) r));
                        }
                        if (r == -1)
@@ -436,26 +348,16 @@ namespace Mono.Unix {
                        if (!CanWrite)
                                throw new NotSupportedException ("Unable to write to the current file descriptor");
                        long offset = Position;
-                       long r = Syscall.sendfile (out_fd, fileDescriptor, ref offset, count);
+                       long r = Native.Syscall.sendfile (out_fd, fileDescriptor, ref offset, count);
                        if (r == -1)
                                UnixMarshal.ThrowExceptionForLastError ();
                }
                
-               [CLSCompliant (false)]
-               [Obsolete ("Use SetOwner (long, long)")]
-               public void SetOwner (uint user, uint group)
-               {
-                       AssertNotDisposed ();
-
-                       int r = Syscall.fchown (fileDescriptor, user, group);
-                       UnixMarshal.ThrowExceptionForLastErrorIf (r);
-               }
-
                public void SetOwner (long user, long group)
                {
                        AssertNotDisposed ();
 
-                       int r = Syscall.fchown (fileDescriptor, 
+                       int r = Native.Syscall.fchown (fileDescriptor, 
                                        Convert.ToUInt32 (user), Convert.ToUInt32 (group));
                        UnixMarshal.ThrowExceptionForLastErrorIf (r);
                }
@@ -464,8 +366,8 @@ namespace Mono.Unix {
                {
                        AssertNotDisposed ();
 
-                       uint uid = UnixUser.GetUserId (user);
-                       uint gid = UnixGroup.GetGroupId (group);
+                       long uid = new UnixUserInfo (user).UserId;
+                       long gid = new UnixGroupInfo (group).GroupId;
                        SetOwner (uid, gid);
                }
 
@@ -473,31 +375,20 @@ namespace Mono.Unix {
                {
                        AssertNotDisposed ();
 
-                       Passwd pw = Syscall.getpwnam (user);
+                       Native.Passwd pw = Native.Syscall.getpwnam (user);
                        if (pw == null)
                                throw new ArgumentException (Locale.GetText ("invalid username"), "user");
-                       uint uid = pw.pw_uid;
-                       uint gid = pw.pw_gid;
+                       long uid = pw.pw_uid;
+                       long gid = pw.pw_gid;
                        SetOwner (uid, gid);
                }
 
-               [CLSCompliant (false)]
-               [Obsolete ("Use GetConfigurationValue (Mono.Unix.Native.PathconfName")]
-               public long GetConfigurationValue (PathConf name)
-               {
-                       AssertNotDisposed ();
-                       long r = Syscall.fpathconf (fileDescriptor, name);
-                       if (r == -1 && Syscall.GetLastError() != (Error) 0)
-                               UnixMarshal.ThrowExceptionForLastError ();
-                       return r;
-               }
-
                [CLSCompliant (false)]
                public long GetConfigurationValue (Native.PathconfName name)
                {
                        AssertNotDisposed ();
                        long r = Native.Syscall.fpathconf (fileDescriptor, name);
-                       if (r == -1 && Syscall.GetLastError() != (Error) 0)
+                       if (r == -1 && Native.Syscall.GetLastError() != (Native.Errno) 0)
                                UnixMarshal.ThrowExceptionForLastError ();
                        return r;
                }
@@ -513,9 +404,13 @@ namespace Mono.Unix {
                                return;
                                
                        Flush ();
+
+                       if (!owner)
+                               return;
+
                        int r;
                        do {
-                               r = Syscall.close (fileDescriptor);
+                               r = Native.Syscall.close (fileDescriptor);
                        } while (UnixMarshal.ShouldRetrySyscall (r));
                        UnixMarshal.ThrowExceptionForLastErrorIf (r);
                        fileDescriptor = InvalidFileDescriptor;