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 
FilePosition()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 
Dispose()227 		public void Dispose ()
228 		{
229 			Cleanup ();
230 			GC.SuppressFinalize (this);
231 		}
232 
Cleanup()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 
ToString()241 		public override string ToString ()
242 		{
243 			return "(" + base.ToString () + " " + GetDump () + ")";
244 		}
245 
GetDump()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 
Equals(object obj)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 
Equals(FilePosition value)267 		public bool Equals (FilePosition value)
268 		{
269 			if (object.ReferenceEquals (this, value))
270 				return true;
271 			return ToString().Equals (value.ToString());
272 		}
273 
GetHashCode()274 		public override int GetHashCode ()
275 		{
276 			return ToString ().GetHashCode ();
277 		}
278 
~FilePosition()279 		~FilePosition ()
280 		{
281 			Cleanup ();
282 		}
283 
operator ==(FilePosition lhs, FilePosition rhs)284 		public static bool operator== (FilePosition lhs, FilePosition rhs)
285 		{
286 			return Object.Equals (lhs, rhs);
287 		}
288 
operator !=(FilePosition lhs, FilePosition rhs)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
SignalHandler(int signal)309 	public delegate void SignalHandler (int signal);
310 
311 
312 #if !NETSTANDARD2_0
313 	internal class XPrintfFunctions
314 	{
XPrintf(object[] parameters)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 
XPrintfFunctions()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")]
VersionStringPtr()401 		private static extern IntPtr VersionStringPtr ();
402 		private static bool versionCheckPerformed = false;
VersionCheck()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 
Stdlib()421 		static Stdlib ()
422 		{
423 			VersionCheck ();
424 		}
425 
Stdlib()426 		internal Stdlib () {}
427 
428 		#region <errno.h> Declarations
429 		//
430 		// <errno.h>  -- COMPLETE
431 		//
432 
GetLastError()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")]
_GetLastError()453 		private static extern int _GetLastError ();
454 
455 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
456 				EntryPoint="Mono_Posix_Stdlib_SetLastError")]
SetLastError(int error)457 		private static extern void SetLastError (int error);
458 
SetLastError(Errno error)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")]
InvokeSignalHandler(int signum, IntPtr handler)472 		internal static extern void InvokeSignalHandler (int signum, IntPtr handler);
473 
474 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
475 				EntryPoint="Mono_Posix_Stdlib_SIG_DFL")]
GetDefaultSignal()476 		private static extern IntPtr GetDefaultSignal ();
477 
478 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
479 				EntryPoint="Mono_Posix_Stdlib_SIG_ERR")]
GetErrorSignal()480 		private static extern IntPtr GetErrorSignal ();
481 
482 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
483 				EntryPoint="Mono_Posix_Stdlib_SIG_IGN")]
GetIgnoreSignal()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 
_ErrorHandler(int signum)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 
_DefaultHandler(int signum)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 
_IgnoreHandler(int signum)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")]
sys_signal(int signum, SignalHandler handler)517 		private static extern IntPtr sys_signal (int signum, SignalHandler handler);
518 
519 		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
520 				SetLastError=true, EntryPoint="signal")]
sys_signal(int signum, IntPtr handler)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()")]
signal(Signum signum, SignalHandler handler)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 
TranslateHandler(IntPtr handler)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 
SetSignalAction(Signum signal, SignalAction action)558 		public static int SetSignalAction (Signum signal, SignalAction action)
559 		{
560 			return SetSignalAction (NativeConvert.FromSignum (signal), action);
561 		}
562 
SetSignalAction(RealTimeSignum rts, SignalAction action)563 		public static int SetSignalAction (RealTimeSignum rts, SignalAction action)
564 		{
565 			return SetSignalAction (NativeConvert.FromRealTimeSignum (rts), action);
566 		}
567 
SetSignalAction(int signum, SignalAction action)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")]
sys_raise(int sig)591 		private static extern int sys_raise (int sig);
592 
593 		[CLSCompliant (false)]
raise(Signum sig)594 		public static int raise (Signum sig)
595 		{
596 			return sys_raise (NativeConvert.FromSignum (sig));
597 		}
598 
raise(RealTimeSignum rts)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")]
GetFullyBuffered()612 		private static extern int GetFullyBuffered ();
613 
614 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
615 				EntryPoint="Mono_Posix_Stdlib__IOLBF")]
GetLineBuffered()616 		private static extern int GetLineBuffered ();
617 
618 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
619 				EntryPoint="Mono_Posix_Stdlib__IONBF")]
GetNonBuffered()620 		private static extern int GetNonBuffered ();
621 
622 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
623 				EntryPoint="Mono_Posix_Stdlib_BUFSIZ")]
GetBufferSize()624 		private static extern int GetBufferSize ();
625 
626 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
627 				EntryPoint="Mono_Posix_Stdlib_CreateFilePosition")]
CreateFilePosition()628 		internal static extern IntPtr CreateFilePosition ();
629 
630 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
631 				EntryPoint="Mono_Posix_Stdlib_DumpFilePosition")]
DumpFilePosition(StringBuilder buf, HandleRef handle, int len)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")]
GetEOF()636 		private static extern int GetEOF ();
637 
638 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
639 				EntryPoint="Mono_Posix_Stdlib_FILENAME_MAX")]
GetFilenameMax()640 		private static extern int GetFilenameMax ();
641 
642 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
643 				EntryPoint="Mono_Posix_Stdlib_FOPEN_MAX")]
GetFopenMax()644 		private static extern int GetFopenMax ();
645 
646 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
647 				EntryPoint="Mono_Posix_Stdlib_L_tmpnam")]
GetTmpnamLength()648 		private static extern int GetTmpnamLength ();
649 
650 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
651 				EntryPoint="Mono_Posix_Stdlib_stdin")]
GetStandardInput()652 		private static extern IntPtr GetStandardInput ();
653 
654 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
655 				EntryPoint="Mono_Posix_Stdlib_stdout")]
GetStandardOutput()656 		private static extern IntPtr GetStandardOutput ();
657 
658 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
659 				EntryPoint="Mono_Posix_Stdlib_stderr")]
GetStandardError()660 		private static extern IntPtr GetStandardError ();
661 
662 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
663 				EntryPoint="Mono_Posix_Stdlib_TMP_MAX")]
GetTmpMax()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)]
remove( [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))] string filename)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)]
rename( [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))] string oldpath, [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))] string newpath)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")]
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")]
sys_tmpnam(StringBuilder s)708 		private static extern IntPtr sys_tmpnam (StringBuilder s);
709 
710 		[Obsolete ("Syscall.mkstemp() should be preferred.")]
tmpnam(StringBuilder s)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.")]
tmpnam()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")]
fclose(IntPtr stream)732 		public static extern int fclose (IntPtr stream);
733 
734 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
735 				SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fflush")]
fflush(IntPtr stream)736 		public static extern int fflush (IntPtr stream);
737 
738 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
739 				SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fopen")]
fopen( [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))] string path, string mode)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")]
freopen( [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))] string path, string mode, IntPtr stream)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")]
setbuf(IntPtr stream, IntPtr buf)752 		public static extern int setbuf (IntPtr stream, IntPtr buf);
753 
754 		[CLSCompliant (false)]
setbuf(IntPtr stream, byte* buf)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")]
setvbuf(IntPtr stream, IntPtr buf, int mode, ulong size)763 		public static extern int setvbuf (IntPtr stream, IntPtr buf, int mode, ulong size);
764 
765 		[CLSCompliant (false)]
setvbuf(IntPtr stream, byte* buf, int mode, ulong size)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")]
sys_fprintf(IntPtr stream, string format, string message)773 		private static extern int sys_fprintf (IntPtr stream, string format, string message);
774 
fprintf(IntPtr stream, string message)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.")]
fprintf(IntPtr stream, string format, params object[] parameters)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")]
sys_printf(string format, string message)797 		private static extern int sys_printf (string format, string message);
798 
printf(string message)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.")]
printf(string format, params object[] parameters)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")]
sys_snprintf(StringBuilder s, ulong n, string format, string message)820 		private static extern int sys_snprintf (StringBuilder s, ulong n,
821 				string format, string message);
822 
823 		[CLSCompliant (false)]
snprintf(StringBuilder s, ulong n, string message)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 
snprintf(StringBuilder s, string message)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.")]
snprintf(StringBuilder s, ulong n, string format, params object[] parameters)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.")]
snprintf(StringBuilder s, string format, params object[] parameters)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")]
fgetc(IntPtr stream)884 		public static extern int fgetc (IntPtr stream);
885 
886 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
887 				SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fgets")]
sys_fgets(StringBuilder sb, int size, IntPtr stream)888 		private static extern IntPtr sys_fgets (StringBuilder sb, int size, IntPtr stream);
889 
fgets(StringBuilder sb, int size, IntPtr stream)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 
fgets(StringBuilder sb, IntPtr stream)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")]
fputc(int c, IntPtr stream)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")]
fputs(string s, IntPtr stream)909 		public static extern int fputs (string s, IntPtr stream);
910 
getc(IntPtr stream)911 		public static int getc (IntPtr stream)
912 		{
913 			return fgetc (stream);
914 		}
915 
916 		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
getchar()917 		public static extern int getchar ();
918 
919 		/* SKIP: gets(3) */
920 
putc(int c, IntPtr stream)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)]
putchar(int c)927 		public static extern int putchar (int c);
928 
929 		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
puts(string s)930 		public static extern int puts (string s);
931 
932 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
933 				SetLastError=true, EntryPoint="Mono_Posix_Stdlib_ungetc")]
ungetc(int c, IntPtr stream)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")]
fread(IntPtr ptr, ulong size, ulong nmemb, IntPtr stream)939 		public static extern ulong fread (IntPtr ptr, ulong size, ulong nmemb, IntPtr stream);
940 
941 		[CLSCompliant (false)]
fread(void* ptr, ulong size, ulong nmemb, IntPtr stream)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")]
sys_fread([Out] byte[] ptr, ulong size, ulong nmemb, IntPtr stream)949 		private static extern ulong sys_fread ([Out] byte[] ptr,
950 				ulong size, ulong nmemb, IntPtr stream);
951 
952 		[CLSCompliant (false)]
fread(byte[] ptr, ulong size, ulong nmemb, IntPtr stream)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)]
fread(byte[] ptr, IntPtr stream)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")]
fwrite(IntPtr ptr, ulong size, ulong nmemb, IntPtr stream)969 		public static extern ulong fwrite (IntPtr ptr, ulong size, ulong nmemb, IntPtr stream);
970 
971 		[CLSCompliant (false)]
fwrite(void* ptr, ulong size, ulong nmemb, IntPtr stream)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")]
sys_fwrite(byte[] ptr, ulong size, ulong nmemb, IntPtr stream)979 		private static extern ulong sys_fwrite (byte[] ptr,
980 				ulong size, ulong nmemb, IntPtr stream);
981 
982 		[CLSCompliant (false)]
fwrite(byte[] ptr, ulong size, ulong nmemb, IntPtr stream)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)]
fwrite(byte[] ptr, IntPtr stream)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")]
sys_fgetpos(IntPtr stream, HandleRef pos)998 		private static extern int sys_fgetpos (IntPtr stream, HandleRef pos);
999 
fgetpos(IntPtr stream, FilePosition pos)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")]
sys_fseek(IntPtr stream, long offset, int origin)1007 		private static extern int sys_fseek (IntPtr stream, long offset, int origin);
1008 
1009 		[CLSCompliant (false)]
fseek(IntPtr stream, long offset, SeekFlags origin)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")]
sys_fsetpos(IntPtr stream, HandleRef pos)1018 		private static extern int sys_fsetpos (IntPtr stream, HandleRef pos);
1019 
fsetpos(IntPtr stream, FilePosition pos)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")]
ftell(IntPtr stream)1027 		public static extern long ftell (IntPtr stream);
1028 
1029 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1030 				SetLastError=true, EntryPoint="Mono_Posix_Stdlib_rewind")]
rewind(IntPtr stream)1031 		public static extern int rewind (IntPtr stream);
1032 
1033 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1034 				SetLastError=true, EntryPoint="Mono_Posix_Stdlib_clearerr")]
clearerr(IntPtr stream)1035 		public static extern int clearerr (IntPtr stream);
1036 
1037 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1038 				SetLastError=true, EntryPoint="Mono_Posix_Stdlib_feof")]
feof(IntPtr stream)1039 		public static extern int feof (IntPtr stream);
1040 
1041 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1042 				SetLastError=true, EntryPoint="Mono_Posix_Stdlib_ferror")]
ferror(IntPtr stream)1043 		public static extern int ferror (IntPtr stream);
1044 
1045 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1046 				SetLastError=true, EntryPoint="Mono_Posix_Stdlib_perror")]
perror(string s, int err)1047 		private static extern int perror (string s, int err);
1048 
perror(string s)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")]
GetExitFailure()1059 		private static extern int GetExitFailure();
1060 
1061 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1062 				EntryPoint="Mono_Posix_Stdlib_EXIT_SUCCESS")]
GetExitSuccess()1063 		private static extern int GetExitSuccess ();
1064 
1065 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1066 				EntryPoint="Mono_Posix_Stdlib_MB_CUR_MAX")]
GetMbCurMax()1067 		private static extern int GetMbCurMax ();
1068 
1069 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1070 				EntryPoint="Mono_Posix_Stdlib_RAND_MAX")]
GetRandMax()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)]
rand()1083 		public static extern int rand ();
1084 
1085 		[CLSCompliant (false)]
1086 		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
srand(uint seed)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")]
calloc(ulong nmemb, ulong size)1094 		public static extern IntPtr calloc (ulong nmemb, ulong size);
1095 
1096 		[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
1097 				EntryPoint="Mono_Posix_Stdlib_free")]
free(IntPtr ptr)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")]
malloc(ulong size)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")]
realloc(IntPtr ptr, ulong size)1112 		public static extern IntPtr realloc (IntPtr ptr, ulong size);
1113 
1114 		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
abort()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)]
exit(int status)1121 		public static extern void exit (int status);
1122 
1123 		[CLSCompliant (false)]
1124 		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
_Exit(int status)1125 		public static extern void _Exit (int status);
1126 
1127 		[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, EntryPoint="getenv")]
sys_getenv(string name)1128 		private static extern IntPtr sys_getenv (string name);
1129 
getenv(string name)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)]
system(string @string)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")]
sys_strerror(int errnum)1148 		private static extern IntPtr sys_strerror (int errnum);
1149 
1150 		[CLSCompliant (false)]
strerror(Errno errnum)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")]
strlen(IntPtr s)1165 		public static extern ulong strlen (IntPtr s);
1166 	}
1167 
1168 	#endregion // Classes
1169 }
1170 
1171 // vim: noexpandtab
1172