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.
31 using System.Runtime.InteropServices;
40 public enum Error : int {
41 // errors & their values liberally copied from
42 // FC2 /usr/include/asm/errno.h
44 EPERM = 1, // Operation not permitted
45 ENOENT = 2, // No such file or directory
46 ESRCH = 3, // No such process
47 EINTR = 4, // Interrupted system call
49 ENXIO = 6, // No such device or address
50 E2BIG = 7, // Arg list too long
51 ENOEXEC = 8, // Exec format error
52 EBADF = 9, // Bad file number
53 ECHILD = 10, // No child processes
54 EAGAIN = 11, // Try again
55 ENOMEM = 12, // Out of memory
56 EACCES = 13, // Permission denied
57 EFAULT = 14, // Bad address
58 ENOTBLK = 15, // Block device required
59 EBUSY = 16, // Device or resource busy
60 EEXIST = 17, // File exists
61 EXDEV = 18, // Cross-device link
62 ENODEV = 19, // No such device
63 ENOTDIR = 20, // Not a directory
64 EISDIR = 21, // Is a directory
65 EINVAL = 22, // Invalid argument
66 ENFILE = 23, // File table overflow
67 EMFILE = 24, // Too many open files
68 ENOTTY = 25, // Not a typewriter
69 ETXTBSY = 26, // Text file busy
70 EFBIG = 27, // File too large
71 ENOSPC = 28, // No space left on device
72 ESPIPE = 29, // Illegal seek
73 EROFS = 30, // Read-only file system
74 EMLINK = 31, // Too many links
75 EPIPE = 32, // Broken pipe
76 EDOM = 33, // Math argument out of domain of func
77 ERANGE = 34, // Math result not representable
78 EDEADLK = 35, // Resource deadlock would occur
79 ENAMETOOLONG = 36, // File name too long
80 ENOLCK = 37, // No record locks available
81 ENOSYS = 38, // Function not implemented
82 ENOTEMPTY = 39, // Directory not empty
83 ELOOP = 40, // Too many symbolic links encountered
84 EWOULDBLOCK = EAGAIN, // Operation would block
85 ENOMSG = 42, // No message of desired type
86 EIDRM = 43, // Identifier removed
87 ECHRNG = 44, // Channel number out of range
88 EL2NSYNC = 45, // Level 2 not synchronized
89 EL3HLT = 46, // Level 3 halted
90 EL3RST = 47, // Level 3 reset
91 ELNRNG = 48, // Link number out of range
92 EUNATCH = 49, // Protocol driver not attached
93 ENOCSI = 50, // No CSI structure available
94 EL2HLT = 51, // Level 2 halted
95 EBADE = 52, // Invalid exchange
96 EBADR = 53, // Invalid request descriptor
97 EXFULL = 54, // Exchange full
98 ENOANO = 55, // No anode
99 EBADRQC = 56, // Invalid request code
100 EBADSLT = 57, // Invalid slot
104 EBFONT = 59, // Bad font file format
105 ENOSTR = 60, // Device not a stream
106 ENODATA = 61, // No data available
107 ETIME = 62, // Timer expired
108 ENOSR = 63, // Out of streams resources
109 ENONET = 64, // Machine is not on the network
110 ENOPKG = 65, // Package not installed
111 EREMOTE = 66, // Object is remote
112 ENOLINK = 67, // Link has been severed
113 EADV = 68, // Advertise error
114 ESRMNT = 69, // Srmount error
115 ECOMM = 70, // Communication error on send
116 EPROTO = 71, // Protocol error
117 EMULTIHOP = 72, // Multihop attempted
118 EDOTDOT = 73, // RFS specific error
119 EBADMSG = 74, // Not a data message
120 EOVERFLOW = 75, // Value too large for defined data type
121 ENOTUNIQ = 76, // Name not unique on network
122 EBADFD = 77, // File descriptor in bad state
123 EREMCHG = 78, // Remote address changed
124 ELIBACC = 79, // Can not access a needed shared library
125 ELIBBAD = 80, // Accessing a corrupted shared library
126 ELIBSCN = 81, // .lib section in a.out corrupted
127 ELIBMAX = 82, // Attempting to link in too many shared libraries
128 ELIBEXEC = 83, // Cannot exec a shared library directly
129 EILSEQ = 84, // Illegal byte sequence
130 ERESTART = 85, // Interrupted system call should be restarted
131 ESTRPIPE = 86, // Streams pipe error
132 EUSERS = 87, // Too many users
133 ENOTSOCK = 88, // Socket operation on non-socket
134 EDESTADDRREQ = 89, // Destination address required
135 EMSGSIZE = 90, // Message too long
136 EPROTOTYPE = 91, // Protocol wrong type for socket
137 ENOPROTOOPT = 92, // Protocol not available
138 EPROTONOSUPPORT = 93, // Protocol not supported
139 ESOCKTNOSUPPORT = 94, // Socket type not supported
140 EOPNOTSUPP = 95, // Operation not supported on transport endpoint
141 EPFNOSUPPORT = 96, // Protocol family not supported
142 EAFNOSUPPORT = 97, // Address family not supported by protocol
143 EADDRINUSE = 98, // Address already in use
144 EADDRNOTAVAIL = 99, // Cannot assign requested address
145 ENETDOWN = 100, // Network is down
146 ENETUNREACH = 101, // Network is unreachable
147 ENETRESET = 102, // Network dropped connection because of reset
148 ECONNABORTED = 103, // Software caused connection abort
149 ECONNRESET = 104, // Connection reset by peer
150 ENOBUFS = 105, // No buffer space available
151 EISCONN = 106, // Transport endpoint is already connected
152 ENOTCONN = 107, // Transport endpoint is not connected
153 ESHUTDOWN = 108, // Cannot send after transport endpoint shutdown
154 ETOOMANYREFS = 109, // Too many references: cannot splice
155 ETIMEDOUT = 110, // Connection timed out
156 ECONNREFUSED = 111, // Connection refused
157 EHOSTDOWN = 112, // Host is down
158 EHOSTUNREACH = 113, // No route to host
159 EALREADY = 114, // Operation already in progress
160 EINPROGRESS = 115, // Operation now in progress
161 ESTALE = 116, // Stale NFS file handle
162 EUCLEAN = 117, // Structure needs cleaning
163 ENOTNAM = 118, // Not a XENIX named type file
164 ENAVAIL = 119, // No XENIX semaphores available
165 EISNAM = 120, // Is a named type file
166 EREMOTEIO = 121, // Remote I/O error
167 EDQUOT = 122, // Quota exceeded
169 ENOMEDIUM = 123, // No medium found
170 EMEDIUMTYPE = 124, // Wrong medium type
177 public sealed class FilePosition : IDisposable {
179 private static readonly int FilePositionDumpSize =
180 Stdlib.DumpFilePosition (null, new HandleRef (null, IntPtr.Zero), 0);
182 private HandleRef pos;
184 public FilePosition ()
186 IntPtr p = Stdlib.CreateFilePosition ();
187 if (p == IntPtr.Zero)
188 throw new OutOfMemoryException ("Unable to malloc fpos_t!");
189 pos = new HandleRef (this, p);
192 internal HandleRef Handle {
196 public void Dispose ()
199 GC.SuppressFinalize (this);
202 private void Cleanup ()
204 if (pos.Handle != IntPtr.Zero) {
205 Stdlib.free (pos.Handle);
206 pos = new HandleRef (this, IntPtr.Zero);
210 public override string ToString ()
212 return "(" + base.ToString () + " " + GetDump () + ")";
215 private string GetDump ()
217 if (FilePositionDumpSize <= 0)
218 return "internal error";
220 StringBuilder buf = new StringBuilder (FilePositionDumpSize+1);
222 if (Stdlib.DumpFilePosition (buf, Handle, FilePositionDumpSize+1) <= 0)
223 return "internal error dumping fpos_t";
225 return buf.ToString ();
228 public override bool Equals (object obj)
230 if (obj == null || GetType() != obj.GetType())
232 return ToString().Equals (obj.ToString());
235 public override int GetHashCode ()
237 return ToString ().GetHashCode ();
245 public static bool operator== (FilePosition lhs, FilePosition rhs)
247 return Object.Equals (lhs, rhs);
250 public static bool operator!= (FilePosition lhs, FilePosition rhs)
252 return !Object.Equals (lhs, rhs);
258 // Right now using this attribute gives an assert because it
259 // isn't implemented.
261 #if NET_2_0 && UNMANAGED_FN_PTR_SUPPORT_FIXED
262 [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
264 public delegate void SignalHandler (int signal);
266 internal sealed class SignalWrapper {
267 private IntPtr handler;
269 internal SignalWrapper (IntPtr handler)
271 this.handler = handler;
274 public void InvokeSignalHandler (int signum)
276 Stdlib.InvokeSignalHandler (signum, handler);
280 internal class XPrintfFunctions
282 internal delegate object XPrintf (object[] parameters);
284 internal static XPrintf printf;
285 internal static XPrintf fprintf;
286 internal static XPrintf snprintf;
287 internal static XPrintf syslog;
289 static XPrintfFunctions ()
291 CdeclFunction _printf = new CdeclFunction (Stdlib.LIBC, "printf", typeof(int));
292 printf = new XPrintf (_printf.Invoke);
294 CdeclFunction _fprintf = new CdeclFunction (Stdlib.LIBC, "fprintf", typeof(int));
295 fprintf = new XPrintf (_fprintf.Invoke);
297 CdeclFunction _snprintf = new CdeclFunction (Stdlib.MPH,
298 "Mono_Posix_Stdlib_snprintf", typeof(int));
299 snprintf = new XPrintf (_snprintf.Invoke);
301 CdeclFunction _syslog = new CdeclFunction (Syscall.LIBC, "syslog", typeof(void));
302 syslog = new XPrintf (_syslog.Invoke);
307 // Convention: Functions that are part of the C standard library go here.
309 // For example, the man page should say something similar to:
312 // ISO 9899 (''ANSI C'')
314 // The intent is that members of this class should be portable to any system
315 // supporting the C runtime (read: non-Unix, including Windows). Using
316 // anything from Syscall is non-portable, but restricting yourself to just
317 // Stdlib is intended to be portable.
321 internal const string LIBC = "msvcrt";
322 internal const string MPH = "MonoPosixHelper";
324 internal Stdlib () {}
326 #region <errno.h> Declarations
328 // <errno.h> -- COMPLETE
331 public static Error GetLastError ()
333 int errno = Marshal.GetLastWin32Error ();
334 return UnixConvert.ToError (errno);
337 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
338 EntryPoint="Mono_Posix_Stdlib_SetLastError")]
339 private static extern void SetLastError (int error);
341 public static void SetLastError (Error error)
343 int _error = UnixConvert.FromError (error);
344 SetLastError (_error);
351 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
352 EntryPoint="Mono_Posix_Stdlib_InvokeSignalHandler")]
353 internal static extern void InvokeSignalHandler (int signum, IntPtr handler);
355 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
356 EntryPoint="Mono_Posix_Stdlib_SIG_DFL")]
357 private static extern IntPtr GetDefaultSignal ();
359 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
360 EntryPoint="Mono_Posix_Stdlib_SIG_ERR")]
361 private static extern IntPtr GetErrorSignal ();
363 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
364 EntryPoint="Mono_Posix_Stdlib_SIG_IGN")]
365 private static extern IntPtr GetIgnoreSignal ();
367 private static readonly IntPtr _SIG_DFL = GetDefaultSignal ();
368 private static readonly IntPtr _SIG_ERR = GetErrorSignal ();
369 private static readonly IntPtr _SIG_IGN = GetIgnoreSignal ();
371 private static void _ErrorHandler (int signum)
373 Console.Error.WriteLine ("Error handler invoked for signum " +
374 signum + ". Don't do that.");
377 private static void _DefaultHandler (int signum)
379 Console.Error.WriteLine ("Default handler invoked for signum " +
380 signum + ". Don't do that.");
383 private static void _IgnoreHandler (int signum)
385 Console.Error.WriteLine ("Ignore handler invoked for signum " +
386 signum + ". Don't do that.");
389 public static readonly SignalHandler SIG_DFL = new SignalHandler (_DefaultHandler);
390 public static readonly SignalHandler SIG_ERR = new SignalHandler (_ErrorHandler);
391 public static readonly SignalHandler SIG_IGN = new SignalHandler (_IgnoreHandler);
393 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
394 SetLastError=true, EntryPoint="signal")]
395 private static extern IntPtr sys_signal (int signum, SignalHandler handler);
397 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
398 SetLastError=true, EntryPoint="signal")]
399 private static extern IntPtr sys_signal (int signum, IntPtr handler);
401 public static SignalHandler signal (Signum signum, SignalHandler handler)
403 int _sig = UnixConvert.FromSignum (signum);
405 if (handler == SIG_DFL)
406 r = sys_signal (_sig, _SIG_DFL);
407 else if (handler == SIG_ERR)
408 r = sys_signal (_sig, _SIG_ERR);
409 else if (handler == SIG_IGN)
410 r = sys_signal (_sig, _SIG_IGN);
412 r = sys_signal (_sig, handler);
413 return TranslateHandler (r);
416 private static SignalHandler TranslateHandler (IntPtr handler)
418 if (handler == _SIG_DFL)
420 if (handler == _SIG_ERR)
422 if (handler == _SIG_IGN)
424 return new SignalHandler (new SignalWrapper (handler).InvokeSignalHandler);
427 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, EntryPoint="raise")]
428 private static extern int sys_raise (int sig);
430 public static int raise (Signum sig)
432 int _sig = UnixConvert.FromSignum (sig);
433 return sys_raise (_sig);
437 // <stdio.h> -- COMPLETE except for :
438 // - the scanf(3) family .
439 // - vararg functions.
440 // - Horribly unsafe functions (gets(3)).
442 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
443 EntryPoint="Mono_Posix_Stdlib__IOFBF")]
444 private static extern int GetFullyBuffered ();
446 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
447 EntryPoint="Mono_Posix_Stdlib__IOLBF")]
448 private static extern int GetLineBuffered ();
450 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
451 EntryPoint="Mono_Posix_Stdlib__IONBF")]
452 private static extern int GetNonBuffered ();
454 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
455 EntryPoint="Mono_Posix_Stdlib_BUFSIZ")]
456 private static extern int GetBufferSize ();
458 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
459 EntryPoint="Mono_Posix_Stdlib_CreateFilePosition")]
460 internal static extern IntPtr CreateFilePosition ();
462 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
463 EntryPoint="Mono_Posix_Stdlib_DumpFilePosition")]
464 internal static extern int DumpFilePosition (StringBuilder buf, HandleRef handle, int len);
466 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
467 EntryPoint="Mono_Posix_Stdlib_EOF")]
468 private static extern int GetEOF ();
470 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
471 EntryPoint="Mono_Posix_Stdlib_FILENAME_MAX")]
472 private static extern int GetFilenameMax ();
474 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
475 EntryPoint="Mono_Posix_Stdlib_FOPEN_MAX")]
476 private static extern int GetFopenMax ();
478 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
479 EntryPoint="Mono_Posix_Stdlib_L_tmpnam")]
480 private static extern int GetTmpnamLength ();
482 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
483 EntryPoint="Mono_Posix_Stdlib_stdin")]
484 private static extern IntPtr GetStandardInput ();
486 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
487 EntryPoint="Mono_Posix_Stdlib_stdout")]
488 private static extern IntPtr GetStandardOutput ();
490 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
491 EntryPoint="Mono_Posix_Stdlib_stderr")]
492 private static extern IntPtr GetStandardError ();
494 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
495 EntryPoint="Mono_Posix_Stdlib_TMP_MAX")]
496 private static extern int GetTmpMax ();
498 public static readonly int _IOFBF = GetFullyBuffered ();
499 public static readonly int _IOLBF = GetLineBuffered ();
500 public static readonly int _IONBF = GetNonBuffered ();
501 public static readonly int BUFSIZ = GetBufferSize ();
502 public static readonly int EOF = GetEOF ();
503 public static readonly int FOPEN_MAX = GetFopenMax ();
504 public static readonly int FILENAME_MAX = GetFilenameMax ();
505 public static readonly int L_tmpnam = GetTmpnamLength ();
506 public static readonly IntPtr stderr = GetStandardError ();
507 public static readonly IntPtr stdin = GetStandardInput ();
508 public static readonly IntPtr stdout = GetStandardOutput ();
509 public static readonly int TMP_MAX = GetTmpMax ();
511 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
512 public static extern int remove (string filename);
514 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
515 public static extern int rename (string oldpath, string newpath);
517 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
518 public static extern IntPtr tmpfile ();
520 private static object tmpnam_lock = new object ();
522 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
523 SetLastError=true, EntryPoint="tmpnam")]
524 private static extern IntPtr sys_tmpnam (StringBuilder s);
526 [Obsolete ("Syscall.mkstemp() should be preferred.")]
527 public static string tmpnam (StringBuilder s)
529 if (s != null && s.Capacity < L_tmpnam)
530 throw new ArgumentOutOfRangeException ("s", "s.Capacity < L_tmpnam");
532 IntPtr r = sys_tmpnam (s);
533 return UnixMarshal.PtrToString (r);
537 [Obsolete ("Syscall.mkstemp() should be preferred.")]
538 public static string tmpnam ()
541 IntPtr r = sys_tmpnam (null);
542 return UnixMarshal.PtrToString (r);
546 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
547 public static extern int fclose (IntPtr stream);
549 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
550 public static extern int fflush (IntPtr stream);
552 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
553 public static extern IntPtr fopen (string path, string mode);
555 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
556 public static extern IntPtr freopen (string path, string mode, IntPtr stream);
558 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
559 public static extern void setbuf (IntPtr stream, IntPtr buf);
561 public static unsafe void setbuf (IntPtr stream, byte* buf)
563 setbuf (stream, (IntPtr) buf);
566 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
567 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_setvbuf")]
568 public static extern int setvbuf (IntPtr stream, IntPtr buf, int mode, ulong size);
570 public static unsafe int setvbuf (IntPtr stream, byte* buf, int mode, ulong size)
572 return setvbuf (stream, (IntPtr) buf, mode, size);
575 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
576 EntryPoint="fprintf")]
577 private static extern int sys_fprintf (IntPtr stream, string format, string message);
579 public static int fprintf (IntPtr stream, string message)
581 return sys_fprintf (stream, "%s", message);
584 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
585 "Use fprintf (IntPtr, string) instead.")]
586 public static int fprintf (IntPtr stream, string format, params object[] parameters)
588 object[] _parameters = new object[checked(parameters.Length+2)];
589 _parameters [0] = stream;
590 _parameters [1] = format;
591 Array.Copy (parameters, 0, _parameters, 2, parameters.Length);
592 return (int) XPrintfFunctions.fprintf (_parameters);
595 /* SKIP: fscanf(3) */
597 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
598 EntryPoint="printf")]
599 private static extern int sys_printf (string format, string message);
601 public static int printf (string message)
603 return sys_printf ("%s", message);
606 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
607 "Use printf (string) instead.")]
608 public static int printf (string format, params object[] parameters)
610 object[] _parameters = new object[checked(parameters.Length+1)];
611 _parameters [0] = format;
612 Array.Copy (parameters, 0, _parameters, 1, parameters.Length);
613 return (int) XPrintfFunctions.printf (_parameters);
618 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
619 EntryPoint="Mono_Posix_Stdlib_snprintf")]
620 private static extern int sys_snprintf (StringBuilder s, ulong n,
621 string format, string message);
623 public static int snprintf (StringBuilder s, ulong n, string message)
625 if (n > (ulong) s.Capacity)
626 throw new ArgumentOutOfRangeException ("n", "n must be <= s.Capacity");
627 return sys_snprintf (s, n, "%s", message);
630 public static int snprintf (StringBuilder s, string message)
632 return sys_snprintf (s, (ulong) s.Capacity, "%s", message);
635 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
636 "Use snprintf (StringBuilder, string) instead.")]
637 public static int snprintf (StringBuilder s, ulong n,
638 string format, params object[] parameters)
640 if (n > (ulong) s.Capacity)
641 throw new ArgumentOutOfRangeException ("n", "n must be <= s.Capacity");
643 object[] _parameters = new object[checked(parameters.Length+3)];
646 _parameters [2] = format;
647 Array.Copy (parameters, 0, _parameters, 3, parameters.Length);
648 return (int) XPrintfFunctions.snprintf (_parameters);
651 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
652 "Use snprintf (StringBuilder, string) instead.")]
653 public static int snprintf (StringBuilder s,
654 string format, params object[] parameters)
656 object[] _parameters = new object[checked(parameters.Length+3)];
658 _parameters [1] = (ulong) s.Capacity;
659 _parameters [2] = format;
660 Array.Copy (parameters, 0, _parameters, 3, parameters.Length);
661 return (int) XPrintfFunctions.snprintf (_parameters);
677 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
678 public static extern int fgetc (IntPtr stream);
680 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
681 SetLastError=true, EntryPoint="fgets")]
682 private static extern IntPtr sys_fgets (StringBuilder sb, int size, IntPtr stream);
684 public static StringBuilder fgets (StringBuilder sb, int size, IntPtr stream)
686 IntPtr r = sys_fgets (sb, size, stream);
687 if (r == IntPtr.Zero)
692 public static StringBuilder fgets (StringBuilder sb, IntPtr stream)
694 return fgets (sb, sb.Capacity, stream);
697 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
698 public static extern int fputc (int c, IntPtr stream);
700 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
701 public static extern int fputs (string s, IntPtr stream);
703 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
704 public static extern int getc (IntPtr stream);
706 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
707 public static extern int getchar ();
711 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
712 public static extern int putc (int c, IntPtr stream);
714 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
715 public static extern int putchar (int c);
717 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
718 public static extern int puts (string s);
720 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
721 public static extern int ungetc (int c, IntPtr stream);
723 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
724 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fread")]
725 public static extern ulong fread (IntPtr ptr, ulong size, ulong nmemb, IntPtr stream);
727 public static unsafe ulong fread (void* ptr, ulong size, ulong nmemb, IntPtr stream)
729 return fread ((IntPtr) ptr, size, nmemb, stream);
732 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
733 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fread")]
734 private static extern ulong sys_fread ([Out] byte[] ptr,
735 ulong size, ulong nmemb, IntPtr stream);
737 public static ulong fread (byte[] ptr, ulong size, ulong nmemb, IntPtr stream)
739 if ((size * nmemb) > (ulong) ptr.Length)
740 throw new ArgumentOutOfRangeException ("nmemb");
741 return sys_fread (ptr, size, nmemb, stream);
744 public static ulong fread (byte[] ptr, IntPtr stream)
746 return fread (ptr, 1, (ulong) ptr.Length, stream);
749 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
750 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fwrite")]
751 public static extern ulong fwrite (IntPtr ptr, ulong size, ulong nmemb, IntPtr stream);
753 public static unsafe ulong fwrite (void* ptr, ulong size, ulong nmemb, IntPtr stream)
755 return fwrite ((IntPtr) ptr, size, nmemb, stream);
758 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
759 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fwrite")]
760 private static extern ulong sys_fwrite (byte[] ptr,
761 ulong size, ulong nmemb, IntPtr stream);
763 public static ulong fwrite (byte[] ptr, ulong size, ulong nmemb, IntPtr stream)
765 if ((size * nmemb) > (ulong) ptr.Length)
766 throw new ArgumentOutOfRangeException ("nmemb");
767 return sys_fwrite (ptr, size, nmemb, stream);
770 public static ulong fwrite (byte[] ptr, IntPtr stream)
772 return fwrite (ptr, 1, (ulong) ptr.Length, stream);
775 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
776 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fgetpos")]
777 private static extern int sys_fgetpos (IntPtr stream, HandleRef pos);
779 public static int fgetpos (IntPtr stream, FilePosition pos)
781 return sys_fgetpos (stream, pos.Handle);
784 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
785 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fseek")]
786 private static extern int sys_fseek (IntPtr stream, long offset, int origin);
788 public static int fseek (IntPtr stream, long offset, SeekFlags origin)
790 int _origin = UnixConvert.FromSeekFlags (origin);
791 return sys_fseek (stream, offset, _origin);
794 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
795 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fsetpos")]
796 private static extern int sys_fsetpos (IntPtr stream, HandleRef pos);
798 public static int fsetpos (IntPtr stream, FilePosition pos)
800 return sys_fsetpos (stream, pos.Handle);
803 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
804 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_ftell")]
805 public static extern long ftell (IntPtr stream);
807 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
808 public static extern void rewind (IntPtr stream);
810 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
811 public static extern void clearerr (IntPtr stream);
813 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
814 public static extern int feof (IntPtr stream);
816 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
817 public static extern int ferror (IntPtr stream);
819 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
820 public static extern void perror (string s);
825 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
826 EntryPoint="Mono_Posix_Stdlib_EXIT_FAILURE")]
827 private static extern int GetExitFailure();
829 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
830 EntryPoint="Mono_Posix_Stdlib_EXIT_SUCCESS")]
831 private static extern int GetExitSuccess ();
833 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
834 EntryPoint="Mono_Posix_Stdlib_MB_CUR_MAX")]
835 private static extern int GetMbCurMax ();
837 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
838 EntryPoint="Mono_Posix_Stdlib_RAND_MAX")]
839 private static extern int GetRandMax ();
841 public static readonly int EXIT_FAILURE = GetExitFailure ();
842 public static readonly int EXIT_SUCCESS = GetExitSuccess ();
843 public static readonly int MB_CUR_MAX = GetMbCurMax ();
844 public static readonly int RAND_MAX = GetRandMax ();
846 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
847 public static extern int rand ();
849 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
850 public static extern void srand (uint seed);
853 // void *calloc (size_t nmemb, size_t size);
854 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
855 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_calloc")]
856 public static extern IntPtr calloc (ulong nmemb, ulong size);
858 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
859 public static extern void free (IntPtr ptr);
862 // void *malloc(size_t size);
863 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
864 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_malloc")]
865 public static extern IntPtr malloc (ulong size);
868 // void *realloc(void *ptr, size_t size);
869 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
870 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_realloc")]
871 public static extern IntPtr realloc (IntPtr ptr, ulong size);
873 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
874 public static extern void abort ();
876 /* SKIP: atexit(3) -- the GC should have collected most references by the
877 * time this runs, so no delegates should exist, making it pointless. */
879 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
880 public static extern void exit (int status);
882 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
883 public static extern void _Exit (int status);
885 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, EntryPoint="getenv")]
886 private static extern IntPtr sys_getenv (string name);
888 public static string getenv (string name)
890 IntPtr r = sys_getenv (name);
891 return UnixMarshal.PtrToString (r);
894 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
895 public static extern int system (string @string);
901 private static object strerror_lock = new object ();
903 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
904 SetLastError=true, EntryPoint="strerror")]
905 private static extern IntPtr sys_strerror (int errnum);
907 public static string strerror (Error errnum)
909 int e = UnixConvert.FromError (errnum);
910 lock (strerror_lock) {
911 IntPtr r = sys_strerror (e);
912 return UnixMarshal.PtrToString (r);
917 #endregion // Classes