#line 251 "/home/travis/build/felix-lang/felix/src/packages/program.fdoc"
  
  open class Errno
  {
    pod type errno_t = "int" requires C89_headers::errno_h;
    ctor int : errno_t = "$1";
    ctor errno_t : int = "$1";
    instance Eq[errno_t] {
      fun == : errno_t * errno_t -> bool= "$1==$2";
    }
    inherit Eq[errno_t];
  
    const errno : errno_t = "errno"; // SUCKS
    const ENOERROR : errno_t = "0";
    const EACCES: errno_t;
    const ENOENT: errno_t;
    const EAGAIN: errno_t;
    const ENOMEM: errno_t;
    const EEXIST: errno_t;
    const EINVAL: errno_t;
    const EINTR: errno_t; // call interrupted by a signal
  
    proc maybe_exit(var n:int) { if n != 0 do System::exit(errno.int); done }
    proc maybe_exit(var n:errno_t) { if n != ENOERROR  do System::exit(n.int); done }
    proc maybe_exit() { if errno != ENOERROR do System::exit(errno.int); done }
  
    // Unfortunately we get the crappy GNU version of strerror_r
    // even if we don't define _GNU_SOURCE
    // This stupidity returns a char*, instead of a void.
    // Unfortunately moron compilers complain about not using
    // the returned result, but there is no legal way to use a void.
    // There is no way out.
  
  if PLAT_WIN32 do
    proc strerror_r: errno_t *  carray[char] * size  = "(void)strerror_s($2, $3, $1);"
      requires C89_headers::string_h /* on Linux.. on OSX it's in stdio.h */
    ;
  else
    proc strerror_r: errno_t * carray[char] * size  =
      """
      strerror_r($1, $2, $3);
      """
      requires C89_headers::string_h
    ;
  done
    fun strerror(e:errno_t) : string = {
      if e.int == 0 do
        return "OK";
      else
        var b:array[char,1000];
        var bad = "[strerror_r] Failed to find text for error number " + e.int.str;
        strncpy (carray (&b),bad._unsafe_cstr,1000.size); // safe because bad is a variable
        strerror_r(e,carray (&b), b.len.size);
        return string( carray (&b));
      done
    }
  
    gen strerror()=> strerror errno;
  
    instance Str[errno_t] { fun str (e:errno_t) => strerror e; }
    inherit Str[errno_t];
  
    // Auto error check support
    class Check[T]
    {
      proc int_to_proc (var x:int) { if x == -1 do ehandler; done }
      fun int_to_int (var x:int) = { if x == -1 do ehandler; done return x; }
      fun pointer_to_pointer[U] (var p:&U) = { if C_hack::isNULL p do #ehandler; done return p; }
      virtual fun ehandler: unit -> any;
    }
  
    type check_ignore = "";
    instance Check[check_ignore]
    {
      fun ehandler ():any = {}
    }
    type check_throw = "";
    instance Check[check_throw]
    {
      fun ehandler ():any = { raise #strerror; }
    }
  }