// Jonathan Pryor (jonpryor@vt.edu)
//
// (C) 2003 Novell, Inc.
-// (C) 2004-2005 Jonathan Pryor
+// (C) 2004-2006 Jonathan Pryor
//
// This file implements the low-level syscall interface to the POSIX
// subsystem.
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using Mono.Unix.Native;
-[assembly:Mono.Unix.Native.HeaderAttribute (
- Includes=
- "sys/types.h," +
- "sys/stat.h," +
- "ah:sys/poll.h," +
- "ah:sys/wait.h," +
- "ah:sys/statvfs.h," +
- "ah:sys/xattr.h," +
- "ah:sys/mman.h," +
- "unistd.h," +
- "fcntl.h," +
- "signal.h," +
- "ah:poll.h," +
- "ah:grp.h," +
- "errno.h," +
- "ah:syslog.h",
- Defines=
- "_GNU_SOURCE," +
- "_XOPEN_SOURCE"
-)]
-
namespace Mono.Unix.Native {
#region Enumerations
O_DIRECTORY = 0x00010000,
O_DIRECT = 0x00004000,
O_ASYNC = 0x00002000,
- O_LARGEFILE = 0x00008000
+ O_LARGEFILE = 0x00008000,
+ O_CLOEXEC = 0x00080000,
+ O_PATH = 0x00200000
+ }
+
+ [Map][Flags]
+ [CLSCompliant (false)]
+ public enum AtFlags : int {
+ AT_SYMLINK_NOFOLLOW = 0x00000100,
+ AT_REMOVEDIR = 0x00000200,
+ AT_SYMLINK_FOLLOW = 0x00000400,
+ AT_NO_AUTOMOUNT = 0x00000800,
+ AT_EMPTY_PATH = 0x00001000
}
// mode_t
// Device types
// Why these are held in "mode_t" is beyond me...
S_IFMT = 0xF000, // Bits which determine file type
+ [Map(SuppressFlags="S_IFMT")]
S_IFDIR = 0x4000, // Directory
+ [Map(SuppressFlags="S_IFMT")]
S_IFCHR = 0x2000, // Character device
+ [Map(SuppressFlags="S_IFMT")]
S_IFBLK = 0x6000, // Block device
+ [Map(SuppressFlags="S_IFMT")]
S_IFREG = 0x8000, // Regular file
+ [Map(SuppressFlags="S_IFMT")]
S_IFIFO = 0x1000, // FIFO
+ [Map(SuppressFlags="S_IFMT")]
S_IFLNK = 0xA000, // Symbolic link
+ [Map(SuppressFlags="S_IFMT")]
S_IFSOCK = 0xC000, // Socket
}
ST_RDONLY = 1, // Mount read-only
ST_NOSUID = 2, // Ignore suid and sgid bits
ST_NODEV = 4, // Disallow access to device special files
+ ST_NOEXEC = 8, // Disallow program execution
ST_SYNCHRONOUS = 16, // Writes are synced at once
+ ST_REMOUNT = 32, // Alter flags of a mounted FS
ST_MANDLOCK = 64, // Allow mandatory locks on an FS
ST_WRITE = 128, // Write on file/directory/symlink
ST_APPEND = 256, // Append-only file
ST_IMMUTABLE = 512, // Immutable file
ST_NOATIME = 1024, // Do not update access times
ST_NODIRATIME = 2048, // Do not update directory access times
+ ST_BIND = 4096, // Bind directory at different place
}
[Map][Flags]
#region Structures
+ [Map ("struct flock")]
public struct Flock
#if NET_2_0
: IEquatable <Flock>
public LockType l_type; // Type of lock: F_RDLCK, F_WRLCK, F_UNLCK
[CLSCompliant (false)]
public SeekFlags l_whence; // How to interpret l_start
- public /* off_t */ long l_start; // Starting offset for lock
- public /* off_t */ long l_len; // Number of bytes to lock
- public /* pid_t */ int l_pid; // PID of process blocking our lock (F_GETLK only)
+ [off_t] public long l_start; // Starting offset for lock
+ [off_t] public long l_len; // Number of bytes to lock
+ [pid_t] public int l_pid; // PID of process blocking our lock (F_GETLK only)
public override int GetHashCode ()
{
public override bool Equals (object obj)
{
- if (obj.GetType() != GetType())
+ if ((obj == null) || (obj.GetType () != GetType ()))
return false;
Flock value = (Flock) obj;
return l_type == value.l_type && l_whence == value.l_whence &&
}
}
+ [Map ("struct pollfd")]
public struct Pollfd
#if NET_2_0
: IEquatable <Pollfd>
}
}
+ [Map ("struct stat")]
public struct Stat
#if NET_2_0
: IEquatable <Stat>
#endif
{
[CLSCompliant (false)]
- public /* dev_t */ ulong st_dev; // device
- [CLSCompliant (false)]
- public /* ino_t */ ulong st_ino; // inode
+ [dev_t] public ulong st_dev; // device
[CLSCompliant (false)]
- public FilePermissions st_mode; // protection
+ [ino_t] public ulong st_ino; // inode
[CLSCompliant (false)]
- private uint _padding_; // padding for structure alignment
+ public FilePermissions st_mode; // protection
+ [NonSerialized]
+#pragma warning disable 169
+ private uint _padding_; // padding for structure alignment
+#pragma warning restore 169
[CLSCompliant (false)]
- public /* nlink_t */ ulong st_nlink; // number of hard links
+ [nlink_t] public ulong st_nlink; // number of hard links
[CLSCompliant (false)]
- public /* uid_t */ uint st_uid; // user ID of owner
+ [uid_t] public uint st_uid; // user ID of owner
[CLSCompliant (false)]
- public /* gid_t */ uint st_gid; // group ID of owner
+ [gid_t] public uint st_gid; // group ID of owner
[CLSCompliant (false)]
- public /* dev_t */ ulong st_rdev; // device type (if inode device)
- public /* off_t */ long st_size; // total size, in bytes
- public /* blksize_t */ long st_blksize; // blocksize for filesystem I/O
- public /* blkcnt_t */ long st_blocks; // number of blocks allocated
- public /* time_t */ long st_atime; // time of last access
- public /* time_t */ long st_mtime; // time of last modification
- public /* time_t */ long st_ctime; // time of last status change
+ [dev_t] public ulong st_rdev; // device type (if inode device)
+ [off_t] public long st_size; // total size, in bytes
+ [blksize_t] public long st_blksize; // blocksize for filesystem I/O
+ [blkcnt_t] public long st_blocks; // number of blocks allocated
+ [time_t] public long st_atime; // time of last access
+ [time_t] public long st_mtime; // time of last modification
+ [time_t] public long st_ctime; // time of last status change
public override int GetHashCode ()
{
}
}
+ // `struct statvfs' isn't portable, so don't generate To/From methods.
+ [Map]
[CLSCompliant (false)]
public struct Statvfs
#if NET_2_0
{
public ulong f_bsize; // file system block size
public ulong f_frsize; // fragment size
- public /* fsblkcnt_t */ ulong f_blocks; // size of fs in f_frsize units
- public /* fsblkcnt_t */ ulong f_bfree; // # free blocks
- public /* fsblkcnt_t */ ulong f_bavail; // # free blocks for non-root
- public /* fsfilcnt_t */ ulong f_files; // # inodes
- public /* fsfilcnt_t */ ulong f_ffree; // # free inodes
- public /* fsfilcnt_t */ ulong f_favail; // # free inodes for non-root
+ [fsblkcnt_t] public ulong f_blocks; // size of fs in f_frsize units
+ [fsblkcnt_t] public ulong f_bfree; // # free blocks
+ [fsblkcnt_t] public ulong f_bavail; // # free blocks for non-root
+ [fsfilcnt_t] public ulong f_files; // # inodes
+ [fsfilcnt_t] public ulong f_ffree; // # free inodes
+ [fsfilcnt_t] public ulong f_favail; // # free inodes for non-root
public ulong f_fsid; // file system id
public MountFlags f_flag; // mount flags
public ulong f_namemax; // maximum filename length
}
}
+ [Map ("struct timeval")]
public struct Timeval
#if NET_2_0
: IEquatable <Timeval>
#endif
{
- public /* time_t */ long tv_sec; // seconds
- public /* suseconds_t */ long tv_usec; // microseconds
+ [time_t] public long tv_sec; // seconds
+ [suseconds_t] public long tv_usec; // microseconds
public override int GetHashCode ()
{
}
}
+ [Map ("struct timezone")]
public struct Timezone
#if NET_2_0
: IEquatable <Timezone>
#endif
{
public int tz_minuteswest; // minutes W of Greenwich
+#pragma warning disable 169
private int tz_dsttime; // type of dst correction (OBSOLETE)
+#pragma warning restore 169
public override int GetHashCode ()
{
}
}
+ [Map ("struct utimbuf")]
public struct Utimbuf
#if NET_2_0
: IEquatable <Utimbuf>
#endif
{
- public /* time_t */ long actime; // access time
- public /* time_t */ long modtime; // modification time
+ [time_t] public long actime; // access time
+ [time_t] public long modtime; // modification time
public override int GetHashCode ()
{
}
}
+ [Map ("struct timespec")]
+ public struct Timespec
+#if NET_2_0
+ : IEquatable <Timespec>
+#endif
+ {
+ [time_t] public long tv_sec; // Seconds.
+ public long tv_nsec; // Nanoseconds.
+
+ public override int GetHashCode ()
+ {
+ return tv_sec.GetHashCode () ^ tv_nsec.GetHashCode ();
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj == null || obj.GetType () != GetType ())
+ return false;
+ Timespec value = (Timespec) obj;
+ return value.tv_sec == tv_sec && value.tv_nsec == tv_nsec;
+ }
+
+ public bool Equals (Timespec value)
+ {
+ return value.tv_sec == tv_sec && value.tv_nsec == tv_nsec;
+ }
+
+ public static bool operator== (Timespec lhs, Timespec rhs)
+ {
+ return lhs.Equals (rhs);
+ }
+
+ public static bool operator!= (Timespec lhs, Timespec rhs)
+ {
+ return !lhs.Equals (rhs);
+ }
+ }
+
+ [Map ("struct iovec")]
+ public struct Iovec
+ {
+ public IntPtr iov_base; // Starting address
+ [CLSCompliant (false)]
+ public ulong iov_len; // Number of bytes to transfer
+ }
+
+ [Flags][Map]
+ public enum EpollFlags {
+ EPOLL_CLOEXEC = 02000000,
+ EPOLL_NONBLOCK = 04000,
+ }
+
+ [Flags][Map]
+ [CLSCompliant (false)]
+ public enum EpollEvents : uint {
+ EPOLLIN = 0x001,
+ EPOLLPRI = 0x002,
+ EPOLLOUT = 0x004,
+ EPOLLRDNORM = 0x040,
+ EPOLLRDBAND = 0x080,
+ EPOLLWRNORM = 0x100,
+ EPOLLWRBAND = 0x200,
+ EPOLLMSG = 0x400,
+ EPOLLERR = 0x008,
+ EPOLLHUP = 0x010,
+ EPOLLRDHUP = 0x2000,
+ EPOLLONESHOT = 1 << 30,
+ EPOLLET = unchecked ((uint) (1 << 31))
+ }
+
+ public enum EpollOp {
+ EPOLL_CTL_ADD = 1,
+ EPOLL_CTL_DEL = 2,
+ EPOLL_CTL_MOD = 3,
+ }
+
+ [StructLayout (LayoutKind.Explicit, Size=12, Pack=1)]
+ [CLSCompliant (false)]
+ public struct EpollEvent {
+ [FieldOffset (0)]
+ public EpollEvents events;
+ [FieldOffset (4)]
+ public int fd;
+ [FieldOffset (4)]
+ public IntPtr ptr;
+ [FieldOffset (4)]
+ public uint u32;
+ [FieldOffset (4)]
+ public ulong u64;
+ }
#endregion
#region Classes
}
}
+ public sealed class Utsname
+#if NET_2_0
+ : IEquatable <Utsname>
+#endif
+ {
+ public string sysname;
+ public string nodename;
+ public string release;
+ public string version;
+ public string machine;
+ public string domainname;
+
+ public override int GetHashCode ()
+ {
+ return sysname.GetHashCode () ^ nodename.GetHashCode () ^
+ release.GetHashCode () ^ version.GetHashCode () ^
+ machine.GetHashCode () ^ domainname.GetHashCode ();
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj == null || GetType() != obj.GetType())
+ return false;
+ Utsname u = (Utsname) obj;
+ return Equals (u);
+ }
+
+ public bool Equals (Utsname value)
+ {
+ return value.sysname == sysname && value.nodename == nodename &&
+ value.release == release && value.version == version &&
+ value.machine == machine && value.domainname == domainname;
+ }
+
+ // Generate string in /etc/passwd format
+ public override string ToString ()
+ {
+ return string.Format ("{0} {1} {2} {3} {4}",
+ sysname, nodename, release, version, machine);
+ }
+
+ public static bool operator== (Utsname lhs, Utsname rhs)
+ {
+ return Object.Equals (lhs, rhs);
+ }
+
+ public static bool operator!= (Utsname lhs, Utsname rhs)
+ {
+ return !Object.Equals (lhs, rhs);
+ }
+ }
+
//
// Convention: Functions *not* part of the standard C library AND part of
// a POSIX and/or Unix standard (X/Open, SUS, XPG, etc.) go here.
public static extern int rewinddir (IntPtr dir);
private struct _Dirent {
- public /* ino_t */ ulong d_ino;
- public /* off_t */ long d_off;
+ [ino_t] public ulong d_ino;
+ [off_t] public long d_off;
public ushort d_reclen;
public byte d_type;
public IntPtr d_name;
[DllImport (LIBC, SetLastError=true)]
public static extern int dirfd (IntPtr dir);
+
+ [DllImport (LIBC, SetLastError=true)]
+ public static extern IntPtr fdopendir (int fd);
#endregion
#region <fcntl.h> Declarations
[DllImport (MPH, SetLastError=true,
EntryPoint="Mono_Posix_Syscall_posix_fallocate")]
public static extern int posix_fallocate (int fd, long offset, ulong len);
+
+ [DllImport (LIBC, SetLastError=true,
+ EntryPoint="openat")]
+ private static extern int sys_openat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, int flags);
+
+ // openat(2)
+ // int openat(int dirfd, const char *pathname, int flags, mode_t mode);
+ [DllImport (LIBC, SetLastError=true,
+ EntryPoint="openat")]
+ private static extern int sys_openat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, int flags, uint mode);
+
+ public static int openat (int dirfd, string pathname, OpenFlags flags)
+ {
+ int _flags = NativeConvert.FromOpenFlags (flags);
+ return sys_openat (dirfd, pathname, _flags);
+ }
+
+ public static int openat (int dirfd, string pathname, OpenFlags flags, FilePermissions mode)
+ {
+ int _flags = NativeConvert.FromOpenFlags (flags);
+ uint _mode = NativeConvert.FromFilePermissions (mode);
+ return sys_openat (dirfd, pathname, _flags, _mode);
+ }
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_get_at_fdcwd")]
+ private static extern int get_at_fdcwd ();
+
+ public static readonly int AT_FDCWD = get_at_fdcwd ();
+
#endregion
#region <fstab.h> Declarations
//
// <fstab.h> -- COMPLETE
//
+ [Map]
private struct _Fstab {
public IntPtr fs_spec;
public IntPtr fs_file;
//
// <grp.h>
//
- // TODO: putgrent(3), fgetgrent_r(), getgrouplist(2), initgroups(3)
+ // TODO: putgrent(3), fgetgrent_r(), initgroups(3)
+
+ // getgrouplist(2)
+ [DllImport (LIBC, SetLastError=true, EntryPoint="getgrouplist")]
+ private static extern int sys_getgrouplist (string user, uint grp, uint [] groups,ref int ngroups);
+
+ public static Group [] getgrouplist (string username)
+ {
+ if (username == null)
+ throw new ArgumentNullException ("username");
+ if (username.Trim () == "")
+ throw new ArgumentException ("Username cannot be empty", "username");
+ // Syscall to getpwnam to retrieve user uid
+ Passwd pw = Syscall.getpwnam (username);
+ if (pw == null)
+ throw new ArgumentException (string.Format ("User {0} does not exists",username), "username");
+ return getgrouplist (pw);
+ }
+
+ public static Group [] getgrouplist (Passwd user)
+ {
+ if (user == null)
+ throw new ArgumentNullException ("user");
+ // initializing ngroups by 16 to get the group count
+ int ngroups = 8;
+ int res = -1;
+ // allocating buffer to store group uid's
+ uint [] groups=null;
+ do {
+ Array.Resize (ref groups, ngroups*=2);
+ res = sys_getgrouplist (user.pw_name, user.pw_gid, groups, ref ngroups);
+ }
+ while (res == -1);
+ List<Group> result = new List<Group> ();
+ Group gr = null;
+ for (int i = 0; i < res; i++) {
+ gr = Syscall.getgrgid (groups [i]);
+ if (gr != null)
+ result.Add (gr);
+ }
+ return result.ToArray ();
+ }
// setgroups(2)
// int setgroups (size_t size, const gid_t *list);
- [DllImport (MPH, SetLastError=true,
+ [DllImport (MPH, SetLastError=true,
EntryPoint="Mono_Posix_Syscall_setgroups")]
public static extern int setgroups (ulong size, uint[] list);
return setgroups ((ulong) list.Length, list);
}
+ [Map]
private struct _Group
{
public IntPtr gr_name;
public IntPtr gr_passwd;
- public /* gid_t */ uint gr_gid;
+ [gid_t] public uint gr_gid;
public int _gr_nmem_;
public IntPtr gr_mem;
public IntPtr _gr_buf_;
//
// SKIPPING: getpw(3): it's dangerous. Use getpwuid(3) instead.
+ [Map]
private struct _Passwd
{
public IntPtr pw_name;
public IntPtr pw_passwd;
- public /* uid_t */ uint pw_uid;
- public /* gid_t */ uint pw_gid;
+ [uid_t] public uint pw_uid;
+ [gid_t] public uint pw_gid;
public IntPtr pw_gecos;
public IntPtr pw_dir;
public IntPtr pw_shell;
}
}
+ [DllImport (LIBC, SetLastError=true)]
+ public static extern int renameat (int olddirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string oldpath, int newdirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string newpath);
#endregion
#region <stdlib.h> Declarations
[DllImport (LIBC, SetLastError=true)]
public static extern int mkstemp (StringBuilder template);
+ [DllImport (LIBC, SetLastError=true, EntryPoint="mkdtemp")]
+ private static extern IntPtr sys_mkdtemp (StringBuilder template);
+
+ public static StringBuilder mkdtemp (StringBuilder template)
+ {
+ if (sys_mkdtemp (template) == IntPtr.Zero)
+ return null;
+ return template;
+ }
+
[DllImport (LIBC, SetLastError=true)]
public static extern int ttyslot ();
#endregion
+ #region <sys/epoll.h> Declarations
+
+ public static int epoll_create (int size)
+ {
+ return sys_epoll_create (size);
+ }
+
+ public static int epoll_create (EpollFlags flags)
+ {
+ return sys_epoll_create1 (flags);
+ }
+
+ public static int epoll_ctl (int epfd, EpollOp op, int fd, EpollEvents events)
+ {
+ EpollEvent ee = new EpollEvent ();
+ ee.events = events;
+ ee.fd = fd;
+
+ return sys_epoll_ctl (epfd, op, fd, ref ee);
+ }
+
+ public static int epoll_wait (int epfd, EpollEvent [] events, int max_events, int timeout)
+ {
+ if (events.Length < max_events)
+ throw new ArgumentOutOfRangeException ("events", "Must refer to at least 'max_events' elements.");
+
+ return sys_epoll_wait (epfd, events, max_events, timeout);
+ }
+
+ [DllImport (LIBC, SetLastError=true, EntryPoint="epoll_create")]
+ private static extern int sys_epoll_create (int size);
+
+ [DllImport (LIBC, SetLastError=true, EntryPoint="epoll_create1")]
+ private static extern int sys_epoll_create1 (EpollFlags flags);
+
+ [DllImport (LIBC, SetLastError=true, EntryPoint="epoll_ctl")]
+ private static extern int sys_epoll_ctl (int epfd, EpollOp op, int fd, ref EpollEvent ee);
+
+ [DllImport (LIBC, SetLastError=true, EntryPoint="epoll_wait")]
+ private static extern int sys_epoll_wait (int epfd, EpollEvent [] ee, int maxevents, int timeout);
+ #endregion
+
#region <sys/mman.h> Declarations
//
// <sys/mman.h>
return sys_mkfifo (pathname, _mode);
}
+ // fchmodat(2)
+ // int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags);
+ [DllImport (LIBC, SetLastError=true, EntryPoint="fchmodat")]
+ private static extern int sys_fchmodat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, uint mode, int flags);
+
+ public static int fchmodat (int dirfd, string pathname, FilePermissions mode, AtFlags flags)
+ {
+ uint _mode = NativeConvert.FromFilePermissions (mode);
+ int _flags = NativeConvert.FromAtFlags (flags);
+ return sys_fchmodat (dirfd, pathname, _mode, _flags);
+ }
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_fstatat")]
+ public static extern int fstatat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string file_name, out Stat buf, AtFlags flags);
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_get_utime_now")]
+ private static extern long get_utime_now ();
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_get_utime_omit")]
+ private static extern long get_utime_omit ();
+
+ public static readonly long UTIME_NOW = get_utime_now ();
+
+ public static readonly long UTIME_OMIT = get_utime_omit ();
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_futimens")]
+ private static extern int sys_futimens (int fd, Timespec[] times);
+
+ public static int futimens (int fd, Timespec[] times)
+ {
+ if (times != null && times.Length != 2) {
+ SetLastError (Errno.EINVAL);
+ return -1;
+ }
+ return sys_futimens (fd, times);
+ }
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_utimensat")]
+ private static extern int sys_utimensat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, Timespec[] times, int flags);
+
+ public static int utimensat (int dirfd, string pathname, Timespec[] times, AtFlags flags)
+ {
+ if (times != null && times.Length != 2) {
+ SetLastError (Errno.EINVAL);
+ return -1;
+ }
+ int _flags = NativeConvert.FromAtFlags (flags);
+ return sys_utimensat (dirfd, pathname, times, _flags);
+ }
+
+ // mkdirat(2)
+ // int mkdirat(int dirfd, const char *pathname, mode_t mode);
+ [DllImport (LIBC, SetLastError=true, EntryPoint="mkdirat")]
+ private static extern int sys_mkdirat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string oldpath, uint mode);
+
+ public static int mkdirat (int dirfd, string oldpath, FilePermissions mode)
+ {
+ uint _mode = NativeConvert.FromFilePermissions (mode);
+ return sys_mkdirat (dirfd, oldpath, _mode);
+ }
+
+ // mknodat(2)
+ // int mknodat (int dirfd, const char *pathname, mode_t mode, dev_t dev);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_mknodat")]
+ public static extern int mknodat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, FilePermissions mode, ulong dev);
+
+ // mkfifoat(3)
+ // int mkfifoat(int dirfd, const char *pathname, mode_t mode);
+ [DllImport (LIBC, SetLastError=true, EntryPoint="mkfifoat")]
+ private static extern int sys_mkfifoat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, uint mode);
+
+ public static int mkfifoat (int dirfd, string pathname, FilePermissions mode)
+ {
+ uint _mode = NativeConvert.FromFilePermissions (mode);
+ return sys_mkfifoat (dirfd, pathname, _mode);
+ }
#endregion
#region <sys/stat.h> Declarations
// <sys/utsname.h>
//
- // TODO: uname(2)
+ [Map]
+ private struct _Utsname
+ {
+ public IntPtr sysname;
+ public IntPtr nodename;
+ public IntPtr release;
+ public IntPtr version;
+ public IntPtr machine;
+ public IntPtr domainname;
+ public IntPtr _buf_;
+ }
+
+ private static void CopyUtsname (ref Utsname to, ref _Utsname from)
+ {
+ try {
+ to = new Utsname ();
+ to.sysname = UnixMarshal.PtrToString (from.sysname);
+ to.nodename = UnixMarshal.PtrToString (from.nodename);
+ to.release = UnixMarshal.PtrToString (from.release);
+ to.version = UnixMarshal.PtrToString (from.version);
+ to.machine = UnixMarshal.PtrToString (from.machine);
+ to.domainname = UnixMarshal.PtrToString (from.domainname);
+ }
+ finally {
+ Stdlib.free (from._buf_);
+ from._buf_ = IntPtr.Zero;
+ }
+ }
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_uname")]
+ private static extern int sys_uname (out _Utsname buf);
+
+ public static int uname (out Utsname buf)
+ {
+ _Utsname _buf;
+ int r = sys_uname (out _buf);
+ buf = new Utsname ();
+ if (r == 0) {
+ CopyUtsname (ref buf, ref _buf);
+ }
+ return r;
+ }
#region <sys/wait.h> Declarations
//
// <time.h>
//
+ // nanosleep(2)
+ // int nanosleep(const struct timespec *req, struct timespec *rem);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_nanosleep")]
+ public static extern int nanosleep (ref Timespec req, ref Timespec rem);
+
// stime(2)
// int stime(time_t *t);
[DllImport (MPH, SetLastError=true,
swab ((IntPtr) from, (IntPtr) to, n);
}
+ [DllImport (LIBC, SetLastError=true, EntryPoint="faccessat")]
+ private static extern int sys_faccessat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, int mode, int flags);
+
+ public static int faccessat (int dirfd, string pathname, AccessModes mode, AtFlags flags)
+ {
+ int _mode = NativeConvert.FromAccessModes (mode);
+ int _flags = NativeConvert.FromAtFlags (flags);
+ return sys_faccessat (dirfd, pathname, _mode, _flags);
+ }
+
+ // fchownat(2)
+ // int fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags);
+ [DllImport (LIBC, SetLastError=true, EntryPoint="fchownat")]
+ private static extern int sys_fchownat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, uint owner, uint group, int flags);
+
+ public static int fchownat (int dirfd, string pathname, uint owner, uint group, AtFlags flags)
+ {
+ int _flags = NativeConvert.FromAtFlags (flags);
+ return sys_fchownat (dirfd, pathname, owner, group, _flags);
+ }
+
+ [DllImport (LIBC, SetLastError=true, EntryPoint="linkat")]
+ private static extern int sys_linkat (int olddirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string oldpath, int newdirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string newpath, int flags);
+
+ public static int linkat (int olddirfd, string oldpath, int newdirfd, string newpath, AtFlags flags)
+ {
+ int _flags = NativeConvert.FromAtFlags (flags);
+ return sys_linkat (olddirfd, oldpath, newdirfd, newpath, _flags);
+ }
+
+ // readlinkat(2)
+ // int readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsize);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_readlinkat")]
+ public static extern int readlinkat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, [Out] StringBuilder buf, ulong bufsiz);
+
+ public static int readlinkat (int dirfd, string pathname, [Out] StringBuilder buf)
+ {
+ return readlinkat (dirfd, pathname, buf, (ulong) buf.Capacity);
+ }
+
+ [DllImport (LIBC, SetLastError=true)]
+ public static extern int symlinkat (
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string oldpath, int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string newpath);
+
+ [DllImport (LIBC, SetLastError=true, EntryPoint="unlinkat")]
+ private static extern int sys_unlinkat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, int flags);
+
+ public static int unlinkat (int dirfd, string pathname, AtFlags flags)
+ {
+ int _flags = NativeConvert.FromAtFlags (flags);
+ return sys_unlinkat (dirfd, pathname, _flags);
+ }
#endregion
#region <utime.h> Declarations
return sys_utime (filename, ref buf, 0);
}
#endregion
+
+ #region <sys/uio.h> Declarations
+ //
+ // <sys/uio.h> -- COMPLETE
+ //
+
+ // readv(2)
+ // ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_readv")]
+ private static extern long sys_readv (int fd, Iovec[] iov, int iovcnt);
+
+ public static long readv (int fd, Iovec[] iov)
+ {
+ return sys_readv (fd, iov, iov.Length);
+ }
+
+ // writev(2)
+ // ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_writev")]
+ private static extern long sys_writev (int fd, Iovec[] iov, int iovcnt);
+
+ public static long writev (int fd, Iovec[] iov)
+ {
+ return sys_writev (fd, iov, iov.Length);
+ }
+
+ // preadv(2)
+ // ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_preadv")]
+ private static extern long sys_preadv (int fd, Iovec[] iov, int iovcnt, long offset);
+
+ public static long preadv (int fd, Iovec[] iov, long offset)
+ {
+ return sys_preadv (fd, iov, iov.Length, offset);
+ }
+
+ // pwritev(2)
+ // ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_pwritev")]
+ private static extern long sys_pwritev (int fd, Iovec[] iov, int iovcnt, long offset);
+
+ public static long pwritev (int fd, Iovec[] iov, long offset)
+ {
+ return sys_pwritev (fd, iov, iov.Length, offset);
+ }
+ #endregion
}
#endregion