static int fork_intrinsic (void) { int ret = fork (); if (ret == -1) (void) SLerrno_set_errno (errno); return ret; }
static void pipe_intrin (void) { int fds[2]; SLFile_FD_Type *f0; SLFile_FD_Type *f1; while (-1 == pipe (fds)) { if (errno == EINTR) { if (-1 != SLang_handle_interrupt ()) continue; } SLerrno_set_errno (errno); SLang_verror (SL_OS_Error, "pipe failed: %s", SLerrno_strerror(errno)); return; } f0 = SLfile_create_fd ("*pipe*", fds[0]); f1 = SLfile_create_fd ("*pipe*", fds[1]); if ((NULL != f0) && (NULL != f1)) { /* Ignore errors and allow the free_fd routines to clean up */ (void) SLfile_push_fd (f0); (void) SLfile_push_fd (f1); } SLfile_free_fd (f1); SLfile_free_fd (f0); }
static int call_what (int what, char *path, char **argv, char **envp) { while (1) { int ret; switch (what) { case CALL_EXECV: ret = execv (path, argv); break; case CALL_EXECVP: ret = execvp (path, argv); break; case CALL_EXECVE: ret = execve (path, argv, envp); break; } if (ret == 0) return 0; /* should never happen */ SLerrno_set_errno (errno); if (errno == EINTR) { if (-1 != SLang_handle_interrupt ()) continue; } break; } return -1; }
static int check_and_set_errno (int e) { #ifdef EINTR if (e == EINTR) return 0; #endif (void) SLerrno_set_errno (e); return -1; }
static void getitimer_intrinsic (int *wp) { struct itimerval it; if (-1 == getitimer (*wp, &it)) { SLerrno_set_errno (errno); SLang_verror (SL_OS_Error, "getitimer failed: %s", SLerrno_strerror (errno)); return; } (void) SLang_push_double (timeval_to_double (&it.it_value)); (void) SLang_push_double (timeval_to_double (&it.it_interval)); }
static int cfsetospeed_intrin (struct termios *t, unsigned int *speed) { unsigned int bspeed; if (-1 == map_speed_to_bspeed (*speed, &bspeed)) return -1; if (-1 == cfsetospeed (t, bspeed)) { (void) SLerrno_set_errno (errno); return -1; } return 0; }
void sl_ioctl (void) { char *argp = NULL; int fd, retval; unsigned int length, request; SLFile_FD_Type *f; SLang_BString_Type *bstr; if (SLang_Num_Function_Args == 3) { if (SLang_pop_bstring (&bstr) == -1) goto usage_error; if (SLang_pop_uint ((unsigned int *) &request) == -1) goto usage_error; if (SLfile_pop_fd (&f) == -1) goto usage_error; argp = SLbstring_get_pointer (bstr, &length); } else if (SLang_Num_Function_Args == 2) { if (SLang_pop_uint ((unsigned int *) &request) == -1) goto usage_error; if (SLfile_pop_fd (&f) == -1) goto usage_error; } else goto usage_error; if (SLfile_get_fd (f, &fd) == -1) return; if ((retval = ioctl (fd, request, argp)) == -1) { SLang_set_error (SL_OS_Error); (void) SLerrno_set_errno (errno); return; } (void) SLang_push_int (retval); if (argp != NULL) (void) SLang_push_bstring (bstr); return; usage_error : SLang_set_error (SL_Usage_Error); return; }
static int get_fd (SLFile_FD_Type *f, int *fdp) { if (f->is_closed == 0) { if (f->get_fd == NULL) { *fdp = f->fd; return 0; } if (0 == (*f->get_fd)(f->clientdata, fdp)) return 0; } *fdp = -1; #ifdef EBADF SLerrno_set_errno (EBADF); #endif return -1; }
/* Returns 0 the system call should not be restarted, 1 otherwise */ static int is_interrupt (int e, int check_eagain) { SLerrno_set_errno (e); #ifdef EINTR if (e == EINTR) { if (0 == SLang_handle_interrupt ()) return 1; } #endif #ifdef EAGAIN if (e == EAGAIN) { if (check_eagain && (0 == SLang_handle_interrupt ())) return 1; } #endif return 0; }
/* Not yet a public function */ static int SLfile_dup2_fd (SLFile_FD_Type *f0, int newfd) { int fd0, fd; if ((f0 == NULL) || (-1 == get_fd (f0, &fd0))) { #ifdef EBADF SLerrno_set_errno (EBADF); #endif return -1; } while (-1 == (fd = dup2 (fd0, newfd))) { if (is_interrupt (errno, 1)) continue; return -1; } return fd; }
static void waitpid_intrinsic (int *pid, int *options) { int status, ret; Waitpid_Type s; while (-1 == (ret = waitpid ((pid_t)*pid, &status, *options))) { if (errno == EINTR) { if (-1 != SLang_handle_interrupt ()) continue; } (void) SLerrno_set_errno (errno); (void) SLang_push_null (); return; } memset ((char *)&s, 0, sizeof(Waitpid_Type)); if (WIFEXITED(status)) { s.exited = 1; s.exit_status = WEXITSTATUS(status); } if (WIFSIGNALED(status)) { s.signal = WTERMSIG(status); #ifdef WCOREDUMP s.coredump = WCOREDUMP(status) != 0; #endif } if (WIFSTOPPED(status)) s.stopped = WSTOPSIG(status); #ifdef WIFCONTINUED s.continued = WIFCONTINUED(status); #endif s.pid = ret; (void) SLang_push_cstruct ((VOID_STAR)&s, Waitpid_Struct); }
static void select_intrin (double *secsp) { SLang_Array_Type *at_read, *at_write, *at_except; fd_set readfs_buf, writefds_buf, exceptfds_buf; fd_set readfs_save_buf, writefds_save_buf, exceptfds_save_buf; fd_set *readfs, *writefds, *exceptfds; struct timeval tv, *tv_ptr; double secs; int ret, n; secs = *secsp; if (secs < 0.0) tv_ptr = NULL; else { tv.tv_sec = (unsigned long) secs; tv.tv_usec = (unsigned long) ((secs - tv.tv_sec) * 1e6); tv_ptr = &tv; } n = 0; if (-1 == pop_fd_set (&at_except, &exceptfds, &exceptfds_buf, &n)) return; if (-1 == pop_fd_set (&at_write, &writefds, &writefds_buf, &n)) { SLang_free_array (at_except); return; } if (-1 == pop_fd_set (&at_read, &readfs, &readfs_buf, &n)) goto free_return; readfs_save_buf = readfs_buf; writefds_save_buf = writefds_buf; exceptfds_save_buf = exceptfds_buf; n += 1; while (-1 == (ret = select (n, readfs, writefds, exceptfds, tv_ptr))) { #ifdef EINTR if (errno == EINTR) { readfs_buf = readfs_save_buf; writefds_buf = writefds_save_buf; exceptfds_buf = exceptfds_save_buf; if (0 == SLang_handle_interrupt ()) continue; } #endif (void) SLerrno_set_errno (errno); break; } if (ret == -1) (void) SLang_push_null (); else (void) push_select_struct (ret, at_read, at_write, at_except, readfs, writefds, exceptfds); free_return: SLang_free_array (at_read); SLang_free_array (at_write); SLang_free_array (at_except); }
static void setitimer_intrinsic (void) { SLang_Ref_Type *interval_ref = NULL, *value_ref = NULL; int w; struct itimerval new_value, old_value; double interval = 0.0, value; int argc = SLang_Num_Function_Args; if (SLang_peek_at_stack () == SLANG_REF_TYPE) { if (-1 == SLang_pop_ref (&value_ref)) return; argc--; if (SLang_peek_at_stack() == SLANG_REF_TYPE) { interval_ref = value_ref; if (-1 == SLang_pop_ref (&value_ref)) goto free_and_return; argc--; } } switch (argc) { case 3: if (-1 == SLang_pop_double (&interval)) goto free_and_return; /* drop */ case 2: default: if ((-1 == SLang_pop_double (&value)) || (-1 == SLang_pop_int (&w))) goto free_and_return; } double_to_timeval (interval, &new_value.it_interval); double_to_timeval (value, &new_value.it_value); if (-1 == setitimer (w, &new_value, &old_value)) { SLerrno_set_errno (errno); SLang_verror (SL_OS_Error, "setitimer failed: %s", SLerrno_strerror (errno)); goto free_and_return; } if (value_ref != NULL) { value = timeval_to_double (&old_value.it_value); if (-1 == SLang_assign_to_ref (value_ref, SLANG_DOUBLE_TYPE, &value)) goto free_and_return; } if (interval_ref != NULL) { interval = timeval_to_double (&old_value.it_interval); if (-1 == SLang_assign_to_ref (interval_ref, SLANG_DOUBLE_TYPE, &interval)) goto free_and_return; } free_and_return: if (value_ref != NULL) SLang_free_ref (value_ref); if (interval_ref != NULL) SLang_free_ref (interval_ref); }
static int write_image_internal (char *file, SLang_Array_Type *at, int color_type, void (*write_fun)(png_struct *, png_byte *p, SLindex_Type, png_byte *), int flip) { FILE *fp; Png_Type *p = NULL; png_struct *png; png_info *info; SLindex_Type width, height; png_byte **image_pointers; int bit_depth; int status = -1; png_byte *tmpbuf; bit_depth = 8; height = at->dims[0]; width = at->dims[1]; if (NULL == (image_pointers = allocate_image_pointers (height, (png_byte *)at->data, width * at->sizeof_type, flip))) return -1; if (NULL == (tmpbuf = (png_byte *)SLmalloc (4*width))) { free_image_pointers (image_pointers); return -1; } if (NULL == (fp = fopen (file, "wb"))) { (void)SLerrno_set_errno (errno); SLang_verror (SL_Open_Error, "Unable to open %s", file); goto return_error; } if (NULL == (p = alloc_png_type ('w'))) goto return_error; p->fp = fp; if (NULL == (p->png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) { SLang_verror (SL_Open_Error, "png_create_write_struct failed"); goto return_error; } png = p->png; if (NULL == (p->info = png_create_info_struct (png))) { SLang_verror (SL_Open_Error, "png_create_info_struct failed"); goto return_error; } info = p->info; if (setjmp(png_jmpbuf(png))) { SLang_verror (SL_Write_Error, "PNG I/O error"); goto return_error; } png_init_io(png, fp); png_set_IHDR (png, info, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png, info); if (-1 == write_array (png, image_pointers, height, width, write_fun, tmpbuf)) goto return_error; png_write_end(png, NULL); if (EOF == fclose (p->fp)) { SLang_verror (SL_Write_Error, "Error closing %s", file); SLerrno_set_errno (errno); } else status = 0; p->fp = NULL; /* drop */ return_error: if (tmpbuf != NULL) SLfree ((char *) tmpbuf); free_image_pointers (image_pointers); if (p != NULL) free_png_type (p); return status; }
static void set_errno (int *errnum) /*{{{*/ { errno = *errnum; SLerrno_set_errno (*errnum); }
static void throw_errno_error (SLFUTURE_CONST char *what, int e) { SLerrno_set_errno (e); SLang_verror (SocketError, "%s: %s", what, SLerrno_strerror (e)); }