5 // Jonathan Pryor (jonpryor@vt.edu)
7 // (C) 2004-2006 Jonathan Pryor
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections;
32 using System.Runtime.InteropServices;
34 using Mono.Unix.Native;
36 namespace Mono.Unix.Native {
41 public enum Errno : int {
42 // errors & their values liberally copied from
43 // FC2 /usr/include/asm/errno.h
45 EPERM = 1, // Operation not permitted
46 ENOENT = 2, // No such file or directory
47 ESRCH = 3, // No such process
48 EINTR = 4, // Interrupted system call
50 ENXIO = 6, // No such device or address
51 E2BIG = 7, // Arg list too long
52 ENOEXEC = 8, // Exec format error
53 EBADF = 9, // Bad file number
54 ECHILD = 10, // No child processes
55 EAGAIN = 11, // Try again
56 ENOMEM = 12, // Out of memory
57 EACCES = 13, // Permission denied
58 EFAULT = 14, // Bad address
59 ENOTBLK = 15, // Block device required
60 EBUSY = 16, // Device or resource busy
61 EEXIST = 17, // File exists
62 EXDEV = 18, // Cross-device link
63 ENODEV = 19, // No such device
64 ENOTDIR = 20, // Not a directory
65 EISDIR = 21, // Is a directory
66 EINVAL = 22, // Invalid argument
67 ENFILE = 23, // File table overflow
68 EMFILE = 24, // Too many open files
69 ENOTTY = 25, // Not a typewriter
70 ETXTBSY = 26, // Text file busy
71 EFBIG = 27, // File too large
72 ENOSPC = 28, // No space left on device
73 ESPIPE = 29, // Illegal seek
74 EROFS = 30, // Read-only file system
75 EMLINK = 31, // Too many links
76 EPIPE = 32, // Broken pipe
77 EDOM = 33, // Math argument out of domain of func
78 ERANGE = 34, // Math result not representable
79 EDEADLK = 35, // Resource deadlock would occur
80 ENAMETOOLONG = 36, // File name too long
81 ENOLCK = 37, // No record locks available
82 ENOSYS = 38, // Function not implemented
83 ENOTEMPTY = 39, // Directory not empty
84 ELOOP = 40, // Too many symbolic links encountered
85 EWOULDBLOCK = EAGAIN, // Operation would block
86 ENOMSG = 42, // No message of desired type
87 EIDRM = 43, // Identifier removed
88 ECHRNG = 44, // Channel number out of range
89 EL2NSYNC = 45, // Level 2 not synchronized
90 EL3HLT = 46, // Level 3 halted
91 EL3RST = 47, // Level 3 reset
92 ELNRNG = 48, // Link number out of range
93 EUNATCH = 49, // Protocol driver not attached
94 ENOCSI = 50, // No CSI structure available
95 EL2HLT = 51, // Level 2 halted
96 EBADE = 52, // Invalid exchange
97 EBADR = 53, // Invalid request descriptor
98 EXFULL = 54, // Exchange full
99 ENOANO = 55, // No anode
100 EBADRQC = 56, // Invalid request code
101 EBADSLT = 57, // Invalid slot
105 EBFONT = 59, // Bad font file format
106 ENOSTR = 60, // Device not a stream
107 ENODATA = 61, // No data available
108 ETIME = 62, // Timer expired
109 ENOSR = 63, // Out of streams resources
110 ENONET = 64, // Machine is not on the network
111 ENOPKG = 65, // Package not installed
112 EREMOTE = 66, // Object is remote
113 ENOLINK = 67, // Link has been severed
114 EADV = 68, // Advertise error
115 ESRMNT = 69, // Srmount error
116 ECOMM = 70, // Communication error on send
117 EPROTO = 71, // Protocol error
118 EMULTIHOP = 72, // Multihop attempted
119 EDOTDOT = 73, // RFS specific error
120 EBADMSG = 74, // Not a data message
121 EOVERFLOW = 75, // Value too large for defined data type
122 ENOTUNIQ = 76, // Name not unique on network
123 EBADFD = 77, // File descriptor in bad state
124 EREMCHG = 78, // Remote address changed
125 ELIBACC = 79, // Can not access a needed shared library
126 ELIBBAD = 80, // Accessing a corrupted shared library
127 ELIBSCN = 81, // .lib section in a.out corrupted
128 ELIBMAX = 82, // Attempting to link in too many shared libraries
129 ELIBEXEC = 83, // Cannot exec a shared library directly
130 EILSEQ = 84, // Illegal byte sequence
131 ERESTART = 85, // Interrupted system call should be restarted
132 ESTRPIPE = 86, // Streams pipe error
133 EUSERS = 87, // Too many users
134 ENOTSOCK = 88, // Socket operation on non-socket
135 EDESTADDRREQ = 89, // Destination address required
136 EMSGSIZE = 90, // Message too long
137 EPROTOTYPE = 91, // Protocol wrong type for socket
138 ENOPROTOOPT = 92, // Protocol not available
139 EPROTONOSUPPORT = 93, // Protocol not supported
140 ESOCKTNOSUPPORT = 94, // Socket type not supported
141 EOPNOTSUPP = 95, // Operation not supported on transport endpoint
142 EPFNOSUPPORT = 96, // Protocol family not supported
143 EAFNOSUPPORT = 97, // Address family not supported by protocol
144 EADDRINUSE = 98, // Address already in use
145 EADDRNOTAVAIL = 99, // Cannot assign requested address
146 ENETDOWN = 100, // Network is down
147 ENETUNREACH = 101, // Network is unreachable
148 ENETRESET = 102, // Network dropped connection because of reset
149 ECONNABORTED = 103, // Software caused connection abort
150 ECONNRESET = 104, // Connection reset by peer
151 ENOBUFS = 105, // No buffer space available
152 EISCONN = 106, // Transport endpoint is already connected
153 ENOTCONN = 107, // Transport endpoint is not connected
154 ESHUTDOWN = 108, // Cannot send after transport endpoint shutdown
155 ETOOMANYREFS = 109, // Too many references: cannot splice
156 ETIMEDOUT = 110, // Connection timed out
157 ECONNREFUSED = 111, // Connection refused
158 EHOSTDOWN = 112, // Host is down
159 EHOSTUNREACH = 113, // No route to host
160 EALREADY = 114, // Operation already in progress
161 EINPROGRESS = 115, // Operation now in progress
162 ESTALE = 116, // Stale NFS file handle
163 EUCLEAN = 117, // Structure needs cleaning
164 ENOTNAM = 118, // Not a XENIX named type file
165 ENAVAIL = 119, // No XENIX semaphores available
166 EISNAM = 120, // Is a named type file
167 EREMOTEIO = 121, // Remote I/O error
168 EDQUOT = 122, // Quota exceeded
170 ENOMEDIUM = 123, // No medium found
171 EMEDIUMTYPE = 124, // Wrong medium type
178 public sealed class FilePosition : MarshalByRefObject, IDisposable
180 , IEquatable <FilePosition>
184 private static readonly int FilePositionDumpSize =
185 Stdlib.DumpFilePosition (null, new HandleRef (null, IntPtr.Zero), 0);
187 private HandleRef pos;
189 public FilePosition ()
191 IntPtr p = Stdlib.CreateFilePosition ();
192 if (p == IntPtr.Zero)
193 throw new OutOfMemoryException ("Unable to malloc fpos_t!");
194 pos = new HandleRef (this, p);
197 internal HandleRef Handle {
201 public void Dispose ()
204 GC.SuppressFinalize (this);
207 private void Cleanup ()
209 if (pos.Handle != IntPtr.Zero) {
210 Stdlib.free (pos.Handle);
211 pos = new HandleRef (this, IntPtr.Zero);
215 public override string ToString ()
217 return "(" + base.ToString () + " " + GetDump () + ")";
220 private string GetDump ()
222 if (FilePositionDumpSize <= 0)
223 return "internal error";
225 StringBuilder buf = new StringBuilder (FilePositionDumpSize+1);
227 if (Stdlib.DumpFilePosition (buf, Handle, FilePositionDumpSize+1) <= 0)
228 return "internal error dumping fpos_t";
230 return buf.ToString ();
233 public override bool Equals (object obj)
235 FilePosition fp = obj as FilePosition;
236 if (obj == null || fp == null)
238 return ToString().Equals (obj.ToString());
241 public bool Equals (FilePosition value)
243 if (object.ReferenceEquals (this, value))
245 return ToString().Equals (value.ToString());
248 public override int GetHashCode ()
250 return ToString ().GetHashCode ();
258 public static bool operator== (FilePosition lhs, FilePosition rhs)
260 return Object.Equals (lhs, rhs);
263 public static bool operator!= (FilePosition lhs, FilePosition rhs)
265 return !Object.Equals (lhs, rhs);
270 public enum SignalAction {
277 // Right now using this attribute gives an assert because it
278 // isn't implemented.
280 #if NET_2_0 && UNMANAGED_FN_PTR_SUPPORT_FIXED
281 [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
283 public delegate void SignalHandler (int signal);
286 internal sealed class SignalWrapper {
287 private IntPtr handler;
289 internal SignalWrapper (IntPtr handler)
291 this.handler = handler;
294 public void InvokeSignalHandler (int signum)
296 Stdlib.InvokeSignalHandler (signum, handler);
301 internal class XPrintfFunctions
303 internal delegate object XPrintf (object[] parameters);
305 internal static XPrintf printf;
306 internal static XPrintf fprintf;
307 internal static XPrintf snprintf;
308 internal static XPrintf syslog;
310 static XPrintfFunctions ()
312 CdeclFunction _printf = new CdeclFunction (Stdlib.LIBC, "printf", typeof(int));
313 printf = new XPrintf (_printf.Invoke);
315 CdeclFunction _fprintf = new CdeclFunction (Stdlib.LIBC, "fprintf", typeof(int));
316 fprintf = new XPrintf (_fprintf.Invoke);
318 CdeclFunction _snprintf = new CdeclFunction (Stdlib.MPH,
319 "Mono_Posix_Stdlib_snprintf", typeof(int));
320 snprintf = new XPrintf (_snprintf.Invoke);
322 CdeclFunction _syslog = new CdeclFunction (Syscall.MPH,
323 "Mono_Posix_Stdlib_syslog2", typeof(int));
324 syslog = new XPrintf (_syslog.Invoke);
329 // Convention: Functions that are part of the C standard library go here.
331 // For example, the man page should say something similar to:
334 // ISO 9899 (''ANSI C'')
336 // The intent is that members of this class should be portable to any system
337 // supporting the C runtime (read: non-Unix, including Windows). Using
338 // anything from Syscall is non-portable, but restricting yourself to just
339 // Stdlib is intended to be portable.
341 // The only methods in here should be:
342 // (1) low-level functions (as defined above).
343 // (2) "Trivial" function overloads. For example, if the parameters to a
344 // function are related (e.g. fwrite(3))
345 // (3) The return type SHOULD NOT be changed. If you want to provide a
346 // convenience function with a nicer return type, place it into one of
347 // the Mono.Unix.Std* wrapper classes, and give it a .NET-styled name.
348 // - EXCEPTION: No public functions should have a `void' return type.
349 // `void' return types should be replaced with `int'.
350 // Rationality: `void'-return functions typically require a
351 // complicated call sequence, such as clear errno, then call, then
352 // check errno to see if any errors occurred. This sequence can't
353 // be done safely in managed code, as errno may change as part of
354 // the P/Invoke mechanism.
355 // Instead, add a MonoPosixHelper export which does:
358 // return errno == 0 ? 0 : -1;
359 // This lets managed code check the return value in the usual manner.
360 // (4) Exceptions SHOULD NOT be thrown. EXCEPTIONS:
361 // - If you're wrapping *broken* methods which make assumptions about
362 // input data, such as that an argument refers to N bytes of data.
363 // This is currently limited to cuserid(3) and encrypt(3).
364 // - If you call functions which themselves generate exceptions.
365 // This is the case for using NativeConvert, which will throw an
366 // exception if an invalid/unsupported value is used.
370 internal const string LIBC = "msvcrt";
371 internal const string MPH = "MonoPosixHelper";
373 internal Stdlib () {}
375 #region <errno.h> Declarations
377 // <errno.h> -- COMPLETE
380 public static Errno GetLastError ()
382 int errno = Marshal.GetLastWin32Error ();
383 return NativeConvert.ToErrno (errno);
386 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
387 EntryPoint="Mono_Posix_Stdlib_SetLastError")]
388 private static extern void SetLastError (int error);
390 protected static void SetLastError (Errno error)
392 int _error = NativeConvert.FromErrno (error);
393 SetLastError (_error);
401 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
402 EntryPoint="Mono_Posix_Stdlib_InvokeSignalHandler")]
403 internal static extern void InvokeSignalHandler (int signum, IntPtr handler);
405 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
406 EntryPoint="Mono_Posix_Stdlib_SIG_DFL")]
407 private static extern IntPtr GetDefaultSignal ();
409 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
410 EntryPoint="Mono_Posix_Stdlib_SIG_ERR")]
411 private static extern IntPtr GetErrorSignal ();
413 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
414 EntryPoint="Mono_Posix_Stdlib_SIG_IGN")]
415 private static extern IntPtr GetIgnoreSignal ();
417 private static readonly IntPtr _SIG_DFL = GetDefaultSignal ();
418 private static readonly IntPtr _SIG_ERR = GetErrorSignal ();
419 private static readonly IntPtr _SIG_IGN = GetIgnoreSignal ();
421 private static void _ErrorHandler (int signum)
423 Console.Error.WriteLine ("Error handler invoked for signum " +
424 signum + ". Don't do that.");
427 private static void _DefaultHandler (int signum)
429 Console.Error.WriteLine ("Default handler invoked for signum " +
430 signum + ". Don't do that.");
433 private static void _IgnoreHandler (int signum)
435 Console.Error.WriteLine ("Ignore handler invoked for signum " +
436 signum + ". Don't do that.");
439 [CLSCompliant (false)]
440 public static readonly SignalHandler SIG_DFL = new SignalHandler (_DefaultHandler);
441 [CLSCompliant (false)]
442 public static readonly SignalHandler SIG_ERR = new SignalHandler (_ErrorHandler);
443 [CLSCompliant (false)]
444 public static readonly SignalHandler SIG_IGN = new SignalHandler (_IgnoreHandler);
446 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
447 SetLastError=true, EntryPoint="signal")]
448 private static extern IntPtr sys_signal (int signum, SignalHandler handler);
450 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
451 SetLastError=true, EntryPoint="signal")]
452 private static extern IntPtr sys_signal (int signum, IntPtr handler);
454 [CLSCompliant (false)]
455 [Obsolete ("This is not safe; " +
456 "use Mono.Unix.UnixSignal for signal delivery or SetSignalAction()")]
457 public static SignalHandler signal (Signum signum, SignalHandler handler)
459 int _sig = NativeConvert.FromSignum (signum);
461 Delegate[] handlers = handler.GetInvocationList ();
462 for (int i = 0; i < handlers.Length; ++i) {
463 Marshal.Prelink (handlers [i].Method);
467 if (handler == SIG_DFL)
468 r = sys_signal (_sig, _SIG_DFL);
469 else if (handler == SIG_ERR)
470 r = sys_signal (_sig, _SIG_ERR);
471 else if (handler == SIG_IGN)
472 r = sys_signal (_sig, _SIG_IGN);
474 r = sys_signal (_sig, handler);
475 return TranslateHandler (r);
478 private static SignalHandler TranslateHandler (IntPtr handler)
480 if (handler == _SIG_DFL)
482 if (handler == _SIG_ERR)
484 if (handler == _SIG_IGN)
487 return (SignalHandler) Marshal.GetDelegateForFunctionPointer (handler, typeof(SignalHandler));
489 return new SignalHandler (new SignalWrapper (handler).InvokeSignalHandler);
493 public static int SetSignalAction (Signum signal, SignalAction action)
495 return SetSignalAction (NativeConvert.FromSignum (signal), action);
498 public static int SetSignalAction (RealTimeSignum rts, SignalAction action)
500 return SetSignalAction (NativeConvert.FromRealTimeSignum (rts), action);
503 private static int SetSignalAction (int signum, SignalAction action)
505 IntPtr handler = IntPtr.Zero;
507 case SignalAction.Default:
510 case SignalAction.Ignore:
513 case SignalAction.Error:
517 throw new ArgumentException ("Invalid action value.", "action");
519 IntPtr r = sys_signal (signum, handler);
525 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, EntryPoint="raise")]
526 private static extern int sys_raise (int sig);
528 [CLSCompliant (false)]
529 public static int raise (Signum sig)
531 return sys_raise (NativeConvert.FromSignum (sig));
534 public static int raise (RealTimeSignum rts)
536 return sys_raise (NativeConvert.FromRealTimeSignum (rts));
540 // <stdio.h> -- COMPLETE except for :
541 // - the scanf(3) family .
542 // - vararg functions.
543 // - Horribly unsafe functions (gets(3)).
545 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
546 EntryPoint="Mono_Posix_Stdlib__IOFBF")]
547 private static extern int GetFullyBuffered ();
549 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
550 EntryPoint="Mono_Posix_Stdlib__IOLBF")]
551 private static extern int GetLineBuffered ();
553 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
554 EntryPoint="Mono_Posix_Stdlib__IONBF")]
555 private static extern int GetNonBuffered ();
557 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
558 EntryPoint="Mono_Posix_Stdlib_BUFSIZ")]
559 private static extern int GetBufferSize ();
561 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
562 EntryPoint="Mono_Posix_Stdlib_CreateFilePosition")]
563 internal static extern IntPtr CreateFilePosition ();
565 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
566 EntryPoint="Mono_Posix_Stdlib_DumpFilePosition")]
567 internal static extern int DumpFilePosition (StringBuilder buf, HandleRef handle, int len);
569 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
570 EntryPoint="Mono_Posix_Stdlib_EOF")]
571 private static extern int GetEOF ();
573 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
574 EntryPoint="Mono_Posix_Stdlib_FILENAME_MAX")]
575 private static extern int GetFilenameMax ();
577 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
578 EntryPoint="Mono_Posix_Stdlib_FOPEN_MAX")]
579 private static extern int GetFopenMax ();
581 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
582 EntryPoint="Mono_Posix_Stdlib_L_tmpnam")]
583 private static extern int GetTmpnamLength ();
585 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
586 EntryPoint="Mono_Posix_Stdlib_stdin")]
587 private static extern IntPtr GetStandardInput ();
589 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
590 EntryPoint="Mono_Posix_Stdlib_stdout")]
591 private static extern IntPtr GetStandardOutput ();
593 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
594 EntryPoint="Mono_Posix_Stdlib_stderr")]
595 private static extern IntPtr GetStandardError ();
597 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
598 EntryPoint="Mono_Posix_Stdlib_TMP_MAX")]
599 private static extern int GetTmpMax ();
601 [CLSCompliant (false)]
602 public static readonly int _IOFBF = GetFullyBuffered ();
603 [CLSCompliant (false)]
604 public static readonly int _IOLBF = GetLineBuffered ();
605 [CLSCompliant (false)]
606 public static readonly int _IONBF = GetNonBuffered ();
607 [CLSCompliant (false)]
608 public static readonly int BUFSIZ = GetBufferSize ();
609 [CLSCompliant (false)]
610 public static readonly int EOF = GetEOF ();
611 [CLSCompliant (false)]
612 public static readonly int FOPEN_MAX = GetFopenMax ();
613 [CLSCompliant (false)]
614 public static readonly int FILENAME_MAX = GetFilenameMax ();
615 [CLSCompliant (false)]
616 public static readonly int L_tmpnam = GetTmpnamLength ();
617 public static readonly IntPtr stderr = GetStandardError ();
618 public static readonly IntPtr stdin = GetStandardInput ();
619 public static readonly IntPtr stdout = GetStandardOutput ();
620 [CLSCompliant (false)]
621 public static readonly int TMP_MAX = GetTmpMax ();
623 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
624 public static extern int remove (
625 [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
628 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
629 public static extern int rename (
630 [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
632 [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
635 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
636 public static extern IntPtr tmpfile ();
638 private static object tmpnam_lock = new object ();
640 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
641 SetLastError=true, EntryPoint="tmpnam")]
642 private static extern IntPtr sys_tmpnam (StringBuilder s);
644 [Obsolete ("Syscall.mkstemp() should be preferred.")]
645 public static string tmpnam (StringBuilder s)
647 if (s != null && s.Capacity < L_tmpnam)
648 throw new ArgumentOutOfRangeException ("s", "s.Capacity < L_tmpnam");
650 IntPtr r = sys_tmpnam (s);
651 return UnixMarshal.PtrToString (r);
655 [Obsolete ("Syscall.mkstemp() should be preferred.")]
656 public static string tmpnam ()
659 IntPtr r = sys_tmpnam (null);
660 return UnixMarshal.PtrToString (r);
664 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
665 public static extern int fclose (IntPtr stream);
667 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
668 public static extern int fflush (IntPtr stream);
670 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
671 public static extern IntPtr fopen (
672 [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
673 string path, string mode);
675 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
676 public static extern IntPtr freopen (
677 [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
678 string path, string mode, IntPtr stream);
680 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
681 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_setbuf")]
682 public static extern int setbuf (IntPtr stream, IntPtr buf);
684 [CLSCompliant (false)]
685 public static unsafe int setbuf (IntPtr stream, byte* buf)
687 return setbuf (stream, (IntPtr) buf);
690 [CLSCompliant (false)]
691 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
692 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_setvbuf")]
693 public static extern int setvbuf (IntPtr stream, IntPtr buf, int mode, ulong size);
695 [CLSCompliant (false)]
696 public static unsafe int setvbuf (IntPtr stream, byte* buf, int mode, ulong size)
698 return setvbuf (stream, (IntPtr) buf, mode, size);
701 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
702 EntryPoint="fprintf")]
703 private static extern int sys_fprintf (IntPtr stream, string format, string message);
705 public static int fprintf (IntPtr stream, string message)
707 return sys_fprintf (stream, "%s", message);
710 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
711 "Use fprintf (IntPtr, string) instead.")]
712 public static int fprintf (IntPtr stream, string format, params object[] parameters)
714 object[] _parameters = new object[checked(parameters.Length+2)];
715 _parameters [0] = stream;
716 _parameters [1] = format;
717 Array.Copy (parameters, 0, _parameters, 2, parameters.Length);
718 return (int) XPrintfFunctions.fprintf (_parameters);
721 /* SKIP: fscanf(3) */
723 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
724 EntryPoint="printf")]
725 private static extern int sys_printf (string format, string message);
727 public static int printf (string message)
729 return sys_printf ("%s", message);
732 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
733 "Use printf (string) instead.")]
734 public static int printf (string format, params object[] parameters)
736 object[] _parameters = new object[checked(parameters.Length+1)];
737 _parameters [0] = format;
738 Array.Copy (parameters, 0, _parameters, 1, parameters.Length);
739 return (int) XPrintfFunctions.printf (_parameters);
744 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
745 EntryPoint="Mono_Posix_Stdlib_snprintf")]
746 private static extern int sys_snprintf (StringBuilder s, ulong n,
747 string format, string message);
749 [CLSCompliant (false)]
750 public static int snprintf (StringBuilder s, ulong n, string message)
752 if (n > (ulong) s.Capacity)
753 throw new ArgumentOutOfRangeException ("n", "n must be <= s.Capacity");
754 return sys_snprintf (s, n, "%s", message);
757 public static int snprintf (StringBuilder s, string message)
759 return sys_snprintf (s, (ulong) s.Capacity, "%s", message);
762 [CLSCompliant (false)]
763 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
764 "Use snprintf (StringBuilder, string) instead.")]
765 public static int snprintf (StringBuilder s, ulong n,
766 string format, params object[] parameters)
768 if (n > (ulong) s.Capacity)
769 throw new ArgumentOutOfRangeException ("n", "n must be <= s.Capacity");
771 object[] _parameters = new object[checked(parameters.Length+3)];
774 _parameters [2] = format;
775 Array.Copy (parameters, 0, _parameters, 3, parameters.Length);
776 return (int) XPrintfFunctions.snprintf (_parameters);
779 [CLSCompliant (false)]
780 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
781 "Use snprintf (StringBuilder, string) instead.")]
782 public static int snprintf (StringBuilder s,
783 string format, params object[] parameters)
785 object[] _parameters = new object[checked(parameters.Length+3)];
787 _parameters [1] = (ulong) s.Capacity;
788 _parameters [2] = format;
789 Array.Copy (parameters, 0, _parameters, 3, parameters.Length);
790 return (int) XPrintfFunctions.snprintf (_parameters);
806 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
807 public static extern int fgetc (IntPtr stream);
809 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
810 SetLastError=true, EntryPoint="fgets")]
811 private static extern IntPtr sys_fgets (StringBuilder sb, int size, IntPtr stream);
813 public static StringBuilder fgets (StringBuilder sb, int size, IntPtr stream)
815 IntPtr r = sys_fgets (sb, size, stream);
816 if (r == IntPtr.Zero)
821 public static StringBuilder fgets (StringBuilder sb, IntPtr stream)
823 return fgets (sb, sb.Capacity, stream);
826 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
827 public static extern int fputc (int c, IntPtr stream);
829 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
830 public static extern int fputs (string s, IntPtr stream);
832 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
833 public static extern int getc (IntPtr stream);
835 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
836 public static extern int getchar ();
840 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
841 public static extern int putc (int c, IntPtr stream);
843 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
844 public static extern int putchar (int c);
846 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
847 public static extern int puts (string s);
849 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
850 public static extern int ungetc (int c, IntPtr stream);
852 [CLSCompliant (false)]
853 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
854 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fread")]
855 public static extern ulong fread (IntPtr ptr, ulong size, ulong nmemb, IntPtr stream);
857 [CLSCompliant (false)]
858 public static unsafe ulong fread (void* ptr, ulong size, ulong nmemb, IntPtr stream)
860 return fread ((IntPtr) ptr, size, nmemb, stream);
863 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
864 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fread")]
865 private static extern ulong sys_fread ([Out] byte[] ptr,
866 ulong size, ulong nmemb, IntPtr stream);
868 [CLSCompliant (false)]
869 public static ulong fread (byte[] ptr, ulong size, ulong nmemb, IntPtr stream)
871 if ((size * nmemb) > (ulong) ptr.Length)
872 throw new ArgumentOutOfRangeException ("nmemb");
873 return sys_fread (ptr, size, nmemb, stream);
876 [CLSCompliant (false)]
877 public static ulong fread (byte[] ptr, IntPtr stream)
879 return fread (ptr, 1, (ulong) ptr.Length, stream);
882 [CLSCompliant (false)]
883 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
884 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fwrite")]
885 public static extern ulong fwrite (IntPtr ptr, ulong size, ulong nmemb, IntPtr stream);
887 [CLSCompliant (false)]
888 public static unsafe ulong fwrite (void* ptr, ulong size, ulong nmemb, IntPtr stream)
890 return fwrite ((IntPtr) ptr, size, nmemb, stream);
893 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
894 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fwrite")]
895 private static extern ulong sys_fwrite (byte[] ptr,
896 ulong size, ulong nmemb, IntPtr stream);
898 [CLSCompliant (false)]
899 public static ulong fwrite (byte[] ptr, ulong size, ulong nmemb, IntPtr stream)
901 if ((size * nmemb) > (ulong) ptr.Length)
902 throw new ArgumentOutOfRangeException ("nmemb");
903 return sys_fwrite (ptr, size, nmemb, stream);
906 [CLSCompliant (false)]
907 public static ulong fwrite (byte[] ptr, IntPtr stream)
909 return fwrite (ptr, 1, (ulong) ptr.Length, stream);
912 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
913 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fgetpos")]
914 private static extern int sys_fgetpos (IntPtr stream, HandleRef pos);
916 public static int fgetpos (IntPtr stream, FilePosition pos)
918 return sys_fgetpos (stream, pos.Handle);
921 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
922 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fseek")]
923 private static extern int sys_fseek (IntPtr stream, long offset, int origin);
925 [CLSCompliant (false)]
926 public static int fseek (IntPtr stream, long offset, SeekFlags origin)
928 int _origin = NativeConvert.FromSeekFlags (origin);
929 return sys_fseek (stream, offset, _origin);
932 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
933 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fsetpos")]
934 private static extern int sys_fsetpos (IntPtr stream, HandleRef pos);
936 public static int fsetpos (IntPtr stream, FilePosition pos)
938 return sys_fsetpos (stream, pos.Handle);
941 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
942 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_ftell")]
943 public static extern long ftell (IntPtr stream);
945 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
946 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_rewind")]
947 public static extern int rewind (IntPtr stream);
949 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
950 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_clearerr")]
951 public static extern int clearerr (IntPtr stream);
953 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
954 public static extern int feof (IntPtr stream);
956 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
957 public static extern int ferror (IntPtr stream);
959 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
960 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_perror")]
961 private static extern int perror (string s, int err);
963 public static int perror (string s)
965 return perror (s, Marshal.GetLastWin32Error ());
971 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
972 EntryPoint="Mono_Posix_Stdlib_EXIT_FAILURE")]
973 private static extern int GetExitFailure();
975 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
976 EntryPoint="Mono_Posix_Stdlib_EXIT_SUCCESS")]
977 private static extern int GetExitSuccess ();
979 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
980 EntryPoint="Mono_Posix_Stdlib_MB_CUR_MAX")]
981 private static extern int GetMbCurMax ();
983 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
984 EntryPoint="Mono_Posix_Stdlib_RAND_MAX")]
985 private static extern int GetRandMax ();
987 [CLSCompliant (false)]
988 public static readonly int EXIT_FAILURE = GetExitFailure ();
989 [CLSCompliant (false)]
990 public static readonly int EXIT_SUCCESS = GetExitSuccess ();
991 [CLSCompliant (false)]
992 public static readonly int MB_CUR_MAX = GetMbCurMax ();
993 [CLSCompliant (false)]
994 public static readonly int RAND_MAX = GetRandMax ();
996 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
997 public static extern int rand ();
999 [CLSCompliant (false)]
1000 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
1001 public static extern void srand (uint seed);
1004 // void *calloc (size_t nmemb, size_t size);
1005 [CLSCompliant (false)]
1006 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1007 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_calloc")]
1008 public static extern IntPtr calloc (ulong nmemb, ulong size);
1010 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
1011 public static extern void free (IntPtr ptr);
1014 // void *malloc(size_t size);
1015 [CLSCompliant (false)]
1016 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1017 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_malloc")]
1018 public static extern IntPtr malloc (ulong size);
1021 // void *realloc(void *ptr, size_t size);
1022 [CLSCompliant (false)]
1023 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1024 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_realloc")]
1025 public static extern IntPtr realloc (IntPtr ptr, ulong size);
1027 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
1028 public static extern void abort ();
1030 /* SKIP: atexit(3) -- the GC should have collected most references by the
1031 * time this runs, so no delegates should exist, making it pointless. */
1033 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
1034 public static extern void exit (int status);
1036 [CLSCompliant (false)]
1037 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
1038 public static extern void _Exit (int status);
1040 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, EntryPoint="getenv")]
1041 private static extern IntPtr sys_getenv (string name);
1043 public static string getenv (string name)
1045 IntPtr r = sys_getenv (name);
1046 return UnixMarshal.PtrToString (r);
1049 [CLSCompliant (false)]
1050 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
1051 public static extern int system (string @string);
1057 private static object strerror_lock = new object ();
1059 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
1060 SetLastError=true, EntryPoint="strerror")]
1061 private static extern IntPtr sys_strerror (int errnum);
1063 [CLSCompliant (false)]
1064 public static string strerror (Errno errnum)
1066 int e = NativeConvert.FromErrno (errnum);
1067 lock (strerror_lock) {
1068 IntPtr r = sys_strerror (e);
1069 return UnixMarshal.PtrToString (r);
1074 // size_t strlen(const char *s);
1075 [CLSCompliant (false)]
1076 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1077 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_strlen")]
1078 public static extern ulong strlen (IntPtr s);
1081 #endregion // Classes