/* Automatically generated by chibi-ffi; version: 0.4 */

#include <chibi/eval.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <signal.h>

#include <unistd.h>
/*  signal.c -- process signals interface                     */
/*  Copyright (c) 2009-2011 Alex Shinn.  All rights reserved. */
/*  BSD-style license: http://synthcode.com/license.txt       */

#define SEXP_MAX_SIGNUM 32

static sexp sexp_signal_contexts[SEXP_MAX_SIGNUM];

static struct sigaction call_sigaction, call_sigdefault, call_sigignore;

static void sexp_call_sigaction (int signum, siginfo_t *info, void *uctx) {
  sexp ctx;
#if ! SEXP_USE_GREEN_THREADS
  sexp sigctx, handler;
  sexp_gc_var1(args);
#endif
  ctx = sexp_signal_contexts[signum];
  if (ctx) {
#if SEXP_USE_GREEN_THREADS
    sexp_global(ctx, SEXP_G_THREADS_SIGNALS) =
      sexp_make_fixnum((1UL<<signum) | sexp_unbox_fixnum(sexp_global(ctx, SEXP_G_THREADS_SIGNALS)));
#else
    handler = sexp_vector_ref(sexp_global(ctx, SEXP_G_SIGNAL_HANDLERS),
                              sexp_make_fixnum(signum));
    if (sexp_applicablep(handler)) {
      sigctx = sexp_make_child_context(ctx, NULL);
      sexp_gc_preserve1(sigctx, args);
      args = sexp_cons(sigctx, sexp_make_fixnum(signum), SEXP_NULL);
      sexp_apply(sigctx, handler, args);
      sexp_gc_release1(sigctx);
    }
#endif
  }
}

static sexp sexp_set_signal_action (sexp ctx, sexp self, sexp signum, sexp newaction) {
  int res;
  sexp oldaction;
  if (! (sexp_fixnump(signum) && sexp_unbox_fixnum(signum) > 0
         && sexp_unbox_fixnum(signum) < SEXP_MAX_SIGNUM))
    return sexp_xtype_exception(ctx, self, "not a valid signal number", signum);
  if (! (sexp_procedurep(newaction) || sexp_opcodep(newaction)
         || sexp_booleanp(newaction)))
    return sexp_type_exception(ctx, self, SEXP_PROCEDURE, newaction);
  if (! sexp_vectorp(sexp_global(ctx, SEXP_G_SIGNAL_HANDLERS)))
    sexp_global(ctx, SEXP_G_SIGNAL_HANDLERS)
      = sexp_make_vector(ctx, sexp_make_fixnum(SEXP_MAX_SIGNUM), SEXP_FALSE);
  oldaction = sexp_vector_ref(sexp_global(ctx, SEXP_G_SIGNAL_HANDLERS), signum);
  res = sigaction(sexp_unbox_fixnum(signum),
                  (sexp_booleanp(newaction) ?
                   (sexp_truep(newaction) ? &call_sigdefault : &call_sigignore)
                   : &call_sigaction),
                  NULL);
  if (res)
    return sexp_user_exception(ctx, self, "couldn't set signal", signum);
  sexp_vector_set(sexp_global(ctx, SEXP_G_SIGNAL_HANDLERS), signum, newaction);
  sexp_signal_contexts[sexp_unbox_fixnum(signum)] = ctx;
  return oldaction;
}

#if SEXP_BSD

#include <sys/time.h>
#ifndef __DragonFly__
#include <sys/param.h>
#include <sys/proc.h>
#endif
#include <sys/sysctl.h>
#ifndef __NetBSD__
#include <sys/user.h>
#endif

