* Makefile: Ignore warnings 0219 (variable declared and never used) and
[mono.git] / mcs / class / Mono.Posix / Mono.Unix / Stdlib.cs
1 //
2 // Mono.Unix/Stdlib.cs
3 //
4 // Authors:
5 //   Jonathan Pryor (jonpryor@vt.edu)
6 //
7 // (C) 2004-2005 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.IO;
31 using System.Runtime.InteropServices;
32 using System.Text;
33 using Mono.Unix;
34
35 namespace Mono.Unix {
36
37         #region Enumerations
38
39         [Map]
40         public enum Error : int {
41                 // errors & their values liberally copied from
42                 // FC2 /usr/include/asm/errno.h
43                 
44                 EPERM           =   1, // Operation not permitted 
45                 ENOENT          =   2, // No such file or directory 
46                 ESRCH           =   3, // No such process 
47                 EINTR           =   4, // Interrupted system call 
48                 EIO             =   5, // I/O error 
49                 ENXIO           =   6, // No such device or address 
50                 E2BIG           =   7, // Arg list too long 
51                 ENOEXEC         =   8, // Exec format error 
52                 EBADF           =   9, // Bad file number 
53                 ECHILD          =  10, // No child processes 
54                 EAGAIN          =  11, // Try again 
55                 ENOMEM          =  12, // Out of memory 
56                 EACCES          =  13, // Permission denied 
57                 EFAULT          =  14, // Bad address 
58                 ENOTBLK         =  15, // Block device required 
59                 EBUSY           =  16, // Device or resource busy 
60                 EEXIST          =  17, // File exists 
61                 EXDEV           =  18, // Cross-device link 
62                 ENODEV          =  19, // No such device 
63                 ENOTDIR         =  20, // Not a directory 
64                 EISDIR          =  21, // Is a directory 
65                 EINVAL          =  22, // Invalid argument 
66                 ENFILE          =  23, // File table overflow 
67                 EMFILE          =  24, // Too many open files 
68                 ENOTTY          =  25, // Not a typewriter 
69                 ETXTBSY         =  26, // Text file busy 
70                 EFBIG           =  27, // File too large 
71                 ENOSPC          =  28, // No space left on device 
72                 ESPIPE          =  29, // Illegal seek 
73                 EROFS           =  30, // Read-only file system 
74                 EMLINK          =  31, // Too many links 
75                 EPIPE           =  32, // Broken pipe 
76                 EDOM            =  33, // Math argument out of domain of func 
77                 ERANGE          =  34, // Math result not representable 
78                 EDEADLK         =  35, // Resource deadlock would occur 
79                 ENAMETOOLONG    =  36, // File name too long 
80                 ENOLCK          =  37, // No record locks available 
81                 ENOSYS          =  38, // Function not implemented 
82                 ENOTEMPTY       =  39, // Directory not empty 
83                 ELOOP           =  40, // Too many symbolic links encountered 
84                 EWOULDBLOCK     =  EAGAIN, // Operation would block 
85                 ENOMSG          =  42, // No message of desired type 
86                 EIDRM           =  43, // Identifier removed 
87                 ECHRNG          =  44, // Channel number out of range 
88                 EL2NSYNC        =  45, // Level 2 not synchronized 
89                 EL3HLT          =  46, // Level 3 halted 
90                 EL3RST          =  47, // Level 3 reset 
91                 ELNRNG          =  48, // Link number out of range 
92                 EUNATCH         =  49, // Protocol driver not attached 
93                 ENOCSI          =  50, // No CSI structure available 
94                 EL2HLT          =  51, // Level 2 halted 
95                 EBADE           =  52, // Invalid exchange 
96                 EBADR           =  53, // Invalid request descriptor 
97                 EXFULL          =  54, // Exchange full 
98                 ENOANO          =  55, // No anode 
99                 EBADRQC         =  56, // Invalid request code 
100                 EBADSLT         =  57, // Invalid slot 
101                       
102                 EDEADLOCK             =  EDEADLK,
103                       
104                 EBFONT          =  59, // Bad font file format 
105                 ENOSTR          =  60, // Device not a stream 
106                 ENODATA         =  61, // No data available 
107                 ETIME           =  62, // Timer expired 
108                 ENOSR           =  63, // Out of streams resources 
109                 ENONET          =  64, // Machine is not on the network 
110                 ENOPKG          =  65, // Package not installed 
111                 EREMOTE         =  66, // Object is remote 
112                 ENOLINK         =  67, // Link has been severed 
113                 EADV            =  68, // Advertise error 
114                 ESRMNT          =  69, // Srmount error 
115                 ECOMM           =  70, // Communication error on send 
116                 EPROTO          =  71, // Protocol error 
117                 EMULTIHOP       =  72, // Multihop attempted 
118                 EDOTDOT         =  73, // RFS specific error 
119                 EBADMSG         =  74, // Not a data message 
120                 EOVERFLOW       =  75, // Value too large for defined data type 
121                 ENOTUNIQ        =  76, // Name not unique on network 
122                 EBADFD          =  77, // File descriptor in bad state 
123                 EREMCHG         =  78, // Remote address changed 
124                 ELIBACC         =  79, // Can not access a needed shared library 
125                 ELIBBAD         =  80, // Accessing a corrupted shared library 
126                 ELIBSCN         =  81, // .lib section in a.out corrupted 
127                 ELIBMAX         =  82, // Attempting to link in too many shared libraries 
128                 ELIBEXEC        =  83, // Cannot exec a shared library directly 
129                 EILSEQ          =  84, // Illegal byte sequence 
130                 ERESTART        =  85, // Interrupted system call should be restarted 
131                 ESTRPIPE        =  86, // Streams pipe error 
132                 EUSERS          =  87, // Too many users 
133                 ENOTSOCK        =  88, // Socket operation on non-socket 
134                 EDESTADDRREQ    =  89, // Destination address required 
135                 EMSGSIZE        =  90, // Message too long 
136                 EPROTOTYPE      =  91, // Protocol wrong type for socket 
137                 ENOPROTOOPT     =  92, // Protocol not available 
138                 EPROTONOSUPPORT =  93, // Protocol not supported 
139                 ESOCKTNOSUPPORT =  94, // Socket type not supported 
140                 EOPNOTSUPP      =  95, // Operation not supported on transport endpoint 
141                 EPFNOSUPPORT    =  96, // Protocol family not supported 
142                 EAFNOSUPPORT    =  97, // Address family not supported by protocol 
143                 EADDRINUSE      =  98, // Address already in use 
144                 EADDRNOTAVAIL   =  99, // Cannot assign requested address 
145                 ENETDOWN        = 100, // Network is down 
146                 ENETUNREACH     = 101, // Network is unreachable 
147                 ENETRESET       = 102, // Network dropped connection because of reset 
148                 ECONNABORTED    = 103, // Software caused connection abort 
149                 ECONNRESET      = 104, // Connection reset by peer 
150                 ENOBUFS         = 105, // No buffer space available 
151                 EISCONN         = 106, // Transport endpoint is already connected 
152                 ENOTCONN        = 107, // Transport endpoint is not connected 
153                 ESHUTDOWN       = 108, // Cannot send after transport endpoint shutdown 
154                 ETOOMANYREFS    = 109, // Too many references: cannot splice 
155                 ETIMEDOUT       = 110, // Connection timed out 
156                 ECONNREFUSED    = 111, // Connection refused 
157                 EHOSTDOWN       = 112, // Host is down 
158                 EHOSTUNREACH    = 113, // No route to host 
159                 EALREADY        = 114, // Operation already in progress 
160                 EINPROGRESS     = 115, // Operation now in progress 
161                 ESTALE          = 116, // Stale NFS file handle 
162                 EUCLEAN         = 117, // Structure needs cleaning 
163                 ENOTNAM         = 118, // Not a XENIX named type file 
164                 ENAVAIL         = 119, // No XENIX semaphores available 
165                 EISNAM          = 120, // Is a named type file 
166                 EREMOTEIO       = 121, // Remote I/O error 
167                 EDQUOT          = 122, // Quota exceeded 
168
169                 ENOMEDIUM       = 123, // No medium found 
170                 EMEDIUMTYPE     = 124, // Wrong medium type 
171         }
172
173         #endregion
174
175         #region Classes
176
177         public sealed class FilePosition : IDisposable {
178
179                 private static readonly int FilePositionDumpSize = 
180                         Stdlib.DumpFilePosition (null, new HandleRef (null, IntPtr.Zero), 0);
181
182                 private HandleRef pos;
183
184                 public FilePosition ()
185                 {
186                         IntPtr p = Stdlib.CreateFilePosition ();
187                         if (p == IntPtr.Zero)
188                                 throw new OutOfMemoryException ("Unable to malloc fpos_t!");
189                         pos = new HandleRef (this, p);
190                 }
191
192                 internal HandleRef Handle {
193                         get {return pos;}
194                 }
195
196                 public void Dispose ()
197                 {
198                         GC.SuppressFinalize (this);
199                         Cleanup ();
200                 }
201
202                 private void Cleanup ()
203                 {
204                         if (pos.Handle != IntPtr.Zero) {
205                                 Stdlib.free (pos.Handle);
206                                 pos = new HandleRef (this, IntPtr.Zero);
207                         }
208                 }
209
210                 public override string ToString ()
211                 {
212                         return "(" + base.ToString () + " " + GetDump () + ")";
213                 }
214
215                 private string GetDump ()
216                 {
217                         if (FilePositionDumpSize <= 0)
218                                 return "internal error";
219
220                         StringBuilder buf = new StringBuilder (FilePositionDumpSize+1);
221
222                         if (Stdlib.DumpFilePosition (buf, Handle, FilePositionDumpSize+1) <= 0)
223                                 return "internal error dumping fpos_t";
224
225                         return buf.ToString ();
226                 }
227
228                 public override bool Equals (object obj)
229                 {
230                         if (obj == null || GetType() != obj.GetType())
231                                 return false;
232                         return ToString().Equals (obj.ToString());
233                 }
234
235                 public override int GetHashCode ()
236                 {
237                         return ToString ().GetHashCode ();
238                 }
239
240                 ~FilePosition ()
241                 {
242                         Cleanup ();
243                 }
244
245                 public static bool operator== (FilePosition lhs, FilePosition rhs)
246                 {
247                         return Object.Equals (lhs, rhs);
248                 }
249
250                 public static bool operator!= (FilePosition lhs, FilePosition rhs)
251                 {
252                         return !Object.Equals (lhs, rhs);
253                 }
254         }
255
256 #if NET_2_0
257         [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
258 #endif
259         public delegate void SignalHandler (int signal);
260
261         internal sealed class SignalWrapper {
262                 private IntPtr handler;
263
264                 internal SignalWrapper (IntPtr handler)
265                 {
266                         this.handler = handler;
267                 }
268
269                 public void InvokeSignalHandler (int signum)
270                 {
271                         Stdlib.InvokeSignalHandler (signum, handler);
272                 }
273         }
274
275         internal class XPrintfFunctions
276         {
277                 internal delegate object XPrintf (object[] parameters);
278
279                 internal static XPrintf printf;
280                 internal static XPrintf fprintf;
281                 internal static XPrintf snprintf;
282                 internal static XPrintf syslog;
283
284                 static XPrintfFunctions ()
285                 {
286                         CdeclFunction _printf = new CdeclFunction (Stdlib.LIBC, "printf", typeof(int));
287                         printf = new XPrintf (_printf.Invoke);
288
289                         CdeclFunction _fprintf = new CdeclFunction (Stdlib.LIBC, "fprintf", typeof(int));
290                         fprintf = new XPrintf (_fprintf.Invoke);
291
292                         CdeclFunction _snprintf = new CdeclFunction (Stdlib.MPH, 
293                                         "Mono_Posix_Stdlib_snprintf", typeof(int));
294                         snprintf = new XPrintf (_snprintf.Invoke);
295
296                         CdeclFunction _syslog = new CdeclFunction (Syscall.LIBC, "syslog", typeof(void));
297                         syslog = new XPrintf (_syslog.Invoke);
298                 }
299         }
300
301         //
302         // Convention: Functions that are part of the C standard library go here.
303         //
304         // For example, the man page should say something similar to:
305         //
306         //    CONFORMING TO
307         //           ISO 9899 (''ANSI C'')
308         //
309         // The intent is that members of this class should be portable to any system
310         // supporting the C runtime (read: non-Unix, including Windows).  Using
311         // anything from Syscall is non-portable, but restricting yourself to just
312         // Stdlib is intended to be portable.
313         //
314         public class Stdlib
315         {
316                 internal const string LIBC = "msvcrt";
317                 internal const string MPH  = "MonoPosixHelper";
318
319                 internal Stdlib () {}
320
321                 #region <errno.h> Declarations
322                 //
323                 // <errno.h>  -- COMPLETE
324                 //
325
326                 public static Error GetLastError ()
327                 {
328                         int errno = Marshal.GetLastWin32Error ();
329                         return UnixConvert.ToError (errno);
330                 }
331
332                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
333                                 EntryPoint="Mono_Posix_Stdlib_SetLastError")]
334                 private static extern void SetLastError (int error);
335
336                 public static void SetLastError (Error error)
337                 {
338                         int _error = UnixConvert.FromError (error);
339                         SetLastError (_error);
340                 }
341                 #endregion
342
343                 //
344                 // <signal.h>
345                 //
346                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
347                                 EntryPoint="Mono_Posix_Syscall_InvokeSignalHandler")]
348                 internal static extern void InvokeSignalHandler (int signum, IntPtr handler);
349
350                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
351                                 EntryPoint="Mono_Posix_Stdlib_SIG_DFL")]
352                 private static extern IntPtr GetDefaultSignal ();
353
354                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
355                                 EntryPoint="Mono_Posix_Stdlib_SIG_ERR")]
356                 private static extern IntPtr GetErrorSignal ();
357
358                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
359                                 EntryPoint="Mono_Posix_Stdlib_SIG_IGN")]
360                 private static extern IntPtr GetIgnoreSignal ();
361
362                 private static readonly IntPtr _SIG_DFL = GetDefaultSignal ();
363                 private static readonly IntPtr _SIG_ERR = GetErrorSignal ();
364                 private static readonly IntPtr _SIG_IGN = GetIgnoreSignal ();
365
366                 private static void _ErrorHandler (int signum)
367                 {
368                         Console.Error.WriteLine ("Error handler invoked for signum " + 
369                                         signum + ".  Don't do that.");
370                 }
371
372                 private static void _DefaultHandler (int signum)
373                 {
374                         Console.Error.WriteLine ("Default handler invoked for signum " + 
375                                         signum + ".  Don't do that.");
376                 }
377
378                 private static void _IgnoreHandler (int signum)
379                 {
380                         Console.Error.WriteLine ("Ignore handler invoked for signum " + 
381                                         signum + ".  Don't do that.");
382                 }
383
384                 public static readonly SignalHandler SIG_DFL = new SignalHandler (_DefaultHandler);
385                 public static readonly SignalHandler SIG_ERR = new SignalHandler (_ErrorHandler);
386                 public static readonly SignalHandler SIG_IGN = new SignalHandler (_IgnoreHandler);
387
388                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
389                                 SetLastError=true, EntryPoint="signal")]
390                 private static extern IntPtr sys_signal (int signum, SignalHandler handler);
391
392                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
393                                 SetLastError=true, EntryPoint="signal")]
394                 private static extern IntPtr sys_signal (int signum, IntPtr handler);
395
396                 public static SignalHandler signal (Signum signum, SignalHandler handler)
397                 {
398                         int _sig = UnixConvert.FromSignum (signum);
399                         IntPtr r;
400                         if (handler == SIG_DFL)
401                                 r = sys_signal (_sig, _SIG_DFL);
402                         else if (handler == SIG_ERR)
403                                 r = sys_signal (_sig, _SIG_ERR);
404                         else if (handler == SIG_IGN)
405                                 r = sys_signal (_sig, _SIG_IGN);
406                         else
407                                 r = sys_signal (_sig, handler);
408                         return TranslateHandler (r);
409                 }
410
411                 private static SignalHandler TranslateHandler (IntPtr handler)
412                 {
413                         if (handler == _SIG_DFL)
414                                 return SIG_DFL;
415                         if (handler == _SIG_ERR)
416                                 return SIG_ERR;
417                         if (handler == _SIG_IGN)
418                                 return SIG_IGN;
419                         return new SignalHandler (new SignalWrapper (handler).InvokeSignalHandler);
420                 }
421
422                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, EntryPoint="raise")]
423                 private static extern int sys_raise (int sig);
424
425                 public static int raise (Signum sig)
426                 {
427                         int _sig = UnixConvert.FromSignum (sig);
428                         return sys_raise (_sig);
429                 }
430
431                 //
432                 // <stdio.h> -- COMPLETE except for :
433                 //    - the scanf(3) family .
434                 //    - vararg functions.
435                 //    - Horribly unsafe functions (gets(3)).
436                 //
437                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
438                                 EntryPoint="Mono_Posix_Stdlib__IOFBF")]
439                 private static extern int GetFullyBuffered ();
440
441                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
442                                 EntryPoint="Mono_Posix_Stdlib__IOLBF")]
443                 private static extern int GetLineBuffered ();
444
445                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
446                                 EntryPoint="Mono_Posix_Stdlib__IONBF")]
447                 private static extern int GetNonBuffered ();
448
449                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
450                                 EntryPoint="Mono_Posix_Stdlib_BUFSIZ")]
451                 private static extern int GetBufferSize ();
452
453                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
454                                 EntryPoint="Mono_Posix_Stdlib_CreateFilePosition")]
455                 internal static extern IntPtr CreateFilePosition ();
456
457                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
458                                 EntryPoint="Mono_Posix_Stdlib_DumpFilePosition")]
459                 internal static extern int DumpFilePosition (StringBuilder buf, HandleRef handle, int len);
460
461                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
462                                 EntryPoint="Mono_Posix_Stdlib_EOF")]
463                 private static extern int GetEOF ();
464
465                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
466                                 EntryPoint="Mono_Posix_Stdlib_FILENAME_MAX")]
467                 private static extern int GetFilenameMax ();
468
469                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
470                                 EntryPoint="Mono_Posix_Stdlib_FOPEN_MAX")]
471                 private static extern int GetFopenMax ();
472
473                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
474                                 EntryPoint="Mono_Posix_Stdlib_L_tmpnam")]
475                 private static extern int GetTmpnamLength ();
476
477                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
478                                 EntryPoint="Mono_Posix_Stdlib_stdin")]
479                 private static extern IntPtr GetStandardInput ();
480
481                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
482                                 EntryPoint="Mono_Posix_Stdlib_stdout")]
483                 private static extern IntPtr GetStandardOutput ();
484
485                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
486                                 EntryPoint="Mono_Posix_Stdlib_stderr")]
487                 private static extern IntPtr GetStandardError ();
488
489                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
490                                 EntryPoint="Mono_Posix_Stdlib_TMP_MAX")]
491                 private static extern int GetTmpMax ();
492
493                 public static readonly int    _IOFBF       = GetFullyBuffered ();
494                 public static readonly int    _IOLBF       = GetLineBuffered ();
495                 public static readonly int    _IONBF       = GetNonBuffered ();
496                 public static readonly int    BUFSIZ       = GetBufferSize ();
497                 public static readonly int    EOF          = GetEOF ();
498                 public static readonly int    FOPEN_MAX    = GetFopenMax ();
499                 public static readonly int    FILENAME_MAX = GetFilenameMax ();
500                 public static readonly int    L_tmpnam     = GetTmpnamLength ();
501                 public static readonly IntPtr stderr       = GetStandardError ();
502                 public static readonly IntPtr stdin        = GetStandardInput ();
503                 public static readonly IntPtr stdout       = GetStandardOutput ();
504                 public static readonly int    TMP_MAX      = GetTmpMax ();
505
506                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
507                 public static extern int remove (string filename);
508
509                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
510                 public static extern int rename (string oldpath, string newpath);
511
512                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
513                 public static extern IntPtr tmpfile ();
514
515                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
516                                 SetLastError=true, EntryPoint="tmpnam")]
517                 private static extern IntPtr sys_tmpnam (StringBuilder s);
518
519                 [Obsolete ("Syscall.mkstemp() should be preferred.")]
520                 public static string tmpnam (StringBuilder s)
521                 {
522                         if (s != null && s.Capacity < L_tmpnam)
523                                 throw new ArgumentOutOfRangeException ("s", "s.Capacity < L_tmpnam");
524                         IntPtr r = sys_tmpnam (s);
525                         return UnixMarshal.PtrToString (r);
526                 }
527
528                 [Obsolete ("Syscall.mkstemp() should be preferred.")]
529                 public static string tmpnam ()
530                 {
531                         IntPtr r = sys_tmpnam (null);
532                         return UnixMarshal.PtrToString (r);
533                 }
534
535                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
536                 public static extern int fclose (IntPtr stream);
537
538                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
539                 public static extern int fflush (IntPtr stream);
540
541                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
542                 public static extern IntPtr fopen (string path, string mode);
543
544                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
545                 public static extern IntPtr freopen (string path, string mode, IntPtr stream);
546
547                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
548                 public static extern void setbuf (IntPtr stream, IntPtr buf);
549
550                 public static unsafe void setbuf (IntPtr stream, byte* buf)
551                 {
552                         setbuf (stream, (IntPtr) buf);
553                 }
554
555                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
556                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_setvbuf")]
557                 public static extern int setvbuf (IntPtr stream, IntPtr buf, int mode, ulong size);
558
559                 public static unsafe int setvbuf (IntPtr stream, byte* buf, int mode, ulong size)
560                 {
561                         return setvbuf (stream, (IntPtr) buf, mode, size);
562                 }
563
564                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
565                                 EntryPoint="fprintf")]
566                 private static extern int sys_fprintf (IntPtr stream, string format, string message);
567
568                 public static int fprintf (IntPtr stream, string message)
569                 {
570                         return sys_fprintf (stream, "%s", message);
571                 }
572
573                 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
574                                 "Use fprintf (IntPtr, string) instead.")]
575                 public static int fprintf (IntPtr stream, string format, params object[] parameters)
576                 {
577                         object[] _parameters = new object[checked(parameters.Length+2)];
578                         _parameters [0] = stream;
579                         _parameters [1] = format;
580                         Array.Copy (parameters, 0, _parameters, 2, parameters.Length);
581                         return (int) XPrintfFunctions.fprintf (_parameters);
582                 }
583
584                 /* SKIP: fscanf(3) */
585
586                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
587                                 EntryPoint="printf")]
588                 private static extern int sys_printf (string format, string message);
589
590                 public static int printf (string message)
591                 {
592                         return sys_printf ("%s", message);
593                 }
594
595                 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
596                                 "Use printf (string) instead.")]
597                 public static int printf (string format, params object[] parameters)
598                 {
599                         object[] _parameters = new object[checked(parameters.Length+1)];
600                         _parameters [0] = format;
601                         Array.Copy (parameters, 0, _parameters, 1, parameters.Length);
602                         return (int) XPrintfFunctions.printf (_parameters);
603                 }
604
605                 /* SKIP: scanf(3) */
606
607                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
608                                 EntryPoint="Mono_Posix_Stdlib_snprintf")]
609                 private static extern int sys_snprintf (StringBuilder s, ulong n, 
610                                 string format, string message);
611
612                 public static int snprintf (StringBuilder s, ulong n, string message)
613                 {
614                         return sys_snprintf (s, n, "%s", message);
615                 }
616
617                 public static int snprintf (StringBuilder s, string message)
618                 {
619                         return sys_snprintf (s, (ulong) s.Capacity, "%s", message);
620                 }
621
622                 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
623                                 "Use snprintf (StringBuilder, string) instead.")]
624                 public static int snprintf (StringBuilder s, ulong n, 
625                                 string format, params object[] parameters)
626                 {
627                         object[] _parameters = new object[checked(parameters.Length+3)];
628                         _parameters [0] = s;
629                         _parameters [1] = n;
630                         _parameters [2] = format;
631                         Array.Copy (parameters, 0, _parameters, 3, parameters.Length);
632                         return (int) XPrintfFunctions.snprintf (_parameters);
633                 }
634
635                 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
636                                 "Use snprintf (StringBuilder, string) instead.")]
637                 public static int snprintf (StringBuilder s,
638                                 string format, params object[] parameters)
639                 {
640                         object[] _parameters = new object[checked(parameters.Length+3)];
641                         _parameters [0] = s;
642                         _parameters [1] = (ulong) s.Capacity;
643                         _parameters [2] = format;
644                         Array.Copy (parameters, 0, _parameters, 3, parameters.Length);
645                         return (int) XPrintfFunctions.snprintf (_parameters);
646                 }
647
648                 /*
649                  * SKIP:
650                  *    sprintf(3)
651                  *    sscanf(3)
652                  *    vfprintf(3)
653                  *    vfscanf(3)
654                  *    vprintf(3)
655                  *    vscanf(3)
656                  *    vsnprintf(3)
657                  *    vsprint(3)
658                  *    vsscanf(3)
659                  */
660
661                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
662                 public static extern int fgetc (IntPtr stream);
663
664                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
665                                 SetLastError=true, EntryPoint="fgets")]
666                 private static extern IntPtr sys_fgets (StringBuilder sb, int size, IntPtr stream);
667
668                 public static StringBuilder fgets (StringBuilder sb, int size, IntPtr stream)
669                 {
670                         IntPtr r = sys_fgets (sb, size, stream);
671                         if (r == IntPtr.Zero)
672                                 return null;
673                         return sb;
674                 }
675
676                 public static StringBuilder fgets (StringBuilder sb, IntPtr stream)
677                 {
678                         return fgets (sb, sb.Capacity, stream);
679                 }
680
681                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
682                 public static extern int fputc (int c, IntPtr stream);
683
684                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
685                 public static extern int fputs (string s, IntPtr stream);
686
687                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
688                 public static extern int getc (IntPtr stream);
689
690                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
691                 public static extern int getchar ();
692
693                 /* SKIP: gets(3) */
694
695                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
696                 public static extern int putc (int c, IntPtr stream);
697
698                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
699                 public static extern int putchar (int c);
700
701                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
702                 public static extern int puts (string s);
703
704                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
705                 public static extern int ungetc (int c, IntPtr stream);
706
707                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
708                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fread")]
709                 public static extern ulong fread (IntPtr ptr, ulong size, ulong nmemb, IntPtr stream);
710
711                 public static unsafe ulong fread (void* ptr, ulong size, ulong nmemb, IntPtr stream)
712                 {
713                         return fread ((IntPtr) ptr, size, nmemb, stream);
714                 }
715
716                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
717                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fread")]
718                 private static extern ulong sys_fread ([Out] byte[] ptr, 
719                                 ulong size, ulong nmemb, IntPtr stream);
720
721                 public static ulong fread (byte[] ptr, ulong size, ulong nmemb, IntPtr stream)
722                 {
723                         if ((size * nmemb) > (ulong) ptr.Length)
724                                 throw new ArgumentOutOfRangeException ("nmemb");
725                         return sys_fread (ptr, size, nmemb, stream);
726                 }
727
728                 public static ulong fread (byte[] ptr, IntPtr stream)
729                 {
730                         return fread (ptr, 1, (ulong) ptr.Length, stream);
731                 }
732
733                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
734                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fwrite")]
735                 public static extern ulong fwrite (IntPtr ptr, ulong size, ulong nmemb, IntPtr stream);
736
737                 public static unsafe ulong fwrite (void* ptr, ulong size, ulong nmemb, IntPtr stream)
738                 {
739                         return fwrite ((IntPtr) ptr, size, nmemb, stream);
740                 }
741
742                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
743                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fwrite")]
744                 private static extern ulong sys_fwrite (byte[] ptr, 
745                                 ulong size, ulong nmemb, IntPtr stream);
746
747                 public static ulong fwrite (byte[] ptr, ulong size, ulong nmemb, IntPtr stream)
748                 {
749                         if ((size * nmemb) > (ulong) ptr.Length)
750                                 throw new ArgumentOutOfRangeException ("nmemb");
751                         return sys_fwrite (ptr, size, nmemb, stream);
752                 }
753
754                 public static ulong fwrite (byte[] ptr, IntPtr stream)
755                 {
756                         return fwrite (ptr, 1, (ulong) ptr.Length, stream);
757                 }
758
759                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
760                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fgetpos")]
761                 private static extern int sys_fgetpos (IntPtr stream, HandleRef pos);
762
763                 public static int fgetpos (IntPtr stream, FilePosition pos)
764                 {
765                         return sys_fgetpos (stream, pos.Handle);
766                 }
767
768                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
769                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fseek")]
770                 private static extern int sys_fseek (IntPtr stream, long offset, int origin);
771
772                 public static int fseek (IntPtr stream, long offset, SeekFlags origin)
773                 {
774                         int _origin = UnixConvert.FromSeekFlags (origin);
775                         return sys_fseek (stream, offset, _origin);
776                 }
777
778                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
779                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fsetpos")]
780                 private static extern int sys_fsetpos (IntPtr stream, HandleRef pos);
781
782                 public static int fsetpos (IntPtr stream, FilePosition pos)
783                 {
784                         return sys_fsetpos (stream, pos.Handle);
785                 }
786
787                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
788                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_ftell")]
789                 public static extern long ftell (IntPtr stream);
790
791                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
792                 public static extern void rewind (IntPtr stream);
793
794                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
795                 public static extern void clearerr (IntPtr stream);
796
797                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
798                 public static extern int feof (IntPtr stream);
799
800                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
801                 public static extern int ferror (IntPtr stream);
802
803                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
804                 public static extern void perror (string s);
805
806                 //
807                 // <stdlib.h>
808                 //
809                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
810                                 EntryPoint="Mono_Posix_Stdlib_EXIT_FAILURE")]
811                 private static extern int GetExitFailure();
812
813                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
814                                 EntryPoint="Mono_Posix_Stdlib_EXIT_SUCCESS")]
815                 private static extern int GetExitSuccess ();
816
817                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
818                                 EntryPoint="Mono_Posix_Stdlib_MB_CUR_MAX")]
819                 private static extern int GetMbCurMax ();
820
821                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
822                                 EntryPoint="Mono_Posix_Stdlib_RAND_MAX")]
823                 private static extern int GetRandMax ();
824
825                 public static readonly int  EXIT_FAILURE = GetExitFailure ();
826                 public static readonly int  EXIT_SUCCESS = GetExitSuccess ();
827                 public static readonly int  MB_CUR_MAX   = GetMbCurMax ();
828                 public static readonly int  RAND_MAX     = GetRandMax ();
829
830                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
831                 public static extern int rand ();
832
833                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
834                 public static extern void srand (uint seed);
835
836                 // calloc(3):
837                 //    void *calloc (size_t nmemb, size_t size);
838                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
839                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_calloc")]
840                 public static extern IntPtr calloc (ulong nmemb, ulong size);
841
842                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
843                 public static extern void free (IntPtr ptr);
844
845                 // malloc(3):
846                 //    void *malloc(size_t size);
847                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
848                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_malloc")]
849                 public static extern IntPtr malloc (ulong size);
850
851                 // realloc(3):
852                 //    void *realloc(void *ptr, size_t size);
853                 [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
854                                 SetLastError=true, EntryPoint="Mono_Posix_Stdlib_realloc")]
855                 public static extern IntPtr realloc (IntPtr ptr, ulong size);
856
857                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
858                 public static extern void abort ();
859
860                 /* SKIP: atexit(3) */
861
862                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
863                 public static extern void exit (int status);
864
865                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)]
866                 public static extern void _Exit (int status);
867
868                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, EntryPoint="getenv")]
869                 private static extern IntPtr sys_getenv (string name);
870
871                 public static string getenv (string name)
872                 {
873                         IntPtr r = sys_getenv (name);
874                         return UnixMarshal.PtrToString (r);
875                 }
876
877                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
878                 public static extern int system (string @string);
879
880                 //
881                 // <string.h>
882                 //
883
884                 [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
885                                 SetLastError=true, EntryPoint="strerror")]
886                 private static extern IntPtr sys_strerror (int errnum);
887
888                 public static string strerror (Error errnum)
889                 {
890                         int e = UnixConvert.FromError (errnum);
891                         IntPtr r = sys_strerror (e);
892                         return UnixMarshal.PtrToString (r);
893                 }
894         }
895
896         #endregion // Classes
897 }
898
899 // vim: noexpandtab