(declare (block) (standard-bindings) (extended-bindings))
(begin
  (define std/os/signal#kill
    (lambda (_pid405_ _signo406_)
      (let ((_r408_ (std/os/signal#_kill _pid405_ _signo406_)))
        (if (not (let () (declare (not safe)) (##fxnegative? _r408_)))
            _r408_
            (std/os/error#raise-os-error
             (let () (declare (not safe)) (##fx- _r408_))
             std/os/signal#kill
             _pid405_
             _signo406_)))))
  (define std/os/signal#sigprocmask
    (lambda (_how398_ _sigset399_ _old-sigset400_)
      (let ((_r402_ (std/os/signal#_sigprocmask
                     _how398_
                     _sigset399_
                     _old-sigset400_)))
        (if (not (let () (declare (not safe)) (##fxnegative? _r402_)))
            _r402_
            (std/os/error#raise-os-error
             (let () (declare (not safe)) (##fx- _r402_))
             std/os/signal#sigprocmask
             _how398_
             _sigset399_
             _old-sigset400_)))))
  (define-cond-expand-feature bsd)
  (define-cond-expand-feature openbsd)
  (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/signal#"
    sigismember
    sigdelset
    sigaddset
    sigfillset
    sigemptyset
    make_sigset
    _sigprocmask
    _kill))
  (c-declare "#include <sys/types.h>")
  (c-declare "#include <signal.h>")
  (namespace
   ("std/os/signal#"
    SIGHUP
    SIGINT
    SIGQUIT
    SIGILL
    SIGTRAP
    SIGABRT
    SIGBUS
    SIGFPE
    SIGKILL
    SIGUSR1
    SIGSEGV
    SIGUSR2
    SIGPIPE
    SIGALRM
    SIGTERM
    SIGCHLD
    SIGCONT
    SIGSTOP
    SIGTSTP
    SIGTTIN
    SIGTTOU
    SIGURG
    SIGXCPU
    SIGXFSZ
    SIGVTALRM
    SIGPROF
    SIGWINCH
    SIGIO
    SIGSYS
    SIGSTKFLT
    SIGPOLL
    SIGPWR
    SIGIOT
    SIGRTMIN
    SIGRTMAX
    SIGEMT
    SIGINFO
    NSIG
    SIGTHR
    SIGPWR
    SIG_BLOCK
    SIG_UNBLOCK
    SIG_SETMASK
    __kill
    __sigprocmask))
  (define-const SIGHUP)
  (define-const SIGINT)
  (define-const SIGQUIT)
  (define-const SIGILL)
  (define-const SIGTRAP)
  (define-const SIGABRT)
  (define-const SIGBUS)
  (define-const SIGFPE)
  (define-const SIGKILL)
  (define-const SIGUSR1)
  (define-const SIGSEGV)
  (define-const SIGUSR2)
  (define-const SIGPIPE)
  (define-const SIGALRM)
  (define-const SIGTERM)
  (define-const SIGCHLD)
  (define-const SIGCONT)
  (define-const SIGSTOP)
  (define-const SIGTSTP)
  (define-const SIGTTIN)
  (define-const SIGTTOU)
  (define-const SIGURG)
  (define-const SIGXCPU)
  (define-const SIGXFSZ)
  (define-const SIGVTALRM)
  (define-const SIGPROF)
  (define-const SIGWINCH)
  (define-const SIGIO)
  (define-const SIGSYS)
  (define-const SIG_BLOCK)
  (define-const SIG_UNBLOCK)
  (define-const SIG_SETMASK)
  (cond-expand
   (linux (define-const SIGIOT)
          (define-const SIGSTKFLT)
          (define-const SIGPOLL)
          (define-const SIGPWR)
          (define-const SIGRTMIN)
          (define-const SIGRTMAX))
   (bsd (define-const SIGEMT) (define-const SIGINFO) (define-const NSIG))
   (else))
  (cond-expand
   (openbsd (define-const SIGTHR))
   (netbsd (define-const SIGPWR))
   (freebsd)
   (darwin)
   (linux)
   (else))
  (define-c-lambda __kill (int int) int "kill")
  (define-with-errno _kill __kill (pid signo))
  (define-guard ffi-have-sigset (c-define-type sigset_t "sigset_t"))
  (define-guard
   ffi-have-sigset*
   (c-define-type sigset_t* (pointer "sigset_t" (sigset_t*) "ffi_free")))
  (define-c-lambda __sigprocmask (int sigset_t* sigset_t*) int "sigprocmask")
  (define-with-errno _sigprocmask __sigprocmask (how sigset old-sigset))
  (define-c-lambda
   make_sigset
   ()
   sigset_t*
   "___return ((sigset_t*) malloc (sizeof (sigset_t))); ")
  (define-c-lambda sigemptyset (sigset_t*) int)
  (define-c-lambda sigfillset (sigset_t*) int)
  (define-c-lambda sigaddset (sigset_t* int) int)
  (define-c-lambda sigdelset (sigset_t* int) int)
  (define-c-lambda sigismember (sigset_t* int) int)
  (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")
  (define std/os/signal#SIGMAX std/os/signal#NSIG))
