5 // Jonathan Pryor (jonpryor@vt.edu)
7 // (C) 2004-2006 Jonathan Pryor
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System
.Collections
;
32 using System
.Runtime
.InteropServices
;
34 using Mono
.Unix
.Native
;
36 namespace Mono
.Unix
.Native
{
41 public enum Errno
: int {
42 // errors & their values liberally copied from
43 // FC2 /usr/include/asm/errno.h
45 EPERM
= 1, // Operation not permitted
46 ENOENT
= 2, // No such file or directory
47 ESRCH
= 3, // No such process
48 EINTR
= 4, // Interrupted system call
50 ENXIO
= 6, // No such device or address
51 E2BIG
= 7, // Arg list too long
52 ENOEXEC
= 8, // Exec format error
53 EBADF
= 9, // Bad file number
54 ECHILD
= 10, // No child processes
55 EAGAIN
= 11, // Try again
56 ENOMEM
= 12, // Out of memory
57 EACCES
= 13, // Permission denied
58 EFAULT
= 14, // Bad address
59 ENOTBLK
= 15, // Block device required
60 EBUSY
= 16, // Device or resource busy
61 EEXIST
= 17, // File exists
62 EXDEV
= 18, // Cross-device link
63 ENODEV
= 19, // No such device
64 ENOTDIR
= 20, // Not a directory
65 EISDIR
= 21, // Is a directory
66 EINVAL
= 22, // Invalid argument
67 ENFILE
= 23, // File table overflow
68 EMFILE
= 24, // Too many open files
69 ENOTTY
= 25, // Not a typewriter
70 ETXTBSY
= 26, // Text file busy
71 EFBIG
= 27, // File too large
72 ENOSPC
= 28, // No space left on device
73 ESPIPE
= 29, // Illegal seek
74 EROFS
= 30, // Read-only file system
75 EMLINK
= 31, // Too many links
76 EPIPE
= 32, // Broken pipe
77 EDOM
= 33, // Math argument out of domain of func
78 ERANGE
= 34, // Math result not representable
79 EDEADLK
= 35, // Resource deadlock would occur
80 ENAMETOOLONG
= 36, // File name too long
81 ENOLCK
= 37, // No record locks available
82 ENOSYS
= 38, // Function not implemented
83 ENOTEMPTY
= 39, // Directory not empty
84 ELOOP
= 40, // Too many symbolic links encountered
85 EWOULDBLOCK
= EAGAIN
, // Operation would block
86 ENOMSG
= 42, // No message of desired type
87 EIDRM
= 43, // Identifier removed
88 ECHRNG
= 44, // Channel number out of range
89 EL2NSYNC
= 45, // Level 2 not synchronized
90 EL3HLT
= 46, // Level 3 halted
91 EL3RST
= 47, // Level 3 reset
92 ELNRNG
= 48, // Link number out of range
93 EUNATCH
= 49, // Protocol driver not attached
94 ENOCSI
= 50, // No CSI structure available
95 EL2HLT
= 51, // Level 2 halted
96 EBADE
= 52, // Invalid exchange
97 EBADR
= 53, // Invalid request descriptor
98 EXFULL
= 54, // Exchange full
99 ENOANO
= 55, // No anode
100 EBADRQC
= 56, // Invalid request code
101 EBADSLT
= 57, // Invalid slot
105 EBFONT
= 59, // Bad font file format
106 ENOSTR
= 60, // Device not a stream
107 ENODATA
= 61, // No data available
108 ETIME
= 62, // Timer expired
109 ENOSR
= 63, // Out of streams resources
110 ENONET
= 64, // Machine is not on the network
111 ENOPKG
= 65, // Package not installed
112 EREMOTE
= 66, // Object is remote
113 ENOLINK
= 67, // Link has been severed
114 EADV
= 68, // Advertise error
115 ESRMNT
= 69, // Srmount error
116 ECOMM
= 70, // Communication error on send
117 EPROTO
= 71, // Protocol error
118 EMULTIHOP
= 72, // Multihop attempted
119 EDOTDOT
= 73, // RFS specific error
120 EBADMSG
= 74, // Not a data message
121 EOVERFLOW
= 75, // Value too large for defined data type
122 ENOTUNIQ
= 76, // Name not unique on network
123 EBADFD
= 77, // File descriptor in bad state
124 EREMCHG
= 78, // Remote address changed
125 ELIBACC
= 79, // Can not access a needed shared library
126 ELIBBAD
= 80, // Accessing a corrupted shared library
127 ELIBSCN
= 81, // .lib section in a.out corrupted
128 ELIBMAX
= 82, // Attempting to link in too many shared libraries
129 ELIBEXEC
= 83, // Cannot exec a shared library directly
130 EILSEQ
= 84, // Illegal byte sequence
131 ERESTART
= 85, // Interrupted system call should be restarted
132 ESTRPIPE
= 86, // Streams pipe error
133 EUSERS
= 87, // Too many users
134 ENOTSOCK
= 88, // Socket operation on non-socket
135 EDESTADDRREQ
= 89, // Destination address required
136 EMSGSIZE
= 90, // Message too long
137 EPROTOTYPE
= 91, // Protocol wrong type for socket
138 ENOPROTOOPT
= 92, // Protocol not available
139 EPROTONOSUPPORT
= 93, // Protocol not supported
140 ESOCKTNOSUPPORT
= 94, // Socket type not supported
141 EOPNOTSUPP
= 95, // Operation not supported on transport endpoint
142 EPFNOSUPPORT
= 96, // Protocol family not supported
143 EAFNOSUPPORT
= 97, // Address family not supported by protocol
144 EADDRINUSE
= 98, // Address already in use
145 EADDRNOTAVAIL
= 99, // Cannot assign requested address
146 ENETDOWN
= 100, // Network is down
147 ENETUNREACH
= 101, // Network is unreachable
148 ENETRESET
= 102, // Network dropped connection because of reset
149 ECONNABORTED
= 103, // Software caused connection abort
150 ECONNRESET
= 104, // Connection reset by peer
151 ENOBUFS
= 105, // No buffer space available
152 EISCONN
= 106, // Transport endpoint is already connected
153 ENOTCONN
= 107, // Transport endpoint is not connected
154 ESHUTDOWN
= 108, // Cannot send after transport endpoint shutdown
155 ETOOMANYREFS
= 109, // Too many references: cannot splice
156 ETIMEDOUT
= 110, // Connection timed out
157 ECONNREFUSED
= 111, // Connection refused
158 EHOSTDOWN
= 112, // Host is down
159 EHOSTUNREACH
= 113, // No route to host
160 EALREADY
= 114, // Operation already in progress
161 EINPROGRESS
= 115, // Operation now in progress
162 ESTALE
= 116, // Stale NFS file handle
163 EUCLEAN
= 117, // Structure needs cleaning
164 ENOTNAM
= 118, // Not a XENIX named type file
165 ENAVAIL
= 119, // No XENIX semaphores available
166 EISNAM
= 120, // Is a named type file
167 EREMOTEIO
= 121, // Remote I/O error
168 EDQUOT
= 122, // Quota exceeded
170 ENOMEDIUM
= 123, // No medium found
171 EMEDIUMTYPE
= 124, // Wrong medium type
180 ENOTRECOVERABLE
= 131,
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
206 public sealed class FilePosition
: MarshalByRefObject
, IDisposable
207 , IEquatable
<FilePosition
>
210 private static readonly int FilePositionDumpSize
=
211 Stdlib
.DumpFilePosition (null, new HandleRef (null, IntPtr
.Zero
), 0);
213 private HandleRef pos
;
215 public FilePosition ()
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
);
223 internal HandleRef Handle
{
227 public void Dispose ()
230 GC
.SuppressFinalize (this);
233 private void Cleanup ()
235 if (pos
.Handle
!= IntPtr
.Zero
) {
236 Stdlib
.free (pos
.Handle
);
237 pos
= new HandleRef (this, IntPtr
.Zero
);
241 public override string ToString ()
243 return "(" + base.ToString () + " " + GetDump () + ")";
246 private string GetDump ()
248 if (FilePositionDumpSize
<= 0)
249 return "internal error";
251 StringBuilder buf
= new StringBuilder (FilePositionDumpSize
+1);
253 if (Stdlib
.DumpFilePosition (buf
, Handle
, FilePositionDumpSize
+1) <= 0)
254 return "internal error dumping fpos_t";
256 return buf
.ToString ();
259 public override bool Equals (object obj
)
261 FilePosition fp
= obj
as FilePosition
;
262 if (obj
== null || fp
== null)
264 return ToString().Equals (obj
.ToString());
267 public bool Equals (FilePosition
value)
269 if (object.ReferenceEquals (this, value))
271 return ToString().Equals (value.ToString());
274 public override int GetHashCode ()
276 return ToString ().GetHashCode ();
284 public static bool operator== (FilePosition lhs
, FilePosition rhs
)
286 return Object
.Equals (lhs
, rhs
);
289 public static bool operator!= (FilePosition lhs
, FilePosition rhs
)
291 return !Object
.Equals (lhs
, rhs
);
296 public enum SignalAction
{
303 // Right now using this attribute gives an assert because it
304 // isn't implemented.
306 #if UNMANAGED_FN_PTR_SUPPORT_FIXED
307 [UnmanagedFunctionPointer (CallingConvention
.Cdecl
)]
309 public delegate void SignalHandler (int signal
);
312 internal class XPrintfFunctions
314 internal delegate object XPrintf (object[] parameters
);
316 internal static XPrintf printf
;
317 internal static XPrintf fprintf
;
318 internal static XPrintf snprintf
;
319 internal static XPrintf syslog
;
321 static XPrintfFunctions ()
323 CdeclFunction _printf
= new CdeclFunction (Stdlib
.LIBC
, "printf", typeof(int));
324 printf
= new XPrintf (_printf
.Invoke
);
326 CdeclFunction _fprintf
= new CdeclFunction (Stdlib
.LIBC
, "fprintf", typeof(int));
327 fprintf
= new XPrintf (_fprintf
.Invoke
);
329 CdeclFunction _snprintf
= new CdeclFunction (Stdlib
.MPH
,
330 "Mono_Posix_Stdlib_snprintf", typeof(int));
331 snprintf
= new XPrintf (_snprintf
.Invoke
);
333 CdeclFunction _syslog
= new CdeclFunction (Syscall
.MPH
,
334 "Mono_Posix_Stdlib_syslog2", typeof(int));
335 syslog
= new XPrintf (_syslog
.Invoke
);
340 // Convention: Functions that are part of the C standard library go here.
342 // For example, the man page should say something similar to:
345 // ISO 9899 (''ANSI C'')
347 // The intent is that members of this class should be portable to any system
348 // supporting the C runtime (read: non-Unix, including Windows). Using
349 // anything from Syscall is non-portable, but restricting yourself to just
350 // Stdlib is intended to be portable.
352 // The only methods in here should be:
353 // (1) low-level functions (as defined above).
354 // (2) "Trivial" function overloads. For example, if the parameters to a
355 // function are related (e.g. fwrite(3))
356 // (3) The return type SHOULD NOT be changed. If you want to provide a
357 // convenience function with a nicer return type, place it into one of
358 // the Mono.Unix.Std* wrapper classes, and give it a .NET-styled name.
359 // - EXCEPTION: No public functions should have a `void' return type.
360 // `void' return types should be replaced with `int'.
361 // Rationality: `void'-return functions typically require a
362 // complicated call sequence, such as clear errno, then call, then
363 // check errno to see if any errors occurred. This sequence can't
364 // be done safely in managed code, as errno may change as part of
365 // the P/Invoke mechanism.
366 // Instead, add a MonoPosixHelper export which does:
369 // return errno == 0 ? 0 : -1;
370 // This lets managed code check the return value in the usual manner.
371 // (4) Exceptions SHOULD NOT be thrown. EXCEPTIONS:
372 // - If you're wrapping *broken* methods which make assumptions about
373 // input data, such as that an argument refers to N bytes of data.
374 // This is currently limited to cuserid(3) and encrypt(3).
375 // - If you call functions which themselves generate exceptions.
376 // This is the case for using NativeConvert, which will throw an
377 // exception if an invalid/unsupported value is used.
381 internal const string LIBC
= "msvcrt";
382 internal const string MPH
= "MonoPosixHelper";
384 // It is possible for Mono.Posix and MonoPosixHelper to get out of sync,
385 // for example if NuGet does something weird. To mitigate this, anyone
386 // editing Mono.Posix needs to observe two rules:
387 // 1. When introducing C-interface changes to MonoPosixHelper, update
388 // the version strings in VersionCheck below and also
389 // Mono_Unix_VersionString in the C sources.
390 // 2. Any class which performs a DllImport on Stdlib.MPH needs to call
391 // Stdlib.VersionCheck in its static constructor.
393 [DllImport (Stdlib
.MPH
, CallingConvention
=CallingConvention
.Cdecl
,
394 EntryPoint
="Mono_Unix_VersionString")]
395 private static extern IntPtr
VersionStringPtr ();
396 private static bool versionCheckPerformed
= false;
397 internal static void VersionCheck ()
399 if (versionCheckPerformed
)
402 // This string is arbitrary; it matters only that it is unique.
403 string assemblyVersion
= "MonoProject-2015-12-1";
404 string nativeVersion
= Marshal
.PtrToStringAnsi (VersionStringPtr ());
405 if (assemblyVersion
!= nativeVersion
)
407 throw new Exception ("Mono.Posix assembly loaded with a different version (\""
408 + assemblyVersion
+ "\") than MonoPosixHelper (\"" + nativeVersion
409 + "\"). You may need to reinstall Mono.Posix.");
412 versionCheckPerformed
= true;
420 internal Stdlib () {}
422 #region <errno.h> Declarations
424 // <errno.h> -- COMPLETE
427 public static Errno
GetLastError ()
429 int errno
= Marshal
.GetLastWin32Error ();
430 return NativeConvert
.ToErrno (errno
);
433 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
434 EntryPoint
="Mono_Posix_Stdlib_SetLastError")]
435 private static extern void SetLastError (int error
);
437 protected static void SetLastError (Errno error
)
439 int _error
= NativeConvert
.FromErrno (error
);
440 SetLastError (_error
);
448 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
449 EntryPoint
="Mono_Posix_Stdlib_InvokeSignalHandler")]
450 internal static extern void InvokeSignalHandler (int signum
, IntPtr handler
);
452 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
453 EntryPoint
="Mono_Posix_Stdlib_SIG_DFL")]
454 private static extern IntPtr
GetDefaultSignal ();
456 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
457 EntryPoint
="Mono_Posix_Stdlib_SIG_ERR")]
458 private static extern IntPtr
GetErrorSignal ();
460 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
461 EntryPoint
="Mono_Posix_Stdlib_SIG_IGN")]
462 private static extern IntPtr
GetIgnoreSignal ();
464 private static readonly IntPtr _SIG_DFL
= GetDefaultSignal ();
465 private static readonly IntPtr _SIG_ERR
= GetErrorSignal ();
466 private static readonly IntPtr _SIG_IGN
= GetIgnoreSignal ();
468 private static void _ErrorHandler (int signum
)
470 Console
.Error
.WriteLine ("Error handler invoked for signum " +
471 signum
+ ". Don't do that.");
474 private static void _DefaultHandler (int signum
)
476 Console
.Error
.WriteLine ("Default handler invoked for signum " +
477 signum
+ ". Don't do that.");
480 private static void _IgnoreHandler (int signum
)
482 Console
.Error
.WriteLine ("Ignore handler invoked for signum " +
483 signum
+ ". Don't do that.");
486 [CLSCompliant (false)]
487 public static readonly SignalHandler SIG_DFL
= new SignalHandler (_DefaultHandler
);
488 [CLSCompliant (false)]
489 public static readonly SignalHandler SIG_ERR
= new SignalHandler (_ErrorHandler
);
490 [CLSCompliant (false)]
491 public static readonly SignalHandler SIG_IGN
= new SignalHandler (_IgnoreHandler
);
493 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
,
494 SetLastError
=true, EntryPoint
="signal")]
495 private static extern IntPtr
sys_signal (int signum
, SignalHandler handler
);
497 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
,
498 SetLastError
=true, EntryPoint
="signal")]
499 private static extern IntPtr
sys_signal (int signum
, IntPtr handler
);
501 [CLSCompliant (false)]
502 [Obsolete ("This is not safe; " +
503 "use Mono.Unix.UnixSignal for signal delivery or SetSignalAction()")]
504 public static SignalHandler
signal (Signum signum
, SignalHandler handler
)
506 int _sig
= NativeConvert
.FromSignum (signum
);
508 Delegate
[] handlers
= handler
.GetInvocationList ();
509 for (int i
= 0; i
< handlers
.Length
; ++i
) {
510 Marshal
.Prelink (handlers
[i
].Method
);
514 if (handler
== SIG_DFL
)
515 r
= sys_signal (_sig
, _SIG_DFL
);
516 else if (handler
== SIG_ERR
)
517 r
= sys_signal (_sig
, _SIG_ERR
);
518 else if (handler
== SIG_IGN
)
519 r
= sys_signal (_sig
, _SIG_IGN
);
521 r
= sys_signal (_sig
, handler
);
522 return TranslateHandler (r
);
525 private static SignalHandler
TranslateHandler (IntPtr handler
)
527 if (handler
== _SIG_DFL
)
529 if (handler
== _SIG_ERR
)
531 if (handler
== _SIG_IGN
)
533 return (SignalHandler
) Marshal
.GetDelegateForFunctionPointer (handler
, typeof(SignalHandler
));
536 public static int SetSignalAction (Signum signal
, SignalAction action
)
538 return SetSignalAction (NativeConvert
.FromSignum (signal
), action
);
541 public static int SetSignalAction (RealTimeSignum rts
, SignalAction action
)
543 return SetSignalAction (NativeConvert
.FromRealTimeSignum (rts
), action
);
546 private static int SetSignalAction (int signum
, SignalAction action
)
548 IntPtr handler
= IntPtr
.Zero
;
550 case SignalAction
.Default
:
553 case SignalAction
.Ignore
:
556 case SignalAction
.Error
:
560 throw new ArgumentException ("Invalid action value.", "action");
562 IntPtr r
= sys_signal (signum
, handler
);
568 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, EntryPoint
="raise")]
569 private static extern int sys_raise (int sig
);
571 [CLSCompliant (false)]
572 public static int raise (Signum sig
)
574 return sys_raise (NativeConvert
.FromSignum (sig
));
577 public static int raise (RealTimeSignum rts
)
579 return sys_raise (NativeConvert
.FromRealTimeSignum (rts
));
583 // <stdio.h> -- COMPLETE except for :
584 // - the scanf(3) family .
585 // - vararg functions.
586 // - Horribly unsafe functions (gets(3)).
588 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
589 EntryPoint
="Mono_Posix_Stdlib__IOFBF")]
590 private static extern int GetFullyBuffered ();
592 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
593 EntryPoint
="Mono_Posix_Stdlib__IOLBF")]
594 private static extern int GetLineBuffered ();
596 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
597 EntryPoint
="Mono_Posix_Stdlib__IONBF")]
598 private static extern int GetNonBuffered ();
600 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
601 EntryPoint
="Mono_Posix_Stdlib_BUFSIZ")]
602 private static extern int GetBufferSize ();
604 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
605 EntryPoint
="Mono_Posix_Stdlib_CreateFilePosition")]
606 internal static extern IntPtr
CreateFilePosition ();
608 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
609 EntryPoint
="Mono_Posix_Stdlib_DumpFilePosition")]
610 internal static extern int DumpFilePosition (StringBuilder buf
, HandleRef handle
, int len
);
612 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
613 EntryPoint
="Mono_Posix_Stdlib_EOF")]
614 private static extern int GetEOF ();
616 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
617 EntryPoint
="Mono_Posix_Stdlib_FILENAME_MAX")]
618 private static extern int GetFilenameMax ();
620 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
621 EntryPoint
="Mono_Posix_Stdlib_FOPEN_MAX")]
622 private static extern int GetFopenMax ();
624 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
625 EntryPoint
="Mono_Posix_Stdlib_L_tmpnam")]
626 private static extern int GetTmpnamLength ();
628 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
629 EntryPoint
="Mono_Posix_Stdlib_stdin")]
630 private static extern IntPtr
GetStandardInput ();
632 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
633 EntryPoint
="Mono_Posix_Stdlib_stdout")]
634 private static extern IntPtr
GetStandardOutput ();
636 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
637 EntryPoint
="Mono_Posix_Stdlib_stderr")]
638 private static extern IntPtr
GetStandardError ();
640 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
641 EntryPoint
="Mono_Posix_Stdlib_TMP_MAX")]
642 private static extern int GetTmpMax ();
644 [CLSCompliant (false)]
645 public static readonly int _IOFBF
= GetFullyBuffered ();
646 [CLSCompliant (false)]
647 public static readonly int _IOLBF
= GetLineBuffered ();
648 [CLSCompliant (false)]
649 public static readonly int _IONBF
= GetNonBuffered ();
650 [CLSCompliant (false)]
651 public static readonly int BUFSIZ
= GetBufferSize ();
652 [CLSCompliant (false)]
653 public static readonly int EOF
= GetEOF ();
654 [CLSCompliant (false)]
655 public static readonly int FOPEN_MAX
= GetFopenMax ();
656 [CLSCompliant (false)]
657 public static readonly int FILENAME_MAX
= GetFilenameMax ();
658 [CLSCompliant (false)]
659 public static readonly int L_tmpnam
= GetTmpnamLength ();
660 public static readonly IntPtr stderr
= GetStandardError ();
661 public static readonly IntPtr stdin
= GetStandardInput ();
662 public static readonly IntPtr stdout
= GetStandardOutput ();
663 [CLSCompliant (false)]
664 public static readonly int TMP_MAX
= GetTmpMax ();
666 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
667 public static extern int remove (
668 [MarshalAs (UnmanagedType
.CustomMarshaler
, MarshalTypeRef
=typeof(FileNameMarshaler
))]
671 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
672 public static extern int rename (
673 [MarshalAs (UnmanagedType
.CustomMarshaler
, MarshalTypeRef
=typeof(FileNameMarshaler
))]
675 [MarshalAs (UnmanagedType
.CustomMarshaler
, MarshalTypeRef
=typeof(FileNameMarshaler
))]
678 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
679 public static extern IntPtr
tmpfile ();
681 private static object tmpnam_lock
= new object ();
683 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
,
684 SetLastError
=true, EntryPoint
="tmpnam")]
685 private static extern IntPtr
sys_tmpnam (StringBuilder s
);
687 [Obsolete ("Syscall.mkstemp() should be preferred.")]
688 public static string tmpnam (StringBuilder s
)
690 if (s
!= null && s
.Capacity
< L_tmpnam
)
691 throw new ArgumentOutOfRangeException ("s", "s.Capacity < L_tmpnam");
693 IntPtr r
= sys_tmpnam (s
);
694 return UnixMarshal
.PtrToString (r
);
698 [Obsolete ("Syscall.mkstemp() should be preferred.")]
699 public static string tmpnam ()
702 IntPtr r
= sys_tmpnam (null);
703 return UnixMarshal
.PtrToString (r
);
707 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
708 public static extern int fclose (IntPtr stream
);
710 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
711 public static extern int fflush (IntPtr stream
);
713 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
714 public static extern IntPtr
fopen (
715 [MarshalAs (UnmanagedType
.CustomMarshaler
, MarshalTypeRef
=typeof(FileNameMarshaler
))]
716 string path
, string mode
);
718 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
719 public static extern IntPtr
freopen (
720 [MarshalAs (UnmanagedType
.CustomMarshaler
, MarshalTypeRef
=typeof(FileNameMarshaler
))]
721 string path
, string mode
, IntPtr stream
);
723 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
724 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_setbuf")]
725 public static extern int setbuf (IntPtr stream
, IntPtr buf
);
727 [CLSCompliant (false)]
728 public static unsafe int setbuf (IntPtr stream
, byte* buf
)
730 return setbuf (stream
, (IntPtr
) buf
);
733 [CLSCompliant (false)]
734 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
735 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_setvbuf")]
736 public static extern int setvbuf (IntPtr stream
, IntPtr buf
, int mode
, ulong size
);
738 [CLSCompliant (false)]
739 public static unsafe int setvbuf (IntPtr stream
, byte* buf
, int mode
, ulong size
)
741 return setvbuf (stream
, (IntPtr
) buf
, mode
, size
);
744 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
,
745 EntryPoint
="fprintf")]
746 private static extern int sys_fprintf (IntPtr stream
, string format
, string message
);
748 public static int fprintf (IntPtr stream
, string message
)
750 return sys_fprintf (stream
, "%s", message
);
753 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
754 "Use fprintf (IntPtr, string) instead.")]
755 public static int fprintf (IntPtr stream
, string format
, params object[] parameters
)
757 object[] _parameters
= new object[checked(parameters
.Length
+2)];
758 _parameters
[0] = stream
;
759 _parameters
[1] = format
;
760 Array
.Copy (parameters
, 0, _parameters
, 2, parameters
.Length
);
761 return (int) XPrintfFunctions
.fprintf (_parameters
);
764 /* SKIP: fscanf(3) */
766 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
,
767 EntryPoint
="printf")]
768 private static extern int sys_printf (string format
, string message
);
770 public static int printf (string message
)
772 return sys_printf ("%s", message
);
775 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
776 "Use printf (string) instead.")]
777 public static int printf (string format
, params object[] parameters
)
779 object[] _parameters
= new object[checked(parameters
.Length
+1)];
780 _parameters
[0] = format
;
781 Array
.Copy (parameters
, 0, _parameters
, 1, parameters
.Length
);
782 return (int) XPrintfFunctions
.printf (_parameters
);
787 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
788 EntryPoint
="Mono_Posix_Stdlib_snprintf")]
789 private static extern int sys_snprintf (StringBuilder s
, ulong n
,
790 string format
, string message
);
792 [CLSCompliant (false)]
793 public static int snprintf (StringBuilder s
, ulong n
, string message
)
795 if (n
> (ulong) s
.Capacity
)
796 throw new ArgumentOutOfRangeException ("n", "n must be <= s.Capacity");
797 return sys_snprintf (s
, n
, "%s", message
);
800 public static int snprintf (StringBuilder s
, string message
)
802 return sys_snprintf (s
, (ulong) s
.Capacity
, "%s", message
);
805 [CLSCompliant (false)]
806 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
807 "Use snprintf (StringBuilder, string) instead.")]
808 public static int snprintf (StringBuilder s
, ulong n
,
809 string format
, params object[] parameters
)
811 if (n
> (ulong) s
.Capacity
)
812 throw new ArgumentOutOfRangeException ("n", "n must be <= s.Capacity");
814 object[] _parameters
= new object[checked(parameters
.Length
+3)];
817 _parameters
[2] = format
;
818 Array
.Copy (parameters
, 0, _parameters
, 3, parameters
.Length
);
819 return (int) XPrintfFunctions
.snprintf (_parameters
);
822 [CLSCompliant (false)]
823 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
824 "Use snprintf (StringBuilder, string) instead.")]
825 public static int snprintf (StringBuilder s
,
826 string format
, params object[] parameters
)
828 object[] _parameters
= new object[checked(parameters
.Length
+3)];
830 _parameters
[1] = (ulong) s
.Capacity
;
831 _parameters
[2] = format
;
832 Array
.Copy (parameters
, 0, _parameters
, 3, parameters
.Length
);
833 return (int) XPrintfFunctions
.snprintf (_parameters
);
849 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
850 public static extern int fgetc (IntPtr stream
);
852 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
,
853 SetLastError
=true, EntryPoint
="fgets")]
854 private static extern IntPtr
sys_fgets (StringBuilder sb
, int size
, IntPtr stream
);
856 public static StringBuilder
fgets (StringBuilder sb
, int size
, IntPtr stream
)
858 IntPtr r
= sys_fgets (sb
, size
, stream
);
859 if (r
== IntPtr
.Zero
)
864 public static StringBuilder
fgets (StringBuilder sb
, IntPtr stream
)
866 return fgets (sb
, sb
.Capacity
, stream
);
869 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
870 public static extern int fputc (int c
, IntPtr stream
);
872 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
873 public static extern int fputs (string s
, IntPtr stream
);
875 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
876 public static extern int getc (IntPtr stream
);
878 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
879 public static extern int getchar ();
883 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
884 public static extern int putc (int c
, IntPtr stream
);
886 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
887 public static extern int putchar (int c
);
889 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
890 public static extern int puts (string s
);
892 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
893 public static extern int ungetc (int c
, IntPtr stream
);
895 [CLSCompliant (false)]
896 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
897 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_fread")]
898 public static extern ulong fread (IntPtr ptr
, ulong size
, ulong nmemb
, IntPtr stream
);
900 [CLSCompliant (false)]
901 public static unsafe ulong fread (void* ptr
, ulong size
, ulong nmemb
, IntPtr stream
)
903 return fread ((IntPtr
) ptr
, size
, nmemb
, stream
);
906 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
907 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_fread")]
908 private static extern ulong sys_fread ([Out
] byte[] ptr
,
909 ulong size
, ulong nmemb
, IntPtr stream
);
911 [CLSCompliant (false)]
912 public static ulong fread (byte[] ptr
, ulong size
, ulong nmemb
, IntPtr stream
)
914 if ((size
* nmemb
) > (ulong) ptr
.Length
)
915 throw new ArgumentOutOfRangeException ("nmemb");
916 return sys_fread (ptr
, size
, nmemb
, stream
);
919 [CLSCompliant (false)]
920 public static ulong fread (byte[] ptr
, IntPtr stream
)
922 return fread (ptr
, 1, (ulong) ptr
.Length
, stream
);
925 [CLSCompliant (false)]
926 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
927 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_fwrite")]
928 public static extern ulong fwrite (IntPtr ptr
, ulong size
, ulong nmemb
, IntPtr stream
);
930 [CLSCompliant (false)]
931 public static unsafe ulong fwrite (void* ptr
, ulong size
, ulong nmemb
, IntPtr stream
)
933 return fwrite ((IntPtr
) ptr
, size
, nmemb
, stream
);
936 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
937 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_fwrite")]
938 private static extern ulong sys_fwrite (byte[] ptr
,
939 ulong size
, ulong nmemb
, IntPtr stream
);
941 [CLSCompliant (false)]
942 public static ulong fwrite (byte[] ptr
, ulong size
, ulong nmemb
, IntPtr stream
)
944 if ((size
* nmemb
) > (ulong) ptr
.Length
)
945 throw new ArgumentOutOfRangeException ("nmemb");
946 return sys_fwrite (ptr
, size
, nmemb
, stream
);
949 [CLSCompliant (false)]
950 public static ulong fwrite (byte[] ptr
, IntPtr stream
)
952 return fwrite (ptr
, 1, (ulong) ptr
.Length
, stream
);
955 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
956 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_fgetpos")]
957 private static extern int sys_fgetpos (IntPtr stream
, HandleRef pos
);
959 public static int fgetpos (IntPtr stream
, FilePosition pos
)
961 return sys_fgetpos (stream
, pos
.Handle
);
964 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
965 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_fseek")]
966 private static extern int sys_fseek (IntPtr stream
, long offset
, int origin
);
968 [CLSCompliant (false)]
969 public static int fseek (IntPtr stream
, long offset
, SeekFlags origin
)
971 int _origin
= NativeConvert
.FromSeekFlags (origin
);
972 return sys_fseek (stream
, offset
, _origin
);
975 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
976 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_fsetpos")]
977 private static extern int sys_fsetpos (IntPtr stream
, HandleRef pos
);
979 public static int fsetpos (IntPtr stream
, FilePosition pos
)
981 return sys_fsetpos (stream
, pos
.Handle
);
984 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
985 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_ftell")]
986 public static extern long ftell (IntPtr stream
);
988 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
989 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_rewind")]
990 public static extern int rewind (IntPtr stream
);
992 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
993 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_clearerr")]
994 public static extern int clearerr (IntPtr stream
);
996 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
)]
997 public static extern int feof (IntPtr stream
);
999 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
)]
1000 public static extern int ferror (IntPtr stream
);
1002 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
1003 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_perror")]
1004 private static extern int perror (string s
, int err
);
1006 public static int perror (string s
)
1008 return perror (s
, Marshal
.GetLastWin32Error ());
1014 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
1015 EntryPoint
="Mono_Posix_Stdlib_EXIT_FAILURE")]
1016 private static extern int GetExitFailure();
1018 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
1019 EntryPoint
="Mono_Posix_Stdlib_EXIT_SUCCESS")]
1020 private static extern int GetExitSuccess ();
1022 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
1023 EntryPoint
="Mono_Posix_Stdlib_MB_CUR_MAX")]
1024 private static extern int GetMbCurMax ();
1026 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
1027 EntryPoint
="Mono_Posix_Stdlib_RAND_MAX")]
1028 private static extern int GetRandMax ();
1030 [CLSCompliant (false)]
1031 public static readonly int EXIT_FAILURE
= GetExitFailure ();
1032 [CLSCompliant (false)]
1033 public static readonly int EXIT_SUCCESS
= GetExitSuccess ();
1034 [CLSCompliant (false)]
1035 public static readonly int MB_CUR_MAX
= GetMbCurMax ();
1036 [CLSCompliant (false)]
1037 public static readonly int RAND_MAX
= GetRandMax ();
1039 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
)]
1040 public static extern int rand ();
1042 [CLSCompliant (false)]
1043 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
)]
1044 public static extern void srand (uint seed
);
1047 // void *calloc (size_t nmemb, size_t size);
1048 [CLSCompliant (false)]
1049 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
1050 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_calloc")]
1051 public static extern IntPtr
calloc (ulong nmemb
, ulong size
);
1053 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
)]
1054 public static extern void free (IntPtr ptr
);
1057 // void *malloc(size_t size);
1058 [CLSCompliant (false)]
1059 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
1060 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_malloc")]
1061 public static extern IntPtr
malloc (ulong size
);
1064 // void *realloc(void *ptr, size_t size);
1065 [CLSCompliant (false)]
1066 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
1067 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_realloc")]
1068 public static extern IntPtr
realloc (IntPtr ptr
, ulong size
);
1070 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
)]
1071 public static extern void abort ();
1073 /* SKIP: atexit(3) -- the GC should have collected most references by the
1074 * time this runs, so no delegates should exist, making it pointless. */
1076 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
)]
1077 public static extern void exit (int status
);
1079 [CLSCompliant (false)]
1080 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
)]
1081 public static extern void _Exit (int status
);
1083 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, EntryPoint
="getenv")]
1084 private static extern IntPtr
sys_getenv (string name
);
1086 public static string getenv (string name
)
1088 IntPtr r
= sys_getenv (name
);
1089 return UnixMarshal
.PtrToString (r
);
1092 [CLSCompliant (false)]
1093 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
, SetLastError
=true)]
1094 public static extern int system (string @string);
1100 private static object strerror_lock
= new object ();
1102 [DllImport (LIBC
, CallingConvention
=CallingConvention
.Cdecl
,
1103 SetLastError
=true, EntryPoint
="strerror")]
1104 private static extern IntPtr
sys_strerror (int errnum
);
1106 [CLSCompliant (false)]
1107 public static string strerror (Errno errnum
)
1109 int e
= NativeConvert
.FromErrno (errnum
);
1110 lock (strerror_lock
) {
1111 IntPtr r
= sys_strerror (e
);
1112 return UnixMarshal
.PtrToString (r
);
1117 // size_t strlen(const char *s);
1118 [CLSCompliant (false)]
1119 [DllImport (MPH
, CallingConvention
=CallingConvention
.Cdecl
,
1120 SetLastError
=true, EntryPoint
="Mono_Posix_Stdlib_strlen")]
1121 public static extern ulong strlen (IntPtr s
);
1124 #endregion // Classes