static sexp sexp_pid_cmdline (sexp ctx, int pid) {
#ifdef __NetBSD__
  /*
   * Newer version with defined interface that doesn't expose kernel
   * guts and works with 64-bit kernel, 32-bit userland.
   */
  struct kinfo_proc2 res;
  int id = KERN_PROC2;
#else
  struct kinfo_proc res;
  int id = KERN_PROC;
#endif
  size_t reslen = sizeof(res);
#if defined(__NetBSD__) || defined(__OpenBSD__)
  int name[6] = {CTL_KERN, id, KERN_PROC_PID, pid, reslen, 1};
  unsigned namelen = 6;
#else
  int name[4] = {CTL_KERN, id, KERN_PROC_PID, pid};
  unsigned namelen = 4;
#endif
  if (sysctl(name, namelen, &res, &reslen, NULL, 0) >= 0 && reslen > 0) {
#if defined(__APPLE__)
    return sexp_c_string(ctx, res.kp_proc.p_comm, -1);
#elif defined(__NetBSD__) || defined(__OpenBSD__)
    return sexp_c_string(ctx, res.p_comm, -1);
#elif __DragonFly__
    return sexp_c_string(ctx, res.kp_comm, -1);
#else
    return sexp_c_string(ctx, res.ki_comm, -1);
#endif
  } else {
    return SEXP_FALSE;
  }
}

#else

/* #include <sys/syscall.h> */
/* #include <linux/sysctl.h> */

/* #define CMDLINE_LENGTH 512 */

/* static sexp sexp_pid_cmdline (sexp ctx, int pid) { */
/*   struct __sysctl_args args; */
/*   char cmdline[CMDLINE_LENGTH]; */
/*   size_t cmdline_length; */
/*   int name[] = { CTL_KERN, KERN_OSTYPE }; */

/*   memset(&args, 0, sizeof(struct __sysctl_args)); */
/*   args.name = name; */
/*   args.nlen = sizeof(name)/sizeof(name[0]); */
/*   args.oldval = cmdline; */
/*   args.oldlenp = &cmdline_length; */
/*   cmdline_length = sizeof(cmdline); */

/*   if (syscall(SYS__sysctl, &args) == -1) { */
/*     return SEXP_FALSE; */
/*   } else { */
/*     return sexp_c_string(ctx, cmdline, -1); */
/*   } */
/* } */

#endif

static pid_t sexp_fork_and_kill_threads (sexp ctx) {
  pid_t res = fork();
#if SEXP_USE_GREEN_THREADS
  if (res == 0) {               /* child */
    sexp_global(ctx, SEXP_G_THREADS_FRONT) = SEXP_NULL;
    sexp_global(ctx, SEXP_G_THREADS_BACK) = SEXP_NULL;
    sexp_global(ctx, SEXP_G_THREADS_PAUSED) = SEXP_NULL;
  }
#endif
  return res;
}

static void sexp_init_signals (sexp ctx, sexp env) {
  call_sigaction.sa_sigaction  = sexp_call_sigaction;
#if SEXP_USE_GREEN_THREADS
  call_sigaction.sa_flags      = SA_SIGINFO | SA_RESTART /* | SA_NODEFER */;
  sigfillset(&call_sigaction.sa_mask);
#else
  call_sigaction.sa_flags      = SA_SIGINFO | SA_RESTART | SA_NODEFER;
#endif
  call_sigdefault.sa_handler   = SIG_DFL;
  call_sigignore.sa_handler    = SIG_IGN;
  memset(sexp_signal_contexts, 0, sizeof(sexp_signal_contexts));
}
/*
types: (sigset_t siginfo_t)
enums: ()
*/

sexp sexp_25_process_command_line_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg1) {
  sexp res;
  if (! sexp_exact_integerp(arg1))
    return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg1);
  res = sexp_pid_cmdline(ctx, sexp_sint_value(arg1));
  return res;
}

sexp sexp_parent_process_id_stub (sexp ctx, sexp self, sexp_sint_t n) {
  sexp res;
  res = sexp_make_unsigned_integer(ctx, getppid());
  return res;
}

sexp sexp_current_process_id_stub (sexp ctx, sexp self, sexp_sint_t n) {
  sexp res;
  res = sexp_make_unsigned_integer(ctx, getpid());
  return res;
}

