5 // Jonathan Pryor (jonpryor@vt.edu)
7 // (C) 2004 Jonathan Pryor
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Runtime.InteropServices;
37 public delegate void SignalHandler (int signal);
39 [StructLayout (LayoutKind.Sequential)]
40 public sealed class FilePosition : IDisposable {
42 [DllImport ("MonoPosixHelper",
43 EntryPoint="Mono_Posix_Stdlib_CreateFilePosition")]
44 private static extern IntPtr CreateFilePosition ();
46 private HandleRef pos;
48 public FilePosition ()
50 IntPtr p = CreateFilePosition ();
52 throw new OutOfMemoryException ("Unable to malloc fpos_t!");
53 pos = new HandleRef (this, p);
56 internal HandleRef Handle {
60 public void Dispose ()
62 GC.SuppressFinalize (this);
66 private void Cleanup ()
68 if (pos.Handle != IntPtr.Zero) {
69 Stdlib.free (pos.Handle);
70 pos = new HandleRef (this, IntPtr.Zero);
80 internal sealed class SignalWrapper {
81 private IntPtr handler;
83 internal SignalWrapper (IntPtr handler)
85 this.handler = handler;
88 private const string MPH = "MonoPosixHelper";
90 [DllImport (MPH, EntryPoint="Mono_Posix_Syscall_InvokeSignalHandler")]
91 private static extern void InvokeSignalHandler (int signum, IntPtr handler);
93 public void InvokeSignalHandler (int signum)
95 InvokeSignalHandler (signum, handler);
99 internal class XPrintfFunctions
101 internal delegate object XPrintf (object[] parameters);
103 internal static XPrintf printf;
104 internal static XPrintf fprintf;
105 internal static XPrintf syslog;
107 static XPrintfFunctions ()
109 CdeclFunction _printf = new CdeclFunction ("libc", "printf", typeof(int));
110 printf = new XPrintf (_printf.Invoke);
112 CdeclFunction _fprintf = new CdeclFunction ("libc", "fprintf", typeof(int));
113 fprintf = new XPrintf (_fprintf.Invoke);
115 CdeclFunction _syslog = new CdeclFunction ("libc", "syslog", typeof(void));
116 syslog = new XPrintf (_syslog.Invoke);
121 // Convention: Functions that are part of the C standard library go here.
123 // For example, the man page should say something similar to:
126 // ISO 9899 (''ANSI C'')
128 // We can also place logical "sibling" exports here -- exports which
129 // strongly relate to an ANSI C function, either as an overload, or which
130 // operates on the same datatype as an ANSI C function. Examples include
131 // fileno(3) and fdopen(3).
135 private const string LIBC = "libc";
136 private const string MPH = "MonoPosixHelper";
138 internal Stdlib () {}
143 [DllImport (MPH, EntryPoint="Mono_Posix_Stdlib_SIG_DFL")]
144 private static extern IntPtr GetDefaultSignal ();
146 [DllImport (MPH, EntryPoint="Mono_Posix_Stdlib_SIG_ERR")]
147 private static extern IntPtr GetErrorSignal ();
149 [DllImport (MPH, EntryPoint="Mono_Posix_Stdlib_SIG_IGN")]
150 private static extern IntPtr GetIgnoreSignal ();
152 private static readonly IntPtr _SIG_DFL = GetDefaultSignal ();
153 private static readonly IntPtr _SIG_ERR = GetErrorSignal ();
154 private static readonly IntPtr _SIG_IGN = GetIgnoreSignal ();
156 private static void _ErrorHandler (int signum)
158 Console.Error.WriteLine ("Error handler invoked for signum " +
159 signum + ". Don't do that.");
162 private static void _DefaultHandler (int signum)
164 Console.Error.WriteLine ("Default handler invoked for signum " +
165 signum + ". Don't do that.");
168 private static void _IgnoreHandler (int signum)
170 Console.Error.WriteLine ("Ignore handler invoked for signum " +
171 signum + ". Don't do that.");
174 public static readonly SignalHandler SIG_DFL = _DefaultHandler;
175 public static readonly SignalHandler SIG_ERR = _ErrorHandler;
176 public static readonly SignalHandler SIG_IGN = _IgnoreHandler;
178 [DllImport (LIBC, SetLastError=true, EntryPoint="signal")]
179 private static extern IntPtr sys_signal (int signum, SignalHandler handler);
181 [DllImport (LIBC, SetLastError=true, EntryPoint="signal")]
182 private static extern IntPtr sys_signal (int signum, IntPtr handler);
184 public static SignalHandler signal (Signum signum, SignalHandler handler)
186 int _sig = UnixConvert.FromSignum (signum);
188 if (handler == SIG_DFL)
189 r = sys_signal (_sig, _SIG_DFL);
190 else if (handler == SIG_ERR)
191 r = sys_signal (_sig, _SIG_ERR);
192 else if (handler == SIG_IGN)
193 r = sys_signal (_sig, _SIG_IGN);
195 r = sys_signal (_sig, handler);
196 return TranslateHandler (r);
199 private static SignalHandler TranslateHandler (IntPtr handler)
201 if (handler == _SIG_DFL)
203 if (handler == _SIG_ERR)
205 if (handler == _SIG_IGN)
207 return new SignalHandler (new SignalWrapper (handler).InvokeSignalHandler);
210 [DllImport (LIBC, EntryPoint="raise")]
211 private static extern int sys_raise (int sig);
213 public static int raise (Signum sig)
215 int _sig = UnixConvert.FromSignum (sig);
216 return sys_raise (_sig);
222 [DllImport (MPH, EntryPoint="Mono_Posix_Stdlib__IOFBF")]
223 private static extern int GetFullyBuffered ();
225 [DllImport (MPH, EntryPoint="Mono_Posix_Stdlib__IOLBF")]
226 private static extern int GetLineBuffered ();
228 [DllImport (MPH, EntryPoint="Mono_Posix_Stdlib__IONBF")]
229 private static extern int GetNonBuffered ();
231 [DllImport (MPH, EntryPoint="Mono_Posix_Stdlib_BUFSIZ")]
232 private static extern int GetBufferSize ();
234 [DllImport (MPH, EntryPoint="Mono_Posix_Stdlib_L_tmpnam")]
235 private static extern int GetTmpnamLength ();
237 [DllImport (MPH, EntryPoint="Mono_Posix_Stdlib_stdin")]
238 private static extern IntPtr GetStandardInput ();
240 [DllImport (MPH, EntryPoint="Mono_Posix_Stdlib_stdout")]
241 private static extern IntPtr GetStandardOutput ();
243 [DllImport (MPH, EntryPoint="Mono_Posix_Stdlib_stderr")]
244 private static extern IntPtr GetStandardError ();
246 public static readonly int _IOFBF = GetFullyBuffered ();
247 public static readonly int _IOLBF = GetLineBuffered ();
248 public static readonly int _IONBF = GetNonBuffered ();
249 public static readonly int BUFSIZ = GetBufferSize ();
250 public static readonly int L_tmpnam = GetTmpnamLength ();
251 public static readonly IntPtr stdin = GetStandardInput ();
252 public static readonly IntPtr stdout = GetStandardOutput ();
253 public static readonly IntPtr stderr = GetStandardError ();
255 [DllImport (LIBC, SetLastError=true)]
256 public static extern void perror (string s);
258 [DllImport (LIBC, SetLastError=true)]
259 public static extern int remove (string filename);
261 [DllImport (LIBC, SetLastError=true)]
262 public static extern int rename (string oldpath, string newpath);
264 [DllImport (LIBC, SetLastError=true)]
265 public static extern IntPtr tmpfile ();
267 [DllImport (LIBC, SetLastError=true, EntryPoint="tmpnam")]
268 private static extern IntPtr sys_tmpnam (StringBuilder s);
270 public static string tmpnam (StringBuilder s)
272 if (s != null && s.Capacity < L_tmpnam)
273 throw new ArgumentOutOfRangeException ("s", "s.Capacity < L_tmpnam");
274 IntPtr r = sys_tmpnam (s);
275 return UnixMarshal.PtrToString (r);
279 public static extern void clearerr (IntPtr stream);
281 [DllImport (LIBC, SetLastError=true)]
282 public static extern IntPtr fopen (string path, string mode);
284 [DllImport (LIBC, SetLastError=true)]
285 public static extern IntPtr fdopen (int filedes, string mode);
287 [DllImport (LIBC, SetLastError=true)]
288 public static extern void setbuf (IntPtr stream, IntPtr buf);
290 public static unsafe void setbuf (IntPtr stream, byte* buf)
292 setbuf (stream, (IntPtr) buf);
295 [DllImport (MPH, SetLastError=true,
296 EntryPoint="Mono_Posix_Stdlib_setvbuf")]
297 public static extern int setvbuf (IntPtr stream, IntPtr buf, int mode, ulong size);
299 public static unsafe int setvbuf (IntPtr stream, byte* buf, int mode, ulong size)
301 return setvbuf (stream, (IntPtr) buf, mode, size);
304 [DllImport (LIBC, SetLastError=true)]
305 public static extern IntPtr freopen (string path, string mode, IntPtr stream);
307 [DllImport (LIBC, SetLastError=true)]
308 public static extern int fclose (IntPtr stream);
310 [DllImport (LIBC, SetLastError=true)]
311 public static extern int fflush (IntPtr stream);
314 public static extern int feof (IntPtr stream);
317 public static extern int ferror (IntPtr stream);
319 [DllImport (LIBC, SetLastError=true)]
320 public static extern int fileno (IntPtr stream);
322 [DllImport (LIBC, EntryPoint="printf")]
323 private static extern int sys_printf (string format, string message);
325 public static int printf (string message)
327 return sys_printf ("%s", message);
330 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
331 "Use printf (string) instead.")]
332 public static int printf (string format, params object[] parameters)
334 object[] _parameters = new object[checked(parameters.Length+1)];
335 _parameters [0] = format;
336 Array.Copy (parameters, 0, _parameters, 1, parameters.Length);
337 return (int) XPrintfFunctions.printf (_parameters);
340 [DllImport (LIBC, EntryPoint="fprintf")]
341 private static extern int sys_fprintf (IntPtr stream, string format, string message);
343 public static int fprintf (IntPtr stream, string message)
345 return sys_fprintf (stream, "%s", message);
348 [Obsolete ("Not necessarily portable due to cdecl restrictions.\n" +
349 "Use fprintf (IntPtr, string) instead.")]
350 public static int fprintf (IntPtr stream, string format, params object[] parameters)
352 object[] _parameters = new object[checked(parameters.Length+2)];
353 _parameters [0] = stream;
354 _parameters [1] = format;
355 Array.Copy (parameters, 0, _parameters, 2, parameters.Length);
356 return (int) XPrintfFunctions.fprintf (_parameters);
359 [DllImport (LIBC, SetLastError=true)]
360 public static extern int fputc (int c, IntPtr stream);
362 [DllImport (LIBC, SetLastError=true)]
363 public static extern int fputs (string s, IntPtr stream);
365 [DllImport (LIBC, SetLastError=true)]
366 public static extern int putc (int c, IntPtr stream);
368 [DllImport (LIBC, SetLastError=true)]
369 public static extern int putchar (int c);
371 [DllImport (LIBC, SetLastError=true)]
372 public static extern int puts (string s);
374 [DllImport (LIBC, SetLastError=true)]
375 public static extern int fgetc (IntPtr stream);
377 [DllImport (LIBC, SetLastError=true, EntryPoint="fgets")]
378 private static extern IntPtr sys_fgets (StringBuilder sb, int size, IntPtr stream);
380 public static StringBuilder fgets (StringBuilder sb, int size, IntPtr stream)
382 IntPtr r = sys_fgets (sb, size, stream);
383 if (r == IntPtr.Zero)
388 public static StringBuilder fgets (StringBuilder sb, IntPtr stream)
390 return fgets (sb, sb.Capacity, stream);
393 [DllImport (LIBC, SetLastError=true)]
394 public static extern int getc (IntPtr stream);
396 [DllImport (LIBC, SetLastError=true)]
397 public static extern int getchar ();
399 // skip gets(3), it's evil.
401 [DllImport (LIBC, SetLastError=true)]
402 public static extern int ungetc (int c, IntPtr stream);
404 [DllImport (MPH, SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fread")]
405 public static extern unsafe ulong fread (void* ptr, ulong size, ulong nmemb, IntPtr stream);
407 [DllImport (MPH, SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fread")]
408 public static extern ulong fread ([Out] byte[] ptr, ulong size, ulong nmemb, IntPtr stream);
410 public static ulong fread (byte[] ptr, IntPtr stream)
412 return fread (ptr, 1, (ulong) ptr.Length, stream);
415 [DllImport (MPH, SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fwrite")]
416 public static extern unsafe ulong fwrite (void* ptr, ulong size, ulong nmemb, IntPtr stream);
418 [DllImport (MPH, SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fwrite")]
419 public static extern ulong fwrite (byte[] ptr, ulong size, ulong nmemb, IntPtr stream);
421 public static ulong fwrite (byte[] ptr, IntPtr stream)
423 return fwrite (ptr, 1, (ulong) ptr.Length, stream);
426 [DllImport (MPH, SetLastError=true,
427 EntryPoint="Mono_Posix_Stdlib_fseek")]
428 private static extern int sys_fseek (IntPtr stream, long offset, int origin);
430 public static int fseek (IntPtr stream, long offset, SeekFlags origin)
432 int _origin = UnixConvert.FromSeekFlags (origin);
433 return sys_fseek (stream, offset, _origin);
436 [DllImport (MPH, SetLastError=true,
437 EntryPoint="Mono_Posix_Stdlib_ftell")]
438 private static extern long ftell (IntPtr stream);
441 public static extern void rewind (IntPtr stream);
443 [DllImport (MPH, SetLastError=true,
444 EntryPoint="Mono_Posix_Stdlib_fgetpos")]
445 private static extern int sys_fgetpos (IntPtr stream, HandleRef pos);
447 public static int fgetpos (IntPtr stream, FilePosition pos)
449 return sys_fgetpos (stream, pos.Handle);
452 [DllImport (MPH, SetLastError=true,
453 EntryPoint="Mono_Posix_Stdlib_fsetpos")]
454 private static extern int sys_fsetpos (IntPtr stream, HandleRef pos);
456 public static int fsetpos (IntPtr stream, FilePosition pos)
458 return sys_fsetpos (stream, pos.Handle);
466 // void *calloc (size_t nmemb, size_t size);
467 [DllImport (MPH, SetLastError=true, EntryPoint="Mono_Posix_Stdlib_calloc")]
468 public static extern IntPtr calloc (ulong nmemb, ulong size);
471 public static extern void exit (int status);
474 public static extern void free (IntPtr ptr);
477 // void *malloc(size_t size);
478 [DllImport (MPH, SetLastError=true, EntryPoint="Mono_Posix_Stdlib_malloc")]
479 public static extern IntPtr malloc (ulong size);
482 // void *realloc(void *ptr, size_t size);
483 [DllImport (MPH, SetLastError=true, EntryPoint="Mono_Posix_Stdlib_realloc")]
484 public static extern IntPtr realloc (IntPtr ptr, ulong size);
486 [DllImport (MPH, SetLastError=true)]
487 public static extern int system (string @string);
493 [DllImport (LIBC, SetLastError=true, EntryPoint="strerror")]
494 private static extern IntPtr sys_strerror (int errnum);
496 public static IntPtr sys_strerror (Error errnum)
498 int e = UnixConvert.FromError (errnum);
499 return sys_strerror (e);
502 public static string strerror (Error errnum)
504 IntPtr r = sys_strerror (errnum);
505 return UnixMarshal.PtrToString (r);