// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
-// (C) 2004 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
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;
}
AssertNotDisposed ();
if (!CanSeek)
throw new NotSupportedException ("File descriptor doesn't support seeking");
- Stat stat;
- int r = Syscall.fstat (fileDescriptor, out stat);
- UnixMarshal.ThrowExceptionForLastErrorIf (r);
- return (long) stat.st_size;
+ RefreshStat ();
+ return stat.st_size;
}
}
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;
}
[CLSCompliant (false)]
- [Obsolete ("The type of this property will change in the next release.")]
- public FilePermissions Permissions {
+ public Native.FilePermissions Protection {
get {
- Stat stat;
- int r = Syscall.fstat (fileDescriptor, out stat);
- UnixMarshal.ThrowExceptionForLastErrorIf (r);
+ RefreshStat ();
return stat.st_mode;
}
set {
- int r = Syscall.fchmod (fileDescriptor, value);
+ // we can't change file type with fchmod, so clear out that portion
+ value &= ~Native.FilePermissions.S_IFMT;
+ int r = Native.Syscall.fchmod (fileDescriptor, value);
UnixMarshal.ThrowExceptionForLastErrorIf (r);
}
}
- public void AdviseNormalAccess (long offset, long len)
- {
- UnixFile.AdviseNormalAccess (fileDescriptor, offset, len);
- }
-
- public void AdviseNormalAccess ()
- {
- UnixFile.AdviseNormalAccess (fileDescriptor);
+ public FileTypes FileType {
+ get {
+ int type = (int) Protection;
+ return (FileTypes) (type & (int) UnixFileSystemInfo.AllFileTypes);
+ }
+ // no set as fchmod(2) won't accept changing the file type.
}
- public void AdviseSequentialAccess (long offset, long len)
- {
- UnixFile.AdviseSequentialAccess (fileDescriptor, offset, len);
+ public FileAccessPermissions FileAccessPermissions {
+ get {
+ int perms = (int) Protection;
+ return (FileAccessPermissions) (perms & (int) FileAccessPermissions.AllPermissions);
+ }
+ set {
+ int perms = (int) Protection;
+ perms &= (int) ~FileAccessPermissions.AllPermissions;
+ perms |= (int) value;
+ Protection = (Native.FilePermissions) perms;
+ }
}
- public void AdviseSequentialAccess ()
- {
- UnixFile.AdviseSequentialAccess (fileDescriptor);
+ public FileSpecialAttributes FileSpecialAttributes {
+ get {
+ int attrs = (int) Protection;
+ return (FileSpecialAttributes) (attrs & (int) UnixFileSystemInfo.AllSpecialAttributes);
+ }
+ set {
+ int perms = (int) Protection;
+ perms &= (int) ~UnixFileSystemInfo.AllSpecialAttributes;
+ perms |= (int) value;
+ Protection = (Native.FilePermissions) perms;
+ }
}
- public void AdviseRandomAccess (long offset, long len)
- {
- UnixFile.AdviseRandomAccess (fileDescriptor, offset, len);
+ public UnixUserInfo OwnerUser {
+ get {RefreshStat (); return new UnixUserInfo (stat.st_uid);}
}
-
- public void AdviseRandomAccess ()
- {
- UnixFile.AdviseRandomAccess (fileDescriptor);
+
+ public long OwnerUserId {
+ get {RefreshStat (); return stat.st_uid;}
}
-
- public void AdviseNeedAccess (long offset, long len)
- {
- UnixFile.AdviseNeedAccess (fileDescriptor, offset, len);
+
+ public UnixGroupInfo OwnerGroup {
+ get {RefreshStat (); return new UnixGroupInfo (stat.st_gid);}
}
-
- public void AdviseNeedAccess ()
- {
- UnixFile.AdviseNeedAccess (fileDescriptor);
+
+ public long OwnerGroupId {
+ get {RefreshStat (); return stat.st_gid;}
}
- public void AdviseNoAccess (long offset, long len)
+ private void RefreshStat ()
{
- UnixFile.AdviseNoAccess (fileDescriptor, offset, len);
- }
-
- public void AdviseNoAccess ()
- {
- UnixFile.AdviseNoAccess (fileDescriptor);
+ AssertNotDisposed ();
+ int r = Native.Syscall.fstat (fileDescriptor, out stat);
+ UnixMarshal.ThrowExceptionForLastErrorIf (r);
}
- public void AdviseOnceAccess (long offset, long len)
+ public void AdviseFileAccessPattern (FileAccessPattern pattern, long offset, long len)
{
- UnixFile.AdviseOnceAccess (fileDescriptor, offset, len);
+ FileHandleOperations.AdviseFileAccessPattern (fileDescriptor, pattern, offset, len);
}
- public void AdviseOnceAccess ()
+ public void AdviseFileAccessPattern (FileAccessPattern pattern)
{
- UnixFile.AdviseOnceAccess (fileDescriptor);
+ AdviseFileAccessPattern (pattern, 0, 0);
}
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)
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)
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)
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;
int r;
do {
- r = Syscall.ftruncate (fileDescriptor, value);
+ r = Native.Syscall.ftruncate (fileDescriptor, value);
} while (UnixMarshal.ShouldRetrySyscall (r));
UnixMarshal.ThrowExceptionForLastErrorIf (r);
}
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)
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)
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);
}
{
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);
}
{
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 ();
- Syscall.SetLastError ((Error) 0);
- 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 ();
- Syscall.SetLastError ((Error) 0);
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;
}
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;
private bool canWrite = false;
private bool owner = true;
private int fileDescriptor = InvalidFileDescriptor;
+ private Native.Stat stat;
}
}