sexp sexp_execvp_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0, sexp arg1) {
  int i = 0;
  char* *tmp1;
  sexp res;
  if (! sexp_stringp(arg0))
    return sexp_type_exception(ctx, self, SEXP_STRING, arg0);
  for (res=arg1; sexp_pairp(res); res=sexp_cdr(res))
    if (! sexp_stringp(sexp_car(res)))
      return sexp_xtype_exception(ctx, self, "not a list of strings", arg1);
  if (! sexp_nullp(res))
    return sexp_xtype_exception(ctx, self, "not a list of strings", arg1);
  tmp1 = (char**) calloc((sexp_unbox_fixnum(sexp_length(ctx, arg1))+1), sizeof(tmp1[0]));
  for (i=0, res=arg1; sexp_pairp(res); res=sexp_cdr(res), i++) {
    tmp1[i] = sexp_string_data(sexp_car(res));
  }
  tmp1[i] = 0;
  res = sexp_make_integer(ctx, execvp(sexp_string_data(arg0), tmp1));
  free(tmp1);
  return res;
}

sexp sexp_25_exit_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0) {
  sexp res;
  if (! sexp_exact_integerp(arg0))
    return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg0);
  res = ((exit(sexp_sint_value(arg0))), SEXP_VOID);
  return res;
}

sexp sexp_kill_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0, sexp arg1) {
  int err = 0;
  sexp res;
  if (! sexp_exact_integerp(arg0))
    return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg0);
  if (! sexp_exact_integerp(arg1))
    return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg1);
  err = kill(sexp_sint_value(arg0), sexp_sint_value(arg1));
  if (err) {
  res = SEXP_FALSE;
  } else {
  res = SEXP_TRUE;
  }
  return res;
}

sexp sexp_waitpid_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0, sexp arg2) {
  int tmp1;
  sexp_gc_var2(res, res1);
  if (! sexp_exact_integerp(arg0))
    return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg0);
  if (! sexp_exact_integerp(arg2))
    return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg2);
  sexp_gc_preserve2(ctx, res, res1);
  res = sexp_make_unsigned_integer(ctx, waitpid(sexp_sint_value(arg0), &tmp1, sexp_sint_value(arg2)));
  res1 = sexp_make_integer(ctx, tmp1);
  res = sexp_cons(ctx, res, SEXP_NULL);
  sexp_push(ctx, res, sexp_car(res));
  sexp_cadr(res) = res1;
  sexp_gc_release2(ctx);
  return res;
}

sexp sexp_fork_stub (sexp ctx, sexp self, sexp_sint_t n) {
  sexp res;
  res = sexp_make_unsigned_integer(ctx, sexp_fork_and_kill_threads(ctx));
  return res;
}

sexp sexp_25_fork_stub (sexp ctx, sexp self, sexp_sint_t n) {
  sexp res;
  res = sexp_make_unsigned_integer(ctx, fork());
  return res;
}

sexp sexp_sleep_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0) {
  sexp res;
  if (! sexp_exact_integerp(arg0))
    return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg0);
  res = sexp_make_unsigned_integer(ctx, sleep(sexp_uint_value(arg0)));
  return res;
}

sexp sexp_alarm_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0) {
  sexp res;
  if (! sexp_exact_integerp(arg0))
    return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg0);
  res = sexp_make_unsigned_integer(ctx, alarm(sexp_uint_value(arg0)));
  return res;
}

sexp sexp_current_signal_mask_stub (sexp ctx, sexp self, sexp_sint_t n) {
  int err = 0;
  sigset_t *tmp2;
  sexp res;
  sexp_gc_var1(res2);
  sexp_gc_preserve1(ctx, res2);
  tmp2 = (sigset_t*) calloc(1, 1 + sizeof(tmp2[0]));
  err = sigprocmask(SIG_BLOCK, NULL, tmp2);
  if (err) {
  res = SEXP_FALSE;
  } else {
  res2 = sexp_make_cpointer(ctx, sexp_unbox_fixnum(sexp_opcode_arg3_type(self)), tmp2, SEXP_FALSE, 1);
  res = res2;
  }
  sexp_gc_release1(ctx);
  return res;
}

