(declare (block) (standard-bindings) (extended-bindings))
(begin
  (define std/os/fdio#fdread__%
    (lambda (_raw480_ _bytes481_ _start482_ _end483_)
      (let ((_fd485_ (if (std/os/fd#fd? _raw480_)
                         (std/os/fd#fd-e _raw480_)
                         _raw480_)))
        (let _lp487_ ()
          (let ((_r491_ (std/os/fdio#_read
                         _fd485_
                         _bytes481_
                         _start482_
                         _end483_)))
            (if (not (let () (declare (not safe)) (##fxnegative? _r491_)))
                _r491_
                (let ((_errno494_
                       (let () (declare (not safe)) (##fx- _r491_))))
                  (if (or (eq? _errno494_ std/os/error#EAGAIN)
                          (eq? _errno494_ std/os/error#EWOULDBLOCK))
                      '#f
                      (if (eq? _errno494_ std/os/error#EINTR)
                          (_lp487_)
                          (std/os/error#raise-os-error
                           _errno494_
                           std/os/fdio#fdread
                           _raw480_
                           _bytes481_
                           _start482_
                           _end483_))))))))))
  (define std/os/fdio#fdread__0
    (lambda (_raw503_ _bytes504_)
      (let* ((_start506_ '0) (_end508_ (u8vector-length _bytes504_)))
        (std/os/fdio#fdread__% _raw503_ _bytes504_ _start506_ _end508_))))
  (define std/os/fdio#fdread__1
    (lambda (_raw510_ _bytes511_ _start512_)
      (let ((_end514_ (u8vector-length _bytes511_)))
        (std/os/fdio#fdread__% _raw510_ _bytes511_ _start512_ _end514_))))
  (define std/os/fdio#fdread
    (lambda _g4120_
      (let ((_g4119_ (let () (declare (not safe)) (##length _g4120_))))
        (cond ((let () (declare (not safe)) (##fx= _g4119_ 2))
               (apply std/os/fdio#fdread__0 _g4120_))
              ((let () (declare (not safe)) (##fx= _g4119_ 3))
               (apply std/os/fdio#fdread__1 _g4120_))
              ((let () (declare (not safe)) (##fx= _g4119_ 4))
               (apply std/os/fdio#fdread__% _g4120_))
              (else
               (##raise-wrong-number-of-arguments-exception
                std/os/fdio#fdread
                _g4120_))))))
  (define std/os/fdio#fdwrite__%
    (lambda (_raw438_ _bytes439_ _start440_ _end441_)
      (let ((_fd443_ (if (std/os/fd#fd? _raw438_)
                         (std/os/fd#fd-e _raw438_)
                         _raw438_)))
        (let _lp445_ ()
          (let ((_r449_ (std/os/fdio#_write
                         _fd443_
                         _bytes439_
                         _start440_
                         _end441_)))
            (if (not (let () (declare (not safe)) (##fxnegative? _r449_)))
                _r449_
                (let ((_errno452_
                       (let () (declare (not safe)) (##fx- _r449_))))
                  (if (or (eq? _errno452_ std/os/error#EAGAIN)
                          (eq? _errno452_ std/os/error#EWOULDBLOCK))
                      '#f
                      (if (eq? _errno452_ std/os/error#EINTR)
                          (_lp445_)
                          (std/os/error#raise-os-error
                           _errno452_
                           std/os/fdio#fdwrite
                           _raw438_
                           _bytes439_
                           _start440_
                           _end441_))))))))))
  (define std/os/fdio#fdwrite__0
    (lambda (_raw461_ _bytes462_)
      (let* ((_start464_ '0) (_end466_ (u8vector-length _bytes462_)))
        (std/os/fdio#fdwrite__% _raw461_ _bytes462_ _start464_ _end466_))))
  (define std/os/fdio#fdwrite__1
    (lambda (_raw468_ _bytes469_ _start470_)
      (let ((_end472_ (u8vector-length _bytes469_)))
        (std/os/fdio#fdwrite__% _raw468_ _bytes469_ _start470_ _end472_))))
  (define std/os/fdio#fdwrite
    (lambda _g4122_
      (let ((_g4121_ (let () (declare (not safe)) (##length _g4122_))))
        (cond ((let () (declare (not safe)) (##fx= _g4121_ 2))
               (apply std/os/fdio#fdwrite__0 _g4122_))
              ((let () (declare (not safe)) (##fx= _g4121_ 3))
               (apply std/os/fdio#fdwrite__1 _g4122_))
              ((let () (declare (not safe)) (##fx= _g4121_ 4))
               (apply std/os/fdio#fdwrite__% _g4122_))
              (else
               (##raise-wrong-number-of-arguments-exception
                std/os/fdio#fdwrite
                _g4122_))))))
  (define std/os/fdio#open__%
    (lambda (_path413_ _flags414_ _mode415_)
      (let* ((_fd420_ (let ((_r417_ (std/os/fdio#_open
                                     _path413_
                                     _flags414_
                                     _mode415_)))
                        (if (not (let ()
                                   (declare (not safe))
                                   (##fxnegative? _r417_)))
                            _r417_
                            (std/os/error#raise-os-error
                             (let () (declare (not safe)) (##fx- _r417_))
                             std/os/fdio#open
                             _path413_
                             _flags414_
                             _mode415_))))
             (_raw422_
              (std/os/fd#fdopen
               _fd420_
               (std/os/fdio#file-direction _flags414_)
               'file)))
        (std/os/fcntl#fd-set-nonblock/closeonexec _raw422_)
        _raw422_)))
  (define std/os/fdio#open__0
    (lambda (_path428_ _flags429_)
      (let ((_mode431_ '0))
        (std/os/fdio#open__% _path428_ _flags429_ _mode431_))))
  (define std/os/fdio#open
    (lambda _g4124_
      (let ((_g4123_ (let () (declare (not safe)) (##length _g4124_))))
        (cond ((let () (declare (not safe)) (##fx= _g4123_ 2))
               (apply std/os/fdio#open__0 _g4124_))
              ((let () (declare (not safe)) (##fx= _g4123_ 3))
               (apply std/os/fdio#open__% _g4124_))
              (else
               (##raise-wrong-number-of-arguments-exception
                std/os/fdio#open
                _g4124_))))))
  (define std/os/fdio#close
    (lambda (_raw400_)
      (if (std/os/fd#fd? _raw400_)
          (close-port _raw400_)
          (let _lp402_ ()
            (let ((_r406_ (std/os/fdio#_close _raw400_)))
              (if (not (let () (declare (not safe)) (##fxnegative? _r406_)))
                  _r406_
                  (let ((_errno409_
                         (let () (declare (not safe)) (##fx- _r406_))))
                    (if '#f
                        '#f
                        (if (eq? _errno409_ std/os/error#EINTR)
                            (_lp402_)
                            (std/os/error#raise-os-error
                             _errno409_
                             std/os/fdio#close
                             _raw400_))))))))))
  (define std/os/fdio#file-direction
    (lambda (_flags398_)
      (if (let ((__tmp4125
                 (let ()
                   (declare (not safe))
                   (##fxand _flags398_ std/os/fcntl#O_RDWR))))
            (declare (not safe))
            (##fx= __tmp4125 std/os/fcntl#O_RDWR))
          'inout
          (if (let ((__tmp4126
                     (let ()
                       (declare (not safe))
                       (##fxand _flags398_ std/os/fcntl#O_RDONLY))))
                (declare (not safe))
                (##fx= __tmp4126 std/os/fcntl#O_RDONLY))
              'in
              (if (let ((__tmp4127
                         (let ()
                           (declare (not safe))
                           (##fxand _flags398_ std/os/fcntl#O_WRONLY))))
                    (declare (not safe))
                    (##fx= __tmp4127 std/os/fcntl#O_WRONLY))
                  'out
                  (error '"Unspecified file direction" _flags398_))))))
  (define-macro (define-guard guard defn)
    (if (eval `(cond-expand (,guard #t) (else #f)))
        '(begin)
        (begin (eval `(define-cond-expand-feature ,guard)) defn)))
  (define-macro (define-c-lambda id args ret #!optional (name #f))
    (let ((name (or name (symbol->string id))))
      `(define ,id (c-lambda ,args ,ret ,name))))
  (define-macro (define-const symbol)
    (let* ((str (symbol->string symbol))
           (ref (string-append "___return (" str ");")))
      `(define ,symbol ((c-lambda () int ,ref)))))
  (define-macro (define-const* symbol)
    (let* ((str (symbol->string symbol))
           (code (string-append
                  "#ifdef "
                  str
                  "\n"
                  "___return (___FIX ("
                  str
                  "));\n"
                  "#else \n"
                  "___return (___FAL);\n"
                  "#endif")))
      `(define ,symbol ((c-lambda () scheme-object ,code)))))
  (define-macro (define-with-errno symbol ffi-symbol args)
    `(define (,symbol ,@args)
       (declare (not interrupts-enabled))
       (let ((r (,ffi-symbol ,@args)))
         (if (##fx< r 0) (##fx- (##c-code "___RESULT = ___FIX (errno);")) r))))
  (define-macro (define-c-struct
                 struct
                 #!optional
                 (members '())
                 release-function)
    (let* ((struct-str (symbol->string struct))
           (struct-ptr (string->symbol (string-append struct-str "*")))
           (shallow-ptr
            (string->symbol (string-append struct-str "-shallow-ptr*")))
           (borrowed-ptr
            (string->symbol (string-append struct-str "-borrowed-ptr*")))
           (string-types
            '(char-string
              nonull-char-string
              UTF-8-string
              nonnull-UTF-8-string
              UTF-16-string
              nonnull-UTF16-string))
           (string-compat-required?
            (let loop ((m members))
              (cond ((null? m) #f)
                    ((member (cdr (car m)) string-types) #t)
                    (else (loop (cdr m))))))
           (string-setter-body
            (lambda (member-name)
              (let ((m (string-append "___arg1->" member-name)))
                (string-append
                 "if("
                 m
                 " == NULL)"
                 "\n"
                 m
                 "= strdup(___arg2);"
                 "\n"
                 "else if (strcmp("
                 m
                 ", ___arg2) != 0) {"
                 "\n"
                 "free("
                 m
                 ");"
                 "\n"
                 m
                 "= strdup(___arg2);"
                 "\n"
                 "}"
                 "\n"
                 "___return;"
                 "\n"))))
           (default-free-body
            (and string-compat-required?
                 (string-append
                  "___SCMOBJ "
                  struct-str
                  "_ffi_free (void *ptr) {"
                  "\n"
                  "struct "
                  struct-str
                  " *obj = (struct "
                  struct-str
                  "*) ptr;"
                  "\n"
                  (apply string-append
                         (map (lambda (m)
                                (cond ((memq (cdr m) string-types)
                                       (let ((mem-name
                                              (symbol->string (car m))))
                                         (string-append
                                          "if(obj->"
                                          mem-name
                                          ") "
                                          "free(obj->"
                                          mem-name
                                          ");"
                                          "\n")))
                                      (else "")))
                              members))
                  "free(obj);"
                  "\n"
                  "return ___FIX (___NO_ERR);"
                  "\n"
                  "}")))
           (release-function
            (or release-function
                (if string-compat-required?
                    (string-append struct-str "_ffi_free")
                    "ffi_free")))
           (string-compat-types
            (if string-compat-required?
                `((c-declare ,default-free-body)
                  (c-define-type
                   ,shallow-ptr
                   (pointer ,struct (,struct-ptr) "ffi_free")))
                '())))
      `(begin
         (c-define-type ,struct (struct ,struct-str))
         (c-define-type
          ,struct-ptr
          (pointer ,struct (,struct-ptr) ,release-function))
         (c-define-type ,borrowed-ptr (pointer ,struct (,struct-ptr)))
         ,@string-compat-types
         (define ,(string->symbol (string-append struct-str "-ptr?"))
           (lambda (obj)
             (and (foreign? obj) (equal? (foreign-tags obj) '(,struct-ptr)))))
         ,@(apply append
                  (map (lambda (m)
                         (let* ((member-name (symbol->string (car m)))
                                (member-type (cdr m))
                                (getter-name
                                 (string-append struct-str "-" member-name))
                                (setter-body
                                 (cond ((member member-type string-types)
                                        (string-setter-body member-name))
                                       (else
                                        (string-append
                                         "___arg1->"
                                         member-name
                                         " = ___arg2;"
                                         "\n"
                                         "___return;"
                                         "\n")))))
                           `((define ,(string->symbol getter-name)
                               (c-lambda
                                (,struct-ptr)
                                ,member-type
                                ,(string-append
                                  "___return(___arg1->"
                                  member-name
                                  ");")))
                             (define ,(string->symbol
                                       (string-append getter-name "-set!"))
                               (c-lambda
                                (,struct-ptr ,member-type)
                                void
                                ,setter-body)))))
                       members))
         (define ,(string->symbol (string-append "malloc-" struct-str))
           (c-lambda
            ()
            ,struct-ptr
            ,(string-append
              "struct "
              struct-str
              "* var = (struct "
              struct-str
              " *) malloc(sizeof(struct "
              struct-str
              "));"
              "\n"
              "if (var == NULL)"
              "\n"
              "    ___return (NULL);"
              "\n"
              "memset(var, 0, sizeof(struct "
              struct-str
              "));"
              "___return(var);")))
         (define ,(string->symbol (string-append "ptr->" struct-str))
           (c-lambda (,struct-ptr) ,struct "___return(*___arg1);"))
         (define ,(string->symbol
                   (string-append "malloc-" struct-str "-array"))
           (c-lambda
            (unsigned-int32)
            ,(if string-compat-required? shallow-ptr struct-ptr)
            ,(string-append
              "struct "
              struct-str
              " *arr_var=(struct "
              struct-str
              " *) malloc(___arg1*sizeof(struct "
              struct-str
              "));"
              "\n"
              "if (arr_var == NULL)"
              "\n"
              "    ___return (NULL);"
              "\n"
              "memset(arr_var, 0, ___arg1*sizeof(struct "
              struct-str
              "));"
              "\n"
              "___return(arr_var);")))
         (define ,(string->symbol (string-append struct-str "-array-ref"))
           (c-lambda
            (,struct-ptr unsigned-int32)
            ,borrowed-ptr
            "___return (___arg1 + ___arg2);"))
         (define ,(string->symbol (string-append struct-str "-array-set!"))
           (c-lambda
            (,struct-ptr unsigned-int32 ,struct-ptr)
            void
            "*(___arg1 + ___arg2) = *___arg3; ___return;")))))
  (c-declare "#include <stdlib.h>")
  (c-declare "#include <string.h>")
  (c-declare "#include <errno.h>")
  (c-declare "static ___SCMOBJ ffi_free (void *ptr);")
  (c-declare
   "#ifndef ___HAVE_FFI_U8VECTOR\n#define ___HAVE_FFI_U8VECTOR\n#define U8_DATA(obj) ___CAST (___U8*, ___BODY_AS (obj, ___tSUBTYPED))\n#define U8_LEN(obj) ___HD_BYTES (___HEADER (obj))\n#endif")
  (namespace
   ("std/os/fdio#"
    S_IXOTH
    S_IWOTH
    S_IROTH
    S_IRWXO
    S_IXGRP
    S_IWGRP
    S_IRGRP
    S_IRWXG
    S_IXUSR
    S_IRUSR
    S_IWUSR
    S_IRWXU
    _close
    _open
    _write
    _read))
  (c-declare "#include <unistd.h>")
  (c-declare "#include <sys/types.h>")
  (c-declare "#include <sys/stat.h>")
  (c-declare "#include <fcntl.h>")
  (define-const S_IRWXU)
  (define-const S_IRUSR)
  (define-const S_IWUSR)
  (define-const S_IXUSR)
  (define-const S_IRWXG)
  (define-const S_IRGRP)
  (define-const S_IWGRP)
  (define-const S_IXGRP)
  (define-const S_IRWXO)
  (define-const S_IROTH)
  (define-const S_IWOTH)
  (define-const S_IXOTH)
  (namespace ("std/os/fdio#" __read __write __open __close))
  (c-declare
   "static int ffi_fdio_read (int fd, ___SCMOBJ bytes, int start, int end);")
  (c-declare
   "static int ffi_fdio_write (int fd, ___SCMOBJ bytes, int start, int end);")
  (define-c-lambda __read (int scheme-object int int) int "ffi_fdio_read")
  (define-c-lambda __write (int scheme-object int int) int "ffi_fdio_write")
  (define-c-lambda __open (UTF-8-string int int) int "open")
  (define-c-lambda __close (int) int "close")
  (define-with-errno _read __read (fd bytes start end))
  (define-with-errno _write __write (fd bytes start end))
  (define-with-errno _open __open (path flags mode))
  (define-with-errno _close __close (fd))
  (c-declare
   "int ffi_fdio_read (int fd, ___SCMOBJ bytes, int start, int end)\n{\n return read (fd, U8_DATA (bytes) + start, end - start);\n}\n\nint ffi_fdio_write (int fd, ___SCMOBJ bytes, int start, int end)\n{\n return write (fd, U8_DATA (bytes) + start, end - start);\n}\n")
  (c-declare
   "#ifndef ___HAVE_FFI_FREE\n#define ___HAVE_FFI_FREE\n___SCMOBJ ffi_free (void *ptr)\n{\n free (ptr);\n return ___FIX (___NO_ERR);\n}\n#endif"))
