5 // Jonathan Pryor (jonpryor@vt.edu)
7 // (C) 2004-2005 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;
41 public enum Error : 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 : IDisposable {
180 private static readonly int FilePositionDumpSize =
181 Stdlib.DumpFilePosition (null, new HandleRef (null, IntPtr.Zero), 0);
183 private HandleRef pos;
185 public FilePosition ()
187 IntPtr p = Stdlib.CreateFilePosition ();
188 if (p == IntPtr.Zero)
189 throw new OutOfMemoryException ("Unable to malloc fpos_t!");
190 pos = new HandleRef (this, p);
193 internal HandleRef Handle {
197 public void Dispose ()
200 GC.SuppressFinalize (this);
203 private void Cleanup ()
205 if (pos.Handle != IntPtr.Zero) {
206 Stdlib.free (pos.Handle);
207 pos = new HandleRef (this, IntPtr.Zero);
211 public override string ToString ()
213 return "(" + base.ToString () + " " + GetDump () + ")";
216 private string GetDump ()
218 if (FilePositionDumpSize <= 0)
219 return "internal error";
221 StringBuilder buf = new StringBuilder (FilePositionDumpSize+1);
223 if (Stdlib.DumpFilePosition (buf, Handle, FilePositionDumpSize+1) <= 0)
224 return "internal error dumping fpos_t";
226 return buf.ToString ();
229 public override bool Equals (object obj)
231 if (obj == null || GetType() != obj.GetType())
233 return ToString().Equals (obj.ToString());
236 public override int GetHashCode ()
238 return ToString ().GetHashCode ();
246 public static bool operator== (FilePosition lhs, FilePosition rhs)
248 return Object.Equals (lhs, rhs);
251 public static bool operator!= (FilePosition lhs, FilePosition rhs)
253 return !Object.Equals (lhs, rhs);
259 // Right now using this attribute gives an assert because it
260 // isn't implemented.
262 #if NET_2_0 && UNMANAGED_FN_PTR_SUPPORT_FIXED
263 [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
265 public delegate void SignalHandler (int signal);
268 internal sealed class SignalWrapper {
269 private IntPtr handler;
271 internal SignalWrapper (IntPtr handler)
273 this.handler = handler;
276 public void InvokeSignalHandler (int signum)
278 Stdlib.InvokeSignalHandler (signum, handler);
283 internal class XPrintfFunctions
285 internal delegate object XPrintf (object[] parameters);
287 internal static XPrintf printf;
288 internal static XPrintf fprintf;
289 internal static XPrintf snprintf;
290 internal static XPrintf syslog;
292 static XPrintfFunctions ()
294 CdeclFunction _printf = new CdeclFunction (Stdlib.LIBC, "printf", typeof(int));
295 printf = new XPrintf (_printf.Invoke);
297 CdeclFunction _fprintf = new CdeclFunction (Stdlib.LIBC, "fprintf", typeof(int));
298 fprintf = new XPrintf (_fprintf.Invoke);
300 CdeclFunction _snprintf = new CdeclFunction (Stdlib.MPH,
301 "Mono_Posix_Stdlib_snprintf", typeof(int));
302 snprintf = new XPrintf (_snprintf.Invoke);
304 CdeclFunction _syslog = new CdeclFunction (Syscall.LIBC, "syslog", typeof(void));
305 syslog = new XPrintf (_syslog.Invoke);
310 // Convention: Functions that are part of the C standard library go here.
312 // For example, the man page should say something similar to:
315 // ISO 9899 (''ANSI C'')
317 // The intent is that members of this class should be portable to any system
318 // supporting the C runtime (read: non-Unix, including Windows). Using
319 // anything from Syscall is non-portable, but restricting yourself to just
320 // Stdlib is intended to be portable.
324 internal const string LIBC = "msvcrt";
325 internal const string MPH = "MonoPosixHelper";
327 internal Stdlib () {}
329 #region <errno.h> Declarations
331 // <errno.h> -- COMPLETE
334 public static Error GetLastError ()
336 int errno = Marshal.GetLastWin32Error ();
337 return UnixConvert.ToError (errno);
340 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
341 EntryPoint="Mono_Posix_Stdlib_SetLastError")]
342 private static extern void SetLastError (int error);
344 public static void SetLastError (Error error)
346 int _error = UnixConvert.FromError (error);
347 SetLastError (_error);
354 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
355 EntryPoint="Mono_Posix_Stdlib_InvokeSignalHandler")]
356 internal static extern void InvokeSignalHandler (int signum, IntPtr handler);
358 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
359 EntryPoint="Mono_Posix_Stdlib_SIG_DFL")]
360 private static extern IntPtr GetDefaultSignal ();
362 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
363 EntryPoint="Mono_Posix_Stdlib_SIG_ERR")]
364 private static extern IntPtr GetErrorSignal ();
366 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
367 EntryPoint="Mono_Posix_Stdlib_SIG_IGN")]
368 private static extern IntPtr GetIgnoreSignal ();
370 private static readonly IntPtr _SIG_DFL = GetDefaultSignal ();
371 private static readonly IntPtr _SIG_ERR = GetErrorSignal ();
372 private static readonly IntPtr _SIG_IGN = GetIgnoreSignal ();
374 private static void _ErrorHandler (int signum)
376 Console.Error.WriteLine ("Error handler invoked for signum " +
377 signum + ". Don't do that.");
380 private static void _DefaultHandler (int signum)
382 Console.Error.WriteLine ("Default handler invoked for signum " +
383 signum + ". Don't do that.");
386 private static void _IgnoreHandler (int signum)
388 Console.Error.WriteLine ("Ignore handler invoked for signum " +
389 signum + ". Don't do that.");
392 public static readonly SignalHandler SIG_DFL = new SignalHandler (_DefaultHandler);
393 public static readonly SignalHandler SIG_ERR = new SignalHandler (_ErrorHandler);
394 public static readonly SignalHandler SIG_IGN = new SignalHandler (_IgnoreHandler);
396 private static readonly SignalHandler[] registered_signals;
400 Array signals = Enum.GetValues(typeof(Signum));
401 registered_signals = new SignalHandler [(int) signals.GetValue (signals.Length-1)];
404 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
405 SetLastError=true, EntryPoint="signal")]
406 private static extern IntPtr sys_signal (int signum, SignalHandler handler);
408 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
409 SetLastError=true, EntryPoint="signal")]
410 private static extern IntPtr sys_signal (int signum, IntPtr handler);
412 public static SignalHandler signal (Signum signum, SignalHandler handler)
414 int _sig = UnixConvert.FromSignum (signum);
416 lock (registered_signals) {
417 registered_signals [(int) signum] = handler;
421 if (handler == SIG_DFL)
422 r = sys_signal (_sig, _SIG_DFL);
423 else if (handler == SIG_ERR)
424 r = sys_signal (_sig, _SIG_ERR);
425 else if (handler == SIG_IGN)
426 r = sys_signal (_sig, _SIG_IGN);
428 r = sys_signal (_sig, handler);
429 return TranslateHandler (r);
432 private static SignalHandler TranslateHandler (IntPtr handler)
434 if (handler == _SIG_DFL)
436 if (handler == _SIG_ERR)
438 if (handler == _SIG_IGN)
441 return (SignalHandler) Marshal.GetDelegateForFunctionPointer (handler, typeof(SignalHandler));
443 return new SignalHandler (new SignalWrapper (handler).InvokeSignalHandler);
447 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, EntryPoint="raise")]
448 private static extern int sys_raise (int sig);
450 public static int raise (Signum sig)
452 int _sig = UnixConvert.FromSignum (sig);
453 return sys_raise (_sig);
457 // <stdio.h> -- COMPLETE except for :
458 // - the scanf(3) family .
459 // - vararg functions.
460 // - Horribly unsafe functions (gets(3)).
462 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
463 EntryPoint="Mono_Posix_Stdlib__IOFBF")]
464 private static extern int GetFullyBuffered ();
466 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
467 EntryPoint="Mono_Posix_Stdlib__IOLBF")]
468 private static extern int GetLineBuffered ();
470 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
471 EntryPoint="Mono_Posix_Stdlib__IONBF")]
472 private static extern int GetNonBuffered ();
474 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
475 EntryPoint="Mono_Posix_Stdlib_BUFSIZ")]
476 private static extern int GetBufferSize ();
478 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
479 EntryPoint="Mono_Posix_Stdlib_CreateFilePosition")]
480 internal static extern IntPtr CreateFilePosition ();
482 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
483 EntryPoint="Mono_Posix_Stdlib_DumpFilePosition")]
484 internal static extern int DumpFilePosition (StringBuilder buf, HandleRef handle, int len);
486 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
487 EntryPoint="Mono_Posix_Stdlib_EOF")]
488 private static extern int GetEOF ();
490 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
491 EntryPoint="Mono_Posix_Stdlib_FILENAME_MAX")]
492 private static extern int GetFilenameMax ();
494 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
495 EntryPoint="Mono_Posix_Stdlib_FOPEN_MAX")]
496 private static extern int GetFopenMax ();
498 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
499 EntryPoint="Mono_Posix_Stdlib_L_tmpnam")]
500 private static extern int GetTmpnamLength ();
502 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
503 EntryPoint="Mono_Posix_Stdlib_stdin")]
504 private static extern IntPtr GetStandardInput ();
506 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
507 EntryPoint="Mono_Posix_Stdlib_stdout")]
508 private static extern IntPtr GetStandardOutput ();
510 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
511 EntryPoint="Mono_Posix_Stdlib_stderr")]
512 private static extern IntPtr GetStandardError ();
514 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
515 EntryPoint="Mono_Posix_Stdlib_TMP_MAX")]
516 private static extern int GetTmpMax ();
518 public static readonly int _IOFBF = GetFullyBuffered ();
519 public static readonly int _IOLBF = GetLineBuffered ();
520 public static readonly int _IONBF = GetNonBuffered ();
521 public static readonly int BUFSIZ = GetBufferSize ();
522 public static readonly int EOF = GetEOF ();
523 public static readonly int FOPEN_MAX = GetFopenMax ();
524 public static readonly int FILENAME_MAX = GetFilenameMax ();
525 public static readonly int L_tmpnam = GetTmpnamLength ();
526 public static readonly IntPtr stderr = GetStandardError ();
527 public static readonly IntPtr stdin = GetStandardInput ();
528 public static readonly IntPtr stdout = GetStandardOutput ();
529 public static readonly int TMP_MAX = GetTmpMax ();
531 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
532 public static extern int remove (string filename);
534 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
535 public static extern int rename (string oldpath, string newpath);
537 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
538 public static extern IntPtr tmpfile ();
540 private static object tmpnam_lock = new object ();
542 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
543 SetLastError=true, EntryPoint="tmpnam")]
544 private static extern IntPtr sys_tmpnam (StringBuilder s);
546 [Obsolete ("Syscall.mkstemp() should be preferred.")]
547 public static string tmpnam (StringBuilder s)
549 if (s != null && s.Capacity < L_tmpnam)
550 throw new ArgumentOutOfRangeException ("s", "s.Capacity < L_tmpnam");
552 IntPtr r = sys_tmpnam (s);
553 return UnixMarshal.PtrToString (r);
557 [Obsolete ("Syscall.mkstemp() should be preferred.")]
558 public static string tmpnam ()
561 IntPtr r = sys_tmpnam (null);
562 return UnixMarshal.PtrToString (r);
566 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
567 public static extern int fclose (IntPtr stream);
569 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
570 public static extern int fflush (IntPtr stream);
572 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
573 public static extern IntPtr fopen (string path, string mode);
575 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
576 public static extern IntPtr freopen (string path, string mode, IntPtr stream);
578 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
579 public static extern void setbuf (IntPtr stream, IntPtr buf);
581 public static unsafe void setbuf (IntPtr stream, byte* buf)
583 setbuf (stream, (IntPtr) buf);
586 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
587 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_setvbuf")]
588 public static extern int setvbuf (IntPtr stream, IntPtr buf, int mode, ulong size);
590 public static unsafe int setvbuf (IntPtr stream, byte* buf, int mode, ulong size)
592 return setvbuf (stream, (IntPtr) buf, mode, size);
595 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
596 EntryPoint="fprintf")]
597 private static extern int sys_fprintf (IntPtr stream, string format, string message);
599 public static int fprintf (IntPtr stream, string message)
601 return sys_fprintf (stream, "%s", message);
604 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
605 "Use fprintf (IntPtr, string) instead.")]
606 public static int fprintf (IntPtr stream, string format, params object[] parameters)
608 object[] _parameters = new object[checked(parameters.Length+2)];
609 _parameters [0] = stream;
610 _parameters [1] = format;
611 Array.Copy (parameters, 0, _parameters, 2, parameters.Length);
612 return (int) XPrintfFunctions.fprintf (_parameters);
615 /* SKIP: fscanf(3) */
617 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
618 EntryPoint="printf")]
619 private static extern int sys_printf (string format, string message);
621 public static int printf (string message)
623 return sys_printf ("%s", message);
626 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
627 "Use printf (string) instead.")]
628 public static int printf (string format, params object[] parameters)
630 object[] _parameters = new object[checked(parameters.Length+1)];
631 _parameters [0] = format;
632 Array.Copy (parameters, 0, _parameters, 1, parameters.Length);
633 return (int) XPrintfFunctions.printf (_parameters);
638 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
639 EntryPoint="Mono_Posix_Stdlib_snprintf")]
640 private static extern int sys_snprintf (StringBuilder s, ulong n,
641 string format, string message);
643 public static int snprintf (StringBuilder s, ulong n, string message)
645 if (n > (ulong) s.Capacity)
646 throw new ArgumentOutOfRangeException ("n", "n must be <= s.Capacity");
647 return sys_snprintf (s, n, "%s", message);
650 public static int snprintf (StringBuilder s, string message)
652 return sys_snprintf (s, (ulong) s.Capacity, "%s", message);
655 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
656 "Use snprintf (StringBuilder, string) instead.")]
657 public static int snprintf (StringBuilder s, ulong n,
658 string format, params object[] parameters)
660 if (n > (ulong) s.Capacity)
661 throw new ArgumentOutOfRangeException ("n", "n must be <= s.Capacity");
663 object[] _parameters = new object[checked(parameters.Length+3)];
666 _parameters [2] = format;
667 Array.Copy (parameters, 0, _parameters, 3, parameters.Length);
668 return (int) XPrintfFunctions.snprintf (_parameters);
671 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
672 "Use snprintf (StringBuilder, string) instead.")]
673 public static int snprintf (StringBuilder s,
674 string format, params object[] parameters)
676 object[] _parameters = new object[checked(parameters.Length+3)];
678 _parameters [1] = (ulong) s.Capacity;
679 _parameters [2] = format;
680 Array.Copy (parameters, 0, _parameters, 3, parameters.Length);
681 return (int) XPrintfFunctions.snprintf (_parameters);
697 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
698 public static extern int fgetc (IntPtr stream);
700 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
701 SetLastError=true, EntryPoint="fgets")]
702 private static extern IntPtr sys_fgets (StringBuilder sb, int size, IntPtr stream);
704 public static StringBuilder fgets (StringBuilder sb, int size, IntPtr stream)
706 IntPtr r = sys_fgets (sb, size, stream);
707 if (r == IntPtr.Zero)
712 public static StringBuilder fgets (StringBuilder sb, IntPtr stream)
714 return fgets (sb, sb.Capacity, stream);
717 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
718 public static extern int fputc (int c, IntPtr stream);
720 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
721 public static extern int fputs (string s, IntPtr stream);
723 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
724 public static extern int getc (IntPtr stream);
726 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
727 public static extern int getchar ();
731 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
732 public static extern int putc (int c, IntPtr stream);
734 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
735 public static extern int putchar (int c);
737 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
738 public static extern int puts (string s);
740 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
741 public static extern int ungetc (int c, IntPtr stream);
743 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
744 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fread")]
745 public static extern ulong fread (IntPtr ptr, ulong size, ulong nmemb, IntPtr stream);
747 public static unsafe ulong fread (void* ptr, ulong size, ulong nmemb, IntPtr stream)
749 return fread ((IntPtr) ptr, size, nmemb, stream);
752 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
753 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fread")]
754 private static extern ulong sys_fread ([Out] byte[] ptr,
755 ulong size, ulong nmemb, IntPtr stream);
757 public static ulong fread (byte[] ptr, ulong size, ulong nmemb, IntPtr stream)
759 if ((size * nmemb) > (ulong) ptr.Length)
760 throw new ArgumentOutOfRangeException ("nmemb");
761 return sys_fread (ptr, size, nmemb, stream);
764 public static ulong fread (byte[] ptr, IntPtr stream)
766 return fread (ptr, 1, (ulong) ptr.Length, stream);
769 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
770 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fwrite")]
771 public static extern ulong fwrite (IntPtr ptr, ulong size, ulong nmemb, IntPtr stream);
773 public static unsafe ulong fwrite (void* ptr, ulong size, ulong nmemb, IntPtr stream)
775 return fwrite ((IntPtr) ptr, size, nmemb, stream);
778 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
779 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fwrite")]
780 private static extern ulong sys_fwrite (byte[] ptr,
781 ulong size, ulong nmemb, IntPtr stream);
783 public static ulong fwrite (byte[] ptr, ulong size, ulong nmemb, IntPtr stream)
785 if ((size * nmemb) > (ulong) ptr.Length)
786 throw new ArgumentOutOfRangeException ("nmemb");
787 return sys_fwrite (ptr, size, nmemb, stream);
790 public static ulong fwrite (byte[] ptr, IntPtr stream)
792 return fwrite (ptr, 1, (ulong) ptr.Length, stream);
795 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
796 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fgetpos")]
797 private static extern int sys_fgetpos (IntPtr stream, HandleRef pos);
799 public static int fgetpos (IntPtr stream, FilePosition pos)
801 return sys_fgetpos (stream, pos.Handle);
804 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
805 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fseek")]
806 private static extern int sys_fseek (IntPtr stream, long offset, int origin);
808 public static int fseek (IntPtr stream, long offset, SeekFlags origin)
810 int _origin = UnixConvert.FromSeekFlags (origin);
811 return sys_fseek (stream, offset, _origin);
814 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
815 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fsetpos")]
816 private static extern int sys_fsetpos (IntPtr stream, HandleRef pos);
818 public static int fsetpos (IntPtr stream, FilePosition pos)
820 return sys_fsetpos (stream, pos.Handle);
823 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
824 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_ftell")]
825 public static extern long ftell (IntPtr stream);
827 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
828 public static extern void rewind (IntPtr stream);
830 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
831 public static extern void clearerr (IntPtr stream);
833 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
834 public static extern int feof (IntPtr stream);
836 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
837 public static extern int ferror (IntPtr stream);
839 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
840 public static extern void perror (string s);
845 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
846 EntryPoint="Mono_Posix_Stdlib_EXIT_FAILURE")]
847 private static extern int GetExitFailure();
849 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
850 EntryPoint="Mono_Posix_Stdlib_EXIT_SUCCESS")]
851 private static extern int GetExitSuccess ();
853 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
854 EntryPoint="Mono_Posix_Stdlib_MB_CUR_MAX")]
855 private static extern int GetMbCurMax ();
857 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
858 EntryPoint="Mono_Posix_Stdlib_RAND_MAX")]
859 private static extern int GetRandMax ();
861 public static readonly int EXIT_FAILURE = GetExitFailure ();
862 public static readonly int EXIT_SUCCESS = GetExitSuccess ();
863 public static readonly int MB_CUR_MAX = GetMbCurMax ();
864 public static readonly int RAND_MAX = GetRandMax ();
866 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
867 public static extern int rand ();
869 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
870 public static extern void srand (uint seed);
873 // void *calloc (size_t nmemb, size_t size);
874 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
875 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_calloc")]
876 public static extern IntPtr calloc (ulong nmemb, ulong size);
878 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
879 public static extern void free (IntPtr ptr);
882 // void *malloc(size_t size);
883 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
884 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_malloc")]
885 public static extern IntPtr malloc (ulong size);
888 // void *realloc(void *ptr, size_t size);
889 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
890 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_realloc")]
891 public static extern IntPtr realloc (IntPtr ptr, ulong size);
893 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
894 public static extern void abort ();
896 /* SKIP: atexit(3) -- the GC should have collected most references by the
897 * time this runs, so no delegates should exist, making it pointless. */
899 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
900 public static extern void exit (int status);
902 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
903 public static extern void _Exit (int status);
905 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, EntryPoint="getenv")]
906 private static extern IntPtr sys_getenv (string name);
908 public static string getenv (string name)
910 IntPtr r = sys_getenv (name);
911 return UnixMarshal.PtrToString (r);
914 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
915 public static extern int system (string @string);
921 private static object strerror_lock = new object ();
923 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
924 SetLastError=true, EntryPoint="strerror")]
925 private static extern IntPtr sys_strerror (int errnum);
927 public static string strerror (Error errnum)
929 int e = UnixConvert.FromError (errnum);
930 lock (strerror_lock) {
931 IntPtr r = sys_strerror (e);
932 return UnixMarshal.PtrToString (r);
937 #endregion // Classes