sexp sexp_signal_mask_set_x_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg1) {
  int err = 0;
  sexp res;
  if (! (sexp_pointerp(arg1) && (sexp_pointer_tag(arg1) == sexp_unbox_fixnum(sexp_opcode_arg2_type(self)))))
    return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg2_type(self)), arg1);
  err = sigprocmask(SIG_SETMASK, (sigset_t*)sexp_cpointer_value(arg1), NULL);
  if (err) {
  res = SEXP_FALSE;
  } else {
  res = SEXP_TRUE;
  }
  return res;
}

sexp sexp_signal_mask_unblock_x_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg1) {
  int err = 0;
  sexp res;
  if (! (sexp_pointerp(arg1) && (sexp_pointer_tag(arg1) == sexp_unbox_fixnum(sexp_opcode_arg2_type(self)))))
    return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg2_type(self)), arg1);
  err = sigprocmask(SIG_UNBLOCK, (sigset_t*)sexp_cpointer_value(arg1), NULL);
  if (err) {
  res = SEXP_FALSE;
  } else {
  res = SEXP_TRUE;
  }
  return res;
}

sexp sexp_signal_mask_block_x_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg1) {
  int err = 0;
  sexp res;
  if (! (sexp_pointerp(arg1) && (sexp_pointer_tag(arg1) == sexp_unbox_fixnum(sexp_opcode_arg2_type(self)))))
    return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg2_type(self)), arg1);
  err = sigprocmask(SIG_BLOCK, (sigset_t*)sexp_cpointer_value(arg1), NULL);
  if (err) {
  res = SEXP_FALSE;
  } else {
  res = SEXP_TRUE;
  }
  return res;
}

sexp sexp_signal_set_contains_p_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0, sexp arg1) {
  sexp res;
  if (! (sexp_pointerp(arg0) && (sexp_pointer_tag(arg0) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self)))))
    return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), arg0);
  if (! sexp_exact_integerp(arg1))
    return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg1);
  res = sexp_make_boolean(sigismember((sigset_t*)sexp_cpointer_value(arg0), sexp_sint_value(arg1)));
  return res;
}

sexp sexp_signal_set_delete_x_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0, sexp arg1) {
  int err = 0;
  sexp res;
  if (! (sexp_pointerp(arg0) && (sexp_pointer_tag(arg0) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self)))))
    return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), arg0);
  if (! sexp_exact_integerp(arg1))
    return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg1);
  err = sigdelset((sigset_t*)sexp_cpointer_value(arg0), sexp_sint_value(arg1));
  if (err) {
  res = SEXP_FALSE;
  } else {
  res = SEXP_TRUE;
  }
  return res;
}

sexp sexp_signal_set_add_x_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0, sexp arg1) {
  int err = 0;
  sexp res;
  if (! (sexp_pointerp(arg0) && (sexp_pointer_tag(arg0) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self)))))
    return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), arg0);
  if (! sexp_exact_integerp(arg1))
    return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg1);
  err = sigaddset((sigset_t*)sexp_cpointer_value(arg0), sexp_sint_value(arg1));
  if (err) {
  res = SEXP_FALSE;
  } else {
  res = SEXP_TRUE;
  }
  return res;
}

sexp sexp_signal_set_fill_x_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0) {
  int err = 0;
  sexp res;
  if (! (sexp_pointerp(arg0) && (sexp_pointer_tag(arg0) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self)))))
    return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), arg0);
  err = sigfillset((sigset_t*)sexp_cpointer_value(arg0));
  if (err) {
  res = SEXP_FALSE;
  } else {
  res = SEXP_TRUE;
  }
  return res;
}

