Merge pull request #4928 from kumpera/ptr_to_struct_intrinsic
[mono.git] / mcs / class / Mono.Posix / Mono.Unix.Native / Stdlib.cs
1 //
2 // Mono.Unix/Stdlib.cs
3 //
4 // Authors:
5 //   Jonathan Pryor (jonpryor@vt.edu)
6 //
7 // (C) 2004-2006 Jonathan Pryor
8 //
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:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
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.
27 //
28
29 using System;
30 using System.Collections;
31 using System.IO;
32 using System.Runtime.InteropServices;
33 using System.Text;
34 using Mono.Unix.Native;
35
36 namespace Mono.Unix.Native {
37
38         #region Enumerations
39
40         [Map]
41         public enum Errno : int {
42                 // errors & their values liberally copied from
43                 // FC2 /usr/include/asm/errno.h
44                 
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 
49                 EIO             =   5, // I/O error 
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 
102                       
103                 EDEADLOCK             =  EDEADLK,
104                       
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 
169
170                 ENOMEDIUM       = 123, // No medium found 
171                 EMEDIUMTYPE     = 124, // Wrong medium type 
172
173                 ECANCELED       = 125,
174                 ENOKEY          = 126,
175                 EKEYEXPIRED     = 127,
176                 EKEYREVOKED     = 128,
177                 EKEYREJECTED    = 129,
178
179                 EOWNERDEAD      = 130,
180                 ENOTRECOVERABLE = 131,
181
182                 // OS X-specific values: OS X value + 1000
183                 EPROCLIM        = 1067, // Too many processes
184                 EBADRPC         = 1072, // RPC struct is bad
185                 ERPCMISMATCH    = 1073, // RPC version wrong
186                 EPROGUNAVAIL    = 1074, // RPC prog. not avail
187                 EPROGMISMATCH   = 1075, // Program version wrong
188                 EPROCUNAVAIL    = 1076, // Bad procedure for program
189                 EFTYPE          = 1079, // Inappropriate file type or format
190                 EAUTH           = 1080, // Authentication error
191                 ENEEDAUTH       = 1081, // Need authenticator
192                 EPWROFF         = 1082, // Device power is off
193                 EDEVERR         = 1083, // Device error, e.g. paper out
194                 EBADEXEC        = 1085, // Bad executable
195                 EBADARCH        = 1086, // Bad CPU type in executable
196                 ESHLIBVERS      = 1087, // Shared library version mismatch
197                 EBADMACHO       = 1088, // Malformed Macho file
198                 ENOATTR         = 1093, // Attribute not found
199                 ENOPOLICY       = 1103, // No such policy registered
200         }
201
202         #endregion
203
204         #region Classes
205
206         public sealed class FilePosition : MarshalByRefObject, IDisposable 
207                 , IEquatable <FilePosition>
208         {
209
210                 private static readonly int FilePositionDumpSize = 
211                         Stdlib.DumpFilePosition (null, new HandleRef (null, IntPtr.Zero), 0);
212
213                 private HandleRef pos;
214
215                 public FilePosition ()
216                 {
217                         IntPtr p = Stdlib.CreateFilePosition ();
218                         if (p == IntPtr.Zero)
219                                 throw new OutOfMemoryException ("Unable to malloc fpos_t!");
220                         pos = new HandleRef (this, p);
221                 }
222
223                 internal HandleRef Handle {
224                         get {return pos;}
225                 }
226
227                 public void Dispose ()
228                 {
229                         Cleanup ();
230                         GC.SuppressFinalize (this);
231                 }
232
233                 private void Cleanup ()
234                 {
235                         if (pos.Handle != IntPtr.Zero) {
236                                 Stdlib.free (pos.Handle);
237                                 pos = new HandleRef (this, IntPtr.Zero);
238                         }
239                 }
240
241                 public override string ToString ()
242                 {
243                         return "(" + base.ToString () + " " + GetDump () + ")";
244                 }
245
246                 private string GetDump ()
247                 {
248                         if (FilePositionDumpSize <= 0)
249                                 return "internal error";
250
251                         StringBuilder buf = new StringBuilder (FilePositionDumpSize+1);
252
253                         if (Stdlib.DumpFilePosition (buf, Handle, FilePositionDumpSize+1) <= 0)
254                                 return "internal error dumping fpos_t";
255
256                         return buf.ToString ();
257                 }
258
259                 public override bool Equals (object obj)
260                 {
261                         FilePosition fp = obj as FilePosition;
262                         if (obj == null || fp == null)
263                                 return false;
264                         return ToString().Equals (obj.ToString());
265                 }
266
267                 public bool Equals (FilePosition value)
268                 {
269                         if (object.ReferenceEquals (this, value))
270                                 return true;
271                         return ToString().Equals (value.ToString());
272                 }
273
274                 public override int GetHashCode ()
275                 {
276                         return ToString ().GetHashCode ();
277                 }
278
279                 ~FilePosition ()
280                 {
281                         Cleanup ();
282                 }
283
284                 public static bool operator== (FilePosition lhs, FilePosition rhs)
285                 {
286                         return Object.Equals (lhs, rhs);
287                 }
288
289                 public static bool operator!= (FilePosition lhs, FilePosition rhs)
290                 {
291                         return !Object.Equals (lhs, rhs);
292                 }
293         }
294
295
296         public enum SignalAction {
297                 Default,
298                 Ignore,
299                 Error
300         }
301
302         //
303         // Right now using this attribute gives an assert because it
304         // isn't implemented.
305         //
306 #if UNMANAGED_FN_PTR_SUPPORT_FIXED
307         [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
308 #endif
309         public delegate void SignalHandler (int signal);
310
311
312 #if !NETSTANDARD2_0
313         internal class XPrintfFunctions
314         {
315                 internal delegate object XPrintf (object[] parameters);
316
317                 internal static XPrintf printf;
318                 internal static XPrintf fprintf;
319                 internal static XPrintf snprintf;
320                 internal static XPrintf syslog;
321
322                 static XPrintfFunctions ()
323                 {
324                         CdeclFunction _printf = new CdeclFunction (Stdlib.LIBC, "printf", typeof(int));
325                         printf = new XPrintf (_printf.Invoke);
326
327                         CdeclFunction _fprintf = new CdeclFunction (Stdlib.LIBC, "fprintf", typeof(int));
328                         fprintf = new XPrintf (_fprintf.Invoke);
329
330                         CdeclFunction _snprintf = new CdeclFunction (Stdlib.MPH, 
331                                         "Mono_Posix_Stdlib_snprintf", typeof(int));
332                         snprintf = new XPrintf (_snprintf.Invoke);
333
334                         CdeclFunction _syslog = new CdeclFunction (Syscall.MPH, 
335                                         "Mono_Posix_Stdlib_syslog2", typeof(int));
336                         syslog = new XPrintf (_syslog.Invoke);
337                 }
338         }
339 #endif
340
341         //
342         // Convention: Functions that are part of the C standard library go here.
343         //
344         // For example, the man page should say something similar to:
345         //
346         //    CONFORMING TO
347         //           ISO 9899 (''ANSI C'')
348         //
349         // The intent is that members of this class should be portable to any system
350         // supporting the C runtime (read: non-Unix, including Windows).  Using
351         // anything from Syscall is non-portable, but restricting yourself to just
352         // Stdlib is intended to be portable.
353         //
354         // The only methods in here should be:
355         //  (1) low-level functions (as defined above).
356         //  (2) "Trivial" function overloads.  For example, if the parameters to a
357         //      function are related (e.g. fwrite(3))
358         //  (3) The return type SHOULD NOT be changed.  If you want to provide a
359         //      convenience function with a nicer return type, place it into one of
360         //      the Mono.Unix.Std* wrapper classes, and give it a .NET-styled name.
361         //      - EXCEPTION: No public functions should have a `void' return type.
362         //        `void' return types should be replaced with `int'.
363         //        Rationality: `void'-return functions typically require a
364         //        complicated call sequence, such as clear errno, then call, then
365         //        check errno to see if any errors occurred.  This sequence can't 
366         //        be done safely in managed code, as errno may change as part of 
367         //        the P/Invoke mechanism.
368         //        Instead, add a MonoPosixHelper export which does:
369         //          errno = 0;
370         //          INVOKE SYSCALL;
371         //          return errno == 0 ? 0 : -1;
372         //        This lets managed code check the return value in the usual manner.
373         //  (4) Exceptions SHOULD NOT be thrown.  EXCEPTIONS: 
374         //      - If you're wrapping *broken* methods which make assumptions about 
375         //        input data, such as that an argument refers to N bytes of data.  
376         //        This is currently limited to cuserid(3) and encrypt(3).
377         //      - If you call functions which themselves generate exceptions.  
378         //        This is the case for using NativeConvert, which will throw an
379         //        exception if an invalid/unsupported value is used.
380         //
381         public class Stdlib
382         {
383 #if FORCE_USE_LIBC_NOT_MSVC
384                 internal const string LIBC = "c";
385 #else
386                 internal const string LIBC = "msvcrt";
387 #endif
388                 internal const string MPH  = "MonoPosixHelper";
389
390                 // It is possible for Mono.Posix and MonoPosixHelper to get out of sync,
391                 // for example if NuGet does something weird. To mitigate this, anyone
392                 // editing Mono.Posix needs to observe two rules:
393                 //   1. When introducing C-interface changes to MonoPosixHelper, update
394                 //      the version strings in VersionCheck below and also
395                 //      Mono_Unix_VersionString in the C sources.
396                 //   2. Any class which performs a DllImport on Stdlib.MPH needs to call
397                 //      Stdlib.VersionCheck in its static constructor.
398
399                 [DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl,
400                                 EntryPoint="Mono_Unix_VersionString")]
401                 private static extern IntPtr VersionStringPtr ();
402                 private static bool versionCheckPerformed = false;
403                 internal static void VersionCheck ()
404                 {
405                         if (versionCheckPerformed)
406                                 return;
407
408                         // This string is arbitrary; it matters only that it is unique.
409                         string assemblyVersion = "MonoProject-2015-12-1";
410                         string nativeVersion = Marshal.PtrToStringAnsi (VersionStringPtr ());
411                         if (assemblyVersion != nativeVersion)
412                         {
413                                 throw new Exception ("Mono.Posix assembly loaded with a different version (\""
414                                         + assemblyVersion + "\") than MonoPosixHelper (\"" + nativeVersion
415                                     + "\"). You may need to reinstall Mono.Posix.");
416                         }
417
418                         versionCheckPerformed = true;
419                 }
420
421                 static Stdlib ()
422                 {
423                         VersionCheck ();
424                 }
425
426                 internal Stdlib () {}
427
428                 #region <errno.h> Declarations
429                 //
430                 // <errno.h>  -- COMPLETE
431                 //
432
433                 public static Errno GetLastError ()
434                 {
435                         // Always call Marshal.GetLastWin32Error() before the OS check,
436                         // even on Windows where we don't use the return value. If we do
437                         // the OS check first Environment.OSVersion (if it happens to be
438                         // the first ever access) will clobber Marshal.GetLastWin32Error()
439                         // and we won't get the desired errno value on non-Windows platforms.
440                         int errno = Marshal.GetLastWin32Error ();
441                         if (Environment.OSVersion.Platform != PlatformID.Unix) {
442                                 // On Windows Marshal.GetLastWin32Error() doesn't take errno
443                                 // into account so we need to call Mono_Posix_Stdlib_GetLastError()
444                                 // which returns the value of errno in the C runtime
445                                 // libMonoPosixHelper.dll was linked against.
446                                 errno = _GetLastError ();
447                         }
448                         return NativeConvert.ToErrno (errno);
449                 }
450
451                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
452                                 EntryPoint="Mono_Posix_Stdlib_GetLastError")]
453                 private static extern int _GetLastError ();
454
455                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
456                                 EntryPoint="Mono_Posix_Stdlib_SetLastError")]
457                 private static extern void SetLastError (int error);
458
459                 protected static void SetLastError (Errno error)
460                 {
461                         int _error = NativeConvert.FromErrno (error);
462                         SetLastError (_error);
463                 }
464
465                 #endregion
466
467                 //
468                 // <signal.h>
469                 //
470                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
471                                 EntryPoint="Mono_Posix_Stdlib_InvokeSignalHandler")]
472                 internal static extern void InvokeSignalHandler (int signum, IntPtr handler);
473
474                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
475                                 EntryPoint="Mono_Posix_Stdlib_SIG_DFL")]
476                 private static extern IntPtr GetDefaultSignal ();
477
478                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
479                                 EntryPoint="Mono_Posix_Stdlib_SIG_ERR")]
480                 private static extern IntPtr GetErrorSignal ();
481
482                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
483                                 EntryPoint="Mono_Posix_Stdlib_SIG_IGN")]
484                 private static extern IntPtr GetIgnoreSignal ();
485
486                 private static readonly IntPtr _SIG_DFL = GetDefaultSignal ();
487                 private static readonly IntPtr _SIG_ERR = GetErrorSignal ();
488                 private static readonly IntPtr _SIG_IGN = GetIgnoreSignal ();
489
490                 private static void _ErrorHandler (int signum)
491                 {
492                         Console.Error.WriteLine ("Error handler invoked for signum " + 
493                                         signum + ".  Don't do that.");
494                 }
495
496                 private static void _DefaultHandler (int signum)
497                 {
498                         Console.Error.WriteLine ("Default handler invoked for signum " + 
499                                         signum + ".  Don't do that.");
500                 }
501
502                 private static void _IgnoreHandler (int signum)
503                 {
504                         Console.Error.WriteLine ("Ignore handler invoked for signum " + 
505                                         signum + ".  Don't do that.");
506                 }
507
508                 [CLSCompliant (false)]
509                 public static readonly SignalHandler SIG_DFL = new SignalHandler (_DefaultHandler);
510                 [CLSCompliant (false)]
511                 public static readonly SignalHandler SIG_ERR = new SignalHandler (_ErrorHandler);
512                 [CLSCompliant (false)]
513                 public static readonly SignalHandler SIG_IGN = new SignalHandler (_IgnoreHandler);
514
515                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
516                                 SetLastError=true, EntryPoint="signal")]
517                 private static extern IntPtr sys_signal (int signum, SignalHandler handler);
518
519                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
520                                 SetLastError=true, EntryPoint="signal")]
521                 private static extern IntPtr sys_signal (int signum, IntPtr handler);
522
523                 [CLSCompliant (false)]
524                 [Obsolete ("This is not safe; " + 
525                                 "use Mono.Unix.UnixSignal for signal delivery or SetSignalAction()")]
526                 public static SignalHandler signal (Signum signum, SignalHandler handler)
527                 {
528                         int _sig = NativeConvert.FromSignum (signum);
529
530                         Delegate[] handlers = handler.GetInvocationList ();
531                         for (int i = 0; i < handlers.Length; ++i) {
532                                 Marshal.Prelink (handlers [i].Method);
533                         }
534
535                         IntPtr r;
536                         if (handler == SIG_DFL)
537                                 r = sys_signal (_sig, _SIG_DFL);
538                         else if (handler == SIG_ERR)
539                                 r = sys_signal (_sig, _SIG_ERR);
540                         else if (handler == SIG_IGN)
541                                 r = sys_signal (_sig, _SIG_IGN);
542                         else
543                                 r = sys_signal (_sig, handler);
544                         return TranslateHandler (r);
545                 }
546
547                 private static SignalHandler TranslateHandler (IntPtr handler)
548                 {
549                         if (handler == _SIG_DFL)
550                                 return SIG_DFL;
551                         if (handler == _SIG_ERR)
552                                 return SIG_ERR;
553                         if (handler == _SIG_IGN)
554                                 return SIG_IGN;
555                         return (SignalHandler) Marshal.GetDelegateForFunctionPointer (handler, typeof(SignalHandler));
556                 }
557
558                 public static int SetSignalAction (Signum signal, SignalAction action)
559                 {
560                         return SetSignalAction (NativeConvert.FromSignum (signal), action);
561                 }
562
563                 public static int SetSignalAction (RealTimeSignum rts, SignalAction action)
564                 {
565                         return SetSignalAction (NativeConvert.FromRealTimeSignum (rts), action);
566                 }
567                 
568                 private static int SetSignalAction (int signum, SignalAction action)
569                 {
570                         IntPtr handler = IntPtr.Zero;
571                         switch (action) {
572                                 case SignalAction.Default:
573                                         handler = _SIG_DFL;
574                                         break;
575                                 case SignalAction.Ignore:
576                                         handler = _SIG_IGN;
577                                         break;
578                                 case SignalAction.Error:
579                                         handler = _SIG_ERR;
580                                         break;
581                                 default:
582                                         throw new ArgumentException ("Invalid action value.", "action");
583                         }
584                         IntPtr r = sys_signal (signum, handler);
585                         if (r == _SIG_ERR)
586                                 return -1;
587                         return 0;
588                 }
589
590                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, EntryPoint="raise")]
591                 private static extern int sys_raise (int sig);
592
593                 [CLSCompliant (false)]
594                 public static int raise (Signum sig)
595                 {
596                         return sys_raise (NativeConvert.FromSignum (sig));
597                 }
598
599                 public static int raise (RealTimeSignum rts)
600                 {
601                         return sys_raise (NativeConvert.FromRealTimeSignum (rts));
602                 }
603
604                 //
605                 // <stdio.h> -- COMPLETE except for :
606                 //    - the scanf(3) family .
607                 //    - vararg functions.
608                 //    - Horribly unsafe functions (gets(3)).
609                 //
610                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
611                                 EntryPoint="Mono_Posix_Stdlib__IOFBF")]
612                 private static extern int GetFullyBuffered ();
613
614                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
615                                 EntryPoint="Mono_Posix_Stdlib__IOLBF")]
616                 private static extern int GetLineBuffered ();
617
618                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
619                                 EntryPoint="Mono_Posix_Stdlib__IONBF")]
620                 private static extern int GetNonBuffered ();
621
622                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
623                                 EntryPoint="Mono_Posix_Stdlib_BUFSIZ")]
624                 private static extern int GetBufferSize ();
625
626                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
627                                 EntryPoint="Mono_Posix_Stdlib_CreateFilePosition")]
628                 internal static extern IntPtr CreateFilePosition ();
629
630                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
631                                 EntryPoint="Mono_Posix_Stdlib_DumpFilePosition")]
632                 internal static extern int DumpFilePosition (StringBuilder buf, HandleRef handle, int len);
633
634                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
635                                 EntryPoint="Mono_Posix_Stdlib_EOF")]
636                 private static extern int GetEOF ();
637
638                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
639                                 EntryPoint="Mono_Posix_Stdlib_FILENAME_MAX")]
640                 private static extern int GetFilenameMax ();
641
642                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
643                                 EntryPoint="Mono_Posix_Stdlib_FOPEN_MAX")]
644                 private static extern int GetFopenMax ();
645
646                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
647                                 EntryPoint="Mono_Posix_Stdlib_L_tmpnam")]
648                 private static extern int GetTmpnamLength ();
649
650                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
651                                 EntryPoint="Mono_Posix_Stdlib_stdin")]
652                 private static extern IntPtr GetStandardInput ();
653
654                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
655                                 EntryPoint="Mono_Posix_Stdlib_stdout")]
656                 private static extern IntPtr GetStandardOutput ();
657
658                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
659                                 EntryPoint="Mono_Posix_Stdlib_stderr")]
660                 private static extern IntPtr GetStandardError ();
661
662                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
663                                 EntryPoint="Mono_Posix_Stdlib_TMP_MAX")]
664                 private static extern int GetTmpMax ();
665
666                 [CLSCompliant (false)]
667                 public static readonly int    _IOFBF       = GetFullyBuffered ();
668                 [CLSCompliant (false)]
669                 public static readonly int    _IOLBF       = GetLineBuffered ();
670                 [CLSCompliant (false)]
671                 public static readonly int    _IONBF       = GetNonBuffered ();
672                 [CLSCompliant (false)]
673                 public static readonly int    BUFSIZ       = GetBufferSize ();
674                 [CLSCompliant (false)]
675                 public static readonly int    EOF          = GetEOF ();
676                 [CLSCompliant (false)]
677                 public static readonly int    FOPEN_MAX    = GetFopenMax ();
678                 [CLSCompliant (false)]
679                 public static readonly int    FILENAME_MAX = GetFilenameMax ();
680                 [CLSCompliant (false)]
681                 public static readonly int    L_tmpnam     = GetTmpnamLength ();
682                 public static readonly IntPtr stderr       = GetStandardError ();
683                 public static readonly IntPtr stdin        = GetStandardInput ();
684                 public static readonly IntPtr stdout       = GetStandardOutput ();
685                 [CLSCompliant (false)]
686                 public static readonly int    TMP_MAX      = GetTmpMax ();
687
688                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
689                 public static extern int remove (
690                                 [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
691                                 string filename);
692
693                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
694                 public static extern int rename (
695                                 [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
696                                 string oldpath, 
697                                 [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
698                                 string newpath);
699
700                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
701                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_tmpfile")]
702                 public static extern IntPtr tmpfile ();
703
704                 private static object tmpnam_lock = new object ();
705
706                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
707                                 SetLastError=true, EntryPoint="tmpnam")]
708                 private static extern IntPtr sys_tmpnam (StringBuilder s);
709
710                 [Obsolete ("Syscall.mkstemp() should be preferred.")]
711                 public static string tmpnam (StringBuilder s)
712                 {
713                         if (s != null && s.Capacity < L_tmpnam)
714                                 throw new ArgumentOutOfRangeException ("s", "s.Capacity < L_tmpnam");
715                         lock (tmpnam_lock) {
716                                 IntPtr r = sys_tmpnam (s);
717                                 return UnixMarshal.PtrToString (r);
718                         }
719                 }
720
721                 [Obsolete ("Syscall.mkstemp() should be preferred.")]
722                 public static string tmpnam ()
723                 {
724                         lock (tmpnam_lock) {
725                                 IntPtr r = sys_tmpnam (null);
726                                 return UnixMarshal.PtrToString (r);
727                         }
728                 }
729
730                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
731                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fclose")]
732                 public static extern int fclose (IntPtr stream);
733
734                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
735                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fflush")]
736                 public static extern int fflush (IntPtr stream);
737
738                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
739                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fopen")]
740                 public static extern IntPtr fopen (
741                                 [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
742                                 string path, string mode);
743
744                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
745                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_freopen")]
746                 public static extern IntPtr freopen (
747                                 [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
748                                 string path, string mode, IntPtr stream);
749
750                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, 
751                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_setbuf")]
752                 public static extern int setbuf (IntPtr stream, IntPtr buf);
753
754                 [CLSCompliant (false)]
755                 public static unsafe int setbuf (IntPtr stream, byte* buf)
756                 {
757                         return setbuf (stream, (IntPtr) buf);
758                 }
759
760                 [CLSCompliant (false)]
761                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
762                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_setvbuf")]
763                 public static extern int setvbuf (IntPtr stream, IntPtr buf, int mode, ulong size);
764
765                 [CLSCompliant (false)]
766                 public static unsafe int setvbuf (IntPtr stream, byte* buf, int mode, ulong size)
767                 {
768                         return setvbuf (stream, (IntPtr) buf, mode, size);
769                 }
770
771                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
772                                 EntryPoint="Mono_Posix_Stdlib_fprintf")]
773                 private static extern int sys_fprintf (IntPtr stream, string format, string message);
774
775                 public static int fprintf (IntPtr stream, string message)
776                 {
777                         return sys_fprintf (stream, "%s", message);
778                 }
779
780 #if !NETSTANDARD2_0
781                 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
782                                 "Use fprintf (IntPtr, string) instead.")]
783                 public static int fprintf (IntPtr stream, string format, params object[] parameters)
784                 {
785                         object[] _parameters = new object[checked(parameters.Length+2)];
786                         _parameters [0] = stream;
787                         _parameters [1] = format;
788                         Array.Copy (parameters, 0, _parameters, 2, parameters.Length);
789                         return (int) XPrintfFunctions.fprintf (_parameters);
790                 }
791 #endif
792
793                 /* SKIP: fscanf(3) */
794
795                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
796                                 EntryPoint="printf")]
797                 private static extern int sys_printf (string format, string message);
798
799                 public static int printf (string message)
800                 {
801                         return sys_printf ("%s", message);
802                 }
803
804 #if !NETSTANDARD2_0
805                 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
806                                 "Use printf (string) instead.")]
807                 public static int printf (string format, params object[] parameters)
808                 {
809                         object[] _parameters = new object[checked(parameters.Length+1)];
810                         _parameters [0] = format;
811                         Array.Copy (parameters, 0, _parameters, 1, parameters.Length);
812                         return (int) XPrintfFunctions.printf (_parameters);
813                 }
814 #endif
815
816                 /* SKIP: scanf(3) */
817
818                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
819                                 EntryPoint="Mono_Posix_Stdlib_snprintf")]
820                 private static extern int sys_snprintf (StringBuilder s, ulong n, 
821                                 string format, string message);
822
823                 [CLSCompliant (false)]
824                 public static int snprintf (StringBuilder s, ulong n, string message)
825                 {
826                         if (n > (ulong) s.Capacity)
827                                 throw new ArgumentOutOfRangeException ("n", "n must be <= s.Capacity");
828                         return sys_snprintf (s, n, "%s", message);
829                 }
830
831                 public static int snprintf (StringBuilder s, string message)
832                 {
833                         return sys_snprintf (s, (ulong) s.Capacity, "%s", message);
834                 }
835
836 #if !NETSTANDARD2_0
837                 [CLSCompliant (false)]
838                 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
839                                 "Use snprintf (StringBuilder, string) instead.")]
840                 public static int snprintf (StringBuilder s, ulong n, 
841                                 string format, params object[] parameters)
842                 {
843                         if (n > (ulong) s.Capacity)
844                                 throw new ArgumentOutOfRangeException ("n", "n must be <= s.Capacity");
845
846                         object[] _parameters = new object[checked(parameters.Length+3)];
847                         _parameters [0] = s;
848                         _parameters [1] = n;
849                         _parameters [2] = format;
850                         Array.Copy (parameters, 0, _parameters, 3, parameters.Length);
851                         return (int) XPrintfFunctions.snprintf (_parameters);
852                 }
853
854                 [CLSCompliant (false)]
855                 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
856                                 "Use snprintf (StringBuilder, string) instead.")]
857                 public static int snprintf (StringBuilder s,
858                                 string format, params object[] parameters)
859                 {
860                         object[] _parameters = new object[checked(parameters.Length+3)];
861                         _parameters [0] = s;
862                         _parameters [1] = (ulong) s.Capacity;
863                         _parameters [2] = format;
864                         Array.Copy (parameters, 0, _parameters, 3, parameters.Length);
865                         return (int) XPrintfFunctions.snprintf (_parameters);
866                 }
867 #endif
868
869                 /*
870                  * SKIP:
871                  *    sprintf(3)
872                  *    sscanf(3)
873                  *    vfprintf(3)
874                  *    vfscanf(3)
875                  *    vprintf(3)
876                  *    vscanf(3)
877                  *    vsnprintf(3)
878                  *    vsprint(3)
879                  *    vsscanf(3)
880                  */
881
882                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
883                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fgetc")]
884                 public static extern int fgetc (IntPtr stream);
885
886                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
887                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fgets")]
888                 private static extern IntPtr sys_fgets (StringBuilder sb, int size, IntPtr stream);
889
890                 public static StringBuilder fgets (StringBuilder sb, int size, IntPtr stream)
891                 {
892                         IntPtr r = sys_fgets (sb, size, stream);
893                         if (r == IntPtr.Zero)
894                                 return null;
895                         return sb;
896                 }
897
898                 public static StringBuilder fgets (StringBuilder sb, IntPtr stream)
899                 {
900                         return fgets (sb, sb.Capacity, stream);
901                 }
902
903                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
904                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fputc")]
905                 public static extern int fputc (int c, IntPtr stream);
906
907                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
908                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fputs")]
909                 public static extern int fputs (string s, IntPtr stream);
910
911                 public static int getc (IntPtr stream)
912                 {
913                         return fgetc (stream);
914                 }
915
916                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
917                 public static extern int getchar ();
918
919                 /* SKIP: gets(3) */
920
921                 public static int putc (int c, IntPtr stream)
922                 {
923                         return fputc (c, stream);
924                 }
925
926                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
927                 public static extern int putchar (int c);
928
929                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
930                 public static extern int puts (string s);
931
932                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
933                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_ungetc")]
934                 public static extern int ungetc (int c, IntPtr stream);
935
936                 [CLSCompliant (false)]
937                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
938                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fread")]
939                 public static extern ulong fread (IntPtr ptr, ulong size, ulong nmemb, IntPtr stream);
940
941                 [CLSCompliant (false)]
942                 public static unsafe ulong fread (void* ptr, ulong size, ulong nmemb, IntPtr stream)
943                 {
944                         return fread ((IntPtr) ptr, size, nmemb, stream);
945                 }
946
947                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
948                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fread")]
949                 private static extern ulong sys_fread ([Out] byte[] ptr, 
950                                 ulong size, ulong nmemb, IntPtr stream);
951
952                 [CLSCompliant (false)]
953                 public static ulong fread (byte[] ptr, ulong size, ulong nmemb, IntPtr stream)
954                 {
955                         if ((size * nmemb) > (ulong) ptr.Length)
956                                 throw new ArgumentOutOfRangeException ("nmemb");
957                         return sys_fread (ptr, size, nmemb, stream);
958                 }
959
960                 [CLSCompliant (false)]
961                 public static ulong fread (byte[] ptr, IntPtr stream)
962                 {
963                         return fread (ptr, 1, (ulong) ptr.Length, stream);
964                 }
965
966                 [CLSCompliant (false)]
967                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
968                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fwrite")]
969                 public static extern ulong fwrite (IntPtr ptr, ulong size, ulong nmemb, IntPtr stream);
970
971                 [CLSCompliant (false)]
972                 public static unsafe ulong fwrite (void* ptr, ulong size, ulong nmemb, IntPtr stream)
973                 {
974                         return fwrite ((IntPtr) ptr, size, nmemb, stream);
975                 }
976
977                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
978                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fwrite")]
979                 private static extern ulong sys_fwrite (byte[] ptr, 
980                                 ulong size, ulong nmemb, IntPtr stream);
981
982                 [CLSCompliant (false)]
983                 public static ulong fwrite (byte[] ptr, ulong size, ulong nmemb, IntPtr stream)
984                 {
985                         if ((size * nmemb) > (ulong) ptr.Length)
986                                 throw new ArgumentOutOfRangeException ("nmemb");
987                         return sys_fwrite (ptr, size, nmemb, stream);
988                 }
989
990                 [CLSCompliant (false)]
991                 public static ulong fwrite (byte[] ptr, IntPtr stream)
992                 {
993                         return fwrite (ptr, 1, (ulong) ptr.Length, stream);
994                 }
995
996                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
997                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fgetpos")]
998                 private static extern int sys_fgetpos (IntPtr stream, HandleRef pos);
999
1000                 public static int fgetpos (IntPtr stream, FilePosition pos)
1001                 {
1002                         return sys_fgetpos (stream, pos.Handle);
1003                 }
1004
1005                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1006                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fseek")]
1007                 private static extern int sys_fseek (IntPtr stream, long offset, int origin);
1008
1009                 [CLSCompliant (false)]
1010                 public static int fseek (IntPtr stream, long offset, SeekFlags origin)
1011                 {
1012                         int _origin = NativeConvert.FromSeekFlags (origin);
1013                         return sys_fseek (stream, offset, _origin);
1014                 }
1015
1016                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1017                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fsetpos")]
1018                 private static extern int sys_fsetpos (IntPtr stream, HandleRef pos);
1019
1020                 public static int fsetpos (IntPtr stream, FilePosition pos)
1021                 {
1022                         return sys_fsetpos (stream, pos.Handle);
1023                 }
1024
1025                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1026                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_ftell")]
1027                 public static extern long ftell (IntPtr stream);
1028
1029                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1030                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_rewind")]
1031                 public static extern int rewind (IntPtr stream);
1032
1033                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1034                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_clearerr")]
1035                 public static extern int clearerr (IntPtr stream);
1036
1037                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1038                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_feof")]
1039                 public static extern int feof (IntPtr stream);
1040
1041                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1042                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_ferror")]
1043                 public static extern int ferror (IntPtr stream);
1044
1045                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, 
1046                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_perror")]
1047                 private static extern int perror (string s, int err);
1048
1049                 public static int perror (string s)
1050                 {
1051                         return perror (s, Marshal.GetLastWin32Error ());
1052                 }
1053
1054                 //
1055                 // <stdlib.h>
1056                 //
1057                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1058                                 EntryPoint="Mono_Posix_Stdlib_EXIT_FAILURE")]
1059                 private static extern int GetExitFailure();
1060
1061                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1062                                 EntryPoint="Mono_Posix_Stdlib_EXIT_SUCCESS")]
1063                 private static extern int GetExitSuccess ();
1064
1065                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1066                                 EntryPoint="Mono_Posix_Stdlib_MB_CUR_MAX")]
1067                 private static extern int GetMbCurMax ();
1068
1069                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1070                                 EntryPoint="Mono_Posix_Stdlib_RAND_MAX")]
1071                 private static extern int GetRandMax ();
1072
1073                 [CLSCompliant (false)]
1074                 public static readonly int  EXIT_FAILURE = GetExitFailure ();
1075                 [CLSCompliant (false)]
1076                 public static readonly int  EXIT_SUCCESS = GetExitSuccess ();
1077                 [CLSCompliant (false)]
1078                 public static readonly int  MB_CUR_MAX   = GetMbCurMax ();
1079                 [CLSCompliant (false)]
1080                 public static readonly int  RAND_MAX     = GetRandMax ();
1081
1082                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
1083                 public static extern int rand ();
1084
1085                 [CLSCompliant (false)]
1086                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
1087                 public static extern void srand (uint seed);
1088
1089                 // calloc(3):
1090                 //    void *calloc (size_t nmemb, size_t size);
1091                 [CLSCompliant (false)]
1092                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1093                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_calloc")]
1094                 public static extern IntPtr calloc (ulong nmemb, ulong size);
1095
1096                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1097                                 EntryPoint="Mono_Posix_Stdlib_free")]
1098                 public static extern void free (IntPtr ptr);
1099
1100                 // malloc(3):
1101                 //    void *malloc(size_t size);
1102                 [CLSCompliant (false)]
1103                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1104                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_malloc")]
1105                 public static extern IntPtr malloc (ulong size);
1106
1107                 // realloc(3):
1108                 //    void *realloc(void *ptr, size_t size);
1109                 [CLSCompliant (false)]
1110                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1111                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_realloc")]
1112                 public static extern IntPtr realloc (IntPtr ptr, ulong size);
1113
1114                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
1115                 public static extern void abort ();
1116
1117                 /* SKIP: atexit(3) -- the GC should have collected most references by the
1118                  * time this runs, so no delegates should exist, making it pointless. */
1119
1120                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
1121                 public static extern void exit (int status);
1122
1123                 [CLSCompliant (false)]
1124                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
1125                 public static extern void _Exit (int status);
1126
1127                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, EntryPoint="getenv")]
1128                 private static extern IntPtr sys_getenv (string name);
1129
1130                 public static string getenv (string name)
1131                 {
1132                         IntPtr r = sys_getenv (name);
1133                         return UnixMarshal.PtrToString (r);
1134                 }
1135
1136                 [CLSCompliant (false)]
1137                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
1138                 public static extern int system (string @string);
1139
1140                 //
1141                 // <string.h>
1142                 //
1143
1144                 private static object strerror_lock = new object ();
1145
1146                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
1147                                 SetLastError=true, EntryPoint="strerror")]
1148                 private static extern IntPtr sys_strerror (int errnum);
1149
1150                 [CLSCompliant (false)]
1151                 public static string strerror (Errno errnum)
1152                 {
1153                         int e = NativeConvert.FromErrno (errnum);
1154                         lock (strerror_lock) {
1155                                 IntPtr r = sys_strerror (e);
1156                                 return UnixMarshal.PtrToString (r);
1157                         }
1158                 }
1159
1160                 // strlen(3):
1161                 //    size_t strlen(const char *s);
1162                 [CLSCompliant (false)]
1163                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1164                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_strlen")]
1165                 public static extern ulong strlen (IntPtr s);
1166         }
1167
1168         #endregion // Classes
1169 }
1170
1171 // vim: noexpandtab