sexp sexp_make_signal_set_stub (sexp ctx, sexp self, sexp_sint_t n) {
  int err = 0;
  sigset_t *tmp0;
  sexp res;
  sexp_gc_var1(res0);
  sexp_gc_preserve1(ctx, res0);
  tmp0 = (sigset_t*) calloc(1, 1 + sizeof(tmp0[0]));
  err = sigemptyset(tmp0);
  if (err) {
  res = SEXP_FALSE;
  } else {
  res0 = sexp_make_cpointer(ctx, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), tmp0, SEXP_FALSE, 1);
  res = res0;
  }
  sexp_gc_release1(ctx);
  return res;
}

sexp sexp_set_signal_action_x_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg2, sexp arg3) {
  sexp res;
  res = sexp_set_signal_action(ctx, self, arg2, arg3);
  return res;
}

sexp sexp_siginfo_t_get_si_signo (sexp ctx, sexp self, sexp_sint_t n, sexp x) {
  if (! (sexp_pointerp(x) && (sexp_pointer_tag(x) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self)))))
    return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), x);
  return sexp_make_integer(ctx, (( siginfo_t*)sexp_cpointer_value(x))->si_signo);
}

sexp sexp_siginfo_t_get_si_errno (sexp ctx, sexp self, sexp_sint_t n, sexp x) {
  if (! (sexp_pointerp(x) && (sexp_pointer_tag(x) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self)))))
    return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), x);
  return sexp_make_integer(ctx, (( siginfo_t*)sexp_cpointer_value(x))->si_errno);
}

sexp sexp_siginfo_t_get_si_code (sexp ctx, sexp self, sexp_sint_t n, sexp x) {
  if (! (sexp_pointerp(x) && (sexp_pointer_tag(x) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self)))))
    return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), x);
  return sexp_make_integer(ctx, (( siginfo_t*)sexp_cpointer_value(x))->si_code);
}

sexp sexp_siginfo_t_get_si_pid (sexp ctx, sexp self, sexp_sint_t n, sexp x) {
  if (! (sexp_pointerp(x) && (sexp_pointer_tag(x) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self)))))
    return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), x);
  return sexp_make_unsigned_integer(ctx, (( siginfo_t*)sexp_cpointer_value(x))->si_pid);
}

sexp sexp_siginfo_t_get_si_uid (sexp ctx, sexp self, sexp_sint_t n, sexp x) {
  if (! (sexp_pointerp(x) && (sexp_pointer_tag(x) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self)))))
    return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), x);
  return sexp_make_unsigned_integer(ctx, (( siginfo_t*)sexp_cpointer_value(x))->si_uid);
}

sexp sexp_siginfo_t_get_si_status (sexp ctx, sexp self, sexp_sint_t n, sexp x) {
  if (! (sexp_pointerp(x) && (sexp_pointer_tag(x) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self)))))
    return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), x);
  return sexp_make_integer(ctx, (( siginfo_t*)sexp_cpointer_value(x))->si_status);
}


sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, const sexp_abi_identifier_t abi) {
  sexp sexp_sigset_t_type_obj;
  sexp sexp_siginfo_t_type_obj;
  sexp_gc_var3(name, tmp, op);
  if (!(sexp_version_compatible(ctx, version, sexp_version)
        && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER)))
    return SEXP_ABI_ERROR;
  sexp_gc_preserve3(ctx, name, tmp, op);
  name = sexp_intern(ctx, "wait/no-hang", 12);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, WNOHANG));
  name = sexp_intern(ctx, "signal/tty-output", 17);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGTTOU));
  name = sexp_intern(ctx, "signal/tty-input", 16);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGTTIN));
  name = sexp_intern(ctx, "signal/tty-stop", 15);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGTSTP));
  name = sexp_intern(ctx, "signal/stop", 11);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGSTOP));
  name = sexp_intern(ctx, "signal/continue", 15);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGCONT));
  name = sexp_intern(ctx, "signal/child", 12);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGCHLD));
  name = sexp_intern(ctx, "signal/user2", 12);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGUSR2));
  name = sexp_intern(ctx, "signal/user1", 12);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGUSR1));
  name = sexp_intern(ctx, "signal/term", 11);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGTERM));
  name = sexp_intern(ctx, "signal/alarm", 12);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGALRM));
  name = sexp_intern(ctx, "signal/pipe", 11);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGPIPE));
  name = sexp_intern(ctx, "signal/segv", 11);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGSEGV));
  name = sexp_intern(ctx, "signal/kill", 11);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGKILL));
  name = sexp_intern(ctx, "signal/fpe", 10);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGFPE));
  name = sexp_intern(ctx, "signal/abort", 12);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGABRT));
  name = sexp_intern(ctx, "signal/illegal", 14);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGILL));
  name = sexp_intern(ctx, "signal/quit", 11);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGQUIT));
  name = sexp_intern(ctx, "signal/interrupt", 16);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGINT));
  name = sexp_intern(ctx, "signal/hang-up", 14);
  sexp_env_define(ctx, env, name, tmp=sexp_make_integer(ctx, SIGHUP));
  name = sexp_c_string(ctx, "sigset_t", -1);
  sexp_sigset_t_type_obj = sexp_register_c_type(ctx, name, sexp_finalize_c_type);
  tmp = sexp_string_to_symbol(ctx, name);
  sexp_env_define(ctx, env, tmp, sexp_sigset_t_type_obj);
  tmp = sexp_make_type_predicate(ctx, name, sexp_sigset_t_type_obj);
  name = sexp_intern(ctx, "signal-set?", 11);
  sexp_env_define(ctx, env, name, tmp);
  name = sexp_c_string(ctx, "siginfo_t", -1);
  sexp_siginfo_t_type_obj = sexp_register_c_type(ctx, name, sexp_finalize_c_type);
  tmp = sexp_string_to_symbol(ctx, name);
  sexp_env_define(ctx, env, tmp, sexp_siginfo_t_type_obj);
  sexp_type_slots(sexp_siginfo_t_type_obj) = SEXP_NULL;
  sexp_push(ctx, sexp_type_slots(sexp_siginfo_t_type_obj), sexp_intern(ctx, "si_status", -1));
  sexp_push(ctx, sexp_type_slots(sexp_siginfo_t_type_obj), sexp_intern(ctx, "si_uid", -1));
  sexp_push(ctx, sexp_type_slots(sexp_siginfo_t_type_obj), sexp_intern(ctx, "si_pid", -1));
  sexp_push(ctx, sexp_type_slots(sexp_siginfo_t_type_obj), sexp_intern(ctx, "si_code", -1));
  sexp_push(ctx, sexp_type_slots(sexp_siginfo_t_type_obj), sexp_intern(ctx, "si_errno", -1));
  sexp_push(ctx, sexp_type_slots(sexp_siginfo_t_type_obj), sexp_intern(ctx, "si_signo", -1));
  sexp_type_getters(sexp_siginfo_t_type_obj) = sexp_make_vector(ctx, SEXP_SIX, SEXP_FALSE);
  sexp_type_setters(sexp_siginfo_t_type_obj) = sexp_make_vector(ctx, SEXP_SIX, SEXP_FALSE);
  tmp = sexp_make_type_predicate(ctx, name, sexp_siginfo_t_type_obj);
  name = sexp_intern(ctx, "signal-info?", 12);
  sexp_env_define(ctx, env, name, tmp);
  op = sexp_define_foreign(ctx, env, "signal-status", 1, sexp_siginfo_t_get_si_status);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_siginfo_t_type_obj));
  }
  op = sexp_define_foreign(ctx, env, "signal-uid", 1, sexp_siginfo_t_get_si_uid);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_siginfo_t_type_obj));
  }
  op = sexp_define_foreign(ctx, env, "signal-pid", 1, sexp_siginfo_t_get_si_pid);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_siginfo_t_type_obj));
  }
  op = sexp_define_foreign(ctx, env, "signal-code", 1, sexp_siginfo_t_get_si_code);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_siginfo_t_type_obj));
  }
  op = sexp_define_foreign(ctx, env, "signal-error-number", 1, sexp_siginfo_t_get_si_errno);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_siginfo_t_type_obj));
  }
  op = sexp_define_foreign(ctx, env, "signal-number", 1, sexp_siginfo_t_get_si_signo);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_siginfo_t_type_obj));
  }
  op = sexp_define_foreign(ctx, env, "%process-command-line", 1, sexp_25_process_command_line_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT);
    sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
  }
  op = sexp_define_foreign(ctx, env, "parent-process-id", 0, sexp_parent_process_id_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
  }
  op = sexp_define_foreign(ctx, env, "current-process-id", 0, sexp_current_process_id_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
  }
  op = sexp_define_foreign(ctx, env, "execvp", 2, sexp_execvp_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_STRING);
    sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_STRING);
  }
  op = sexp_define_foreign(ctx, env, "%exit", 1, sexp_25_exit_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = SEXP_VOID;
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
  }
  op = sexp_define_foreign(ctx, env, "kill", 2, sexp_kill_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
  }
  op = sexp_define_foreign(ctx, env, "waitpid", 2, sexp_waitpid_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg3_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
  }
  op = sexp_define_foreign(ctx, env, "fork", 0, sexp_fork_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
  }
  op = sexp_define_foreign(ctx, env, "%fork", 0, sexp_25_fork_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
  }
  op = sexp_define_foreign(ctx, env, "sleep", 1, sexp_sleep_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
  }
  op = sexp_define_foreign(ctx, env, "alarm", 1, sexp_alarm_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
  }
  op = sexp_define_foreign(ctx, env, "current-signal-mask", 0, sexp_current_signal_mask_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg2_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_sigset_t_type_obj));
    sexp_opcode_arg3_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_sigset_t_type_obj));
  }
  op = sexp_define_foreign(ctx, env, "signal-mask-set!", 1, sexp_signal_mask_set_x_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg2_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_sigset_t_type_obj));
    sexp_opcode_arg3_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_sigset_t_type_obj));
  }
  op = sexp_define_foreign(ctx, env, "signal-mask-unblock!", 1, sexp_signal_mask_unblock_x_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg2_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_sigset_t_type_obj));
    sexp_opcode_arg3_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_sigset_t_type_obj));
  }
  op = sexp_define_foreign(ctx, env, "signal-mask-block!", 1, sexp_signal_mask_block_x_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
    sexp_opcode_arg2_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_sigset_t_type_obj));
    sexp_opcode_arg3_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_sigset_t_type_obj));
  }
  op = sexp_define_foreign(ctx, env, "signal-set-contains?", 2, sexp_signal_set_contains_p_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_BOOLEAN);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_sigset_t_type_obj));
    sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
  }
  op = sexp_define_foreign(ctx, env, "signal-set-delete!", 2, sexp_signal_set_delete_x_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_sigset_t_type_obj));
    sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
  }
  op = sexp_define_foreign(ctx, env, "signal-set-add!", 2, sexp_signal_set_add_x_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_sigset_t_type_obj));
    sexp_opcode_arg2_type(op) = sexp_make_fixnum(SEXP_FIXNUM);
  }
  op = sexp_define_foreign(ctx, env, "signal-set-fill!", 1, sexp_signal_set_fill_x_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_sigset_t_type_obj));
  }
  op = sexp_define_foreign(ctx, env, "make-signal-set", 0, sexp_make_signal_set_stub);
  if (sexp_opcodep(op)) {
    sexp_opcode_return_type(op) = sexp_make_fixnum(SEXP_OBJECT);
    sexp_opcode_arg1_type(op) = sexp_make_fixnum(sexp_type_tag(sexp_sigset_t_type_obj));
  }
  op = sexp_define_foreign(ctx, env, "set-signal-action!", 2, sexp_set_signal_action_x_stub);
  sexp_init_signals(ctx, env);
  sexp_gc_release3(ctx);
  return SEXP_VOID;
}

