static Socket_Type *perform_accept (Socket_Type *s, struct sockaddr *addr, unsigned int *lenp) { socklen_t addr_len; Socket_Type *s1; int fd1; addr_len = *lenp; while (-1 == (fd1 = accept (s->fd, addr, &addr_len))) { #ifdef EINTR if (errno == EINTR) { if (-1 == SLang_handle_interrupt ()) return NULL; continue; } #endif throw_errno_error ("accept", errno); return NULL; } *lenp = (unsigned int) addr_len; if (NULL == (s1 = create_socket (fd1, s->domain, s->type, s->protocol))) (void) close_socket (fd1); return s1; }
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 char *read_with_no_readline (char *prompt, int noecho) { char *line; #ifdef REAL_UNIX_SYSTEM int stdin_is_noecho = 0; #endif char buf[1024]; char *b; fprintf (stdout, "%s", prompt); fflush (stdout); if (noecho) { #ifdef REAL_UNIX_SYSTEM if (isatty (fileno(stdin))) { (void) SLsystem ("stty -echo"); /* yuk */ stdin_is_noecho = 1; } #endif } line = buf; while (NULL == fgets (buf, sizeof (buf), stdin)) { #ifdef EINTR if (errno == EINTR) { if (-1 == SLang_handle_interrupt ()) { line = NULL; break; } continue; } #endif line = NULL; break; } #ifdef REAL_UNIX_SYSTEM if (stdin_is_noecho) (void) SLsystem ("stty echo"); #endif if (line == NULL) return NULL; /* Remove the final newline */ b = line; while (*b && (*b != '\n')) b++; *b = 0; return SLmake_string (line); }
/* 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; }
static int scalar_fwrite (SLtype type, FILE *fp, VOID_STAR ptr, unsigned int desired, unsigned int *actual) { unsigned int n; char *buf = (char *)ptr; size_t desired_bytes, actual_bytes; size_t size = _pSLclass_get_class (type)->cl_sizeof_type; desired_bytes = size * desired; actual_bytes = 0; while (desired_bytes) { int e; errno = 0; n = fwrite (buf, 1, desired_bytes, fp); actual_bytes += n; if (n == desired_bytes) break; e = errno; desired_bytes -= n; buf += n; clearerr (fp); #ifdef EINTR if ((e == EINTR) && (0 == SLang_handle_interrupt ())) continue; #endif _pSLerrno_errno = e; /* Apparantly, the write can be interrupted returning a short item * count but not set errno. */ if (n == 0) break; } if (actual_bytes % size) { /* Sigh. We failed to write out a full object. */ } *actual = actual_bytes / size; return 0; }
static int close_socket (int fd) { /* Do not call close again to avoid undefined behavior */ if (-1 == close (fd)) { #ifdef EINTR if (errno == EINTR) { if (-1 == SLang_handle_interrupt ()) return -1; } #endif return -1; } return 0; }
static int scalar_fread (SLtype type, FILE *fp, VOID_STAR ptr, unsigned int desired, unsigned int *actual) { unsigned int n; char *buf = (char *)ptr; size_t desired_bytes, actual_bytes; size_t size = _pSLclass_get_class (type)->cl_sizeof_type; desired_bytes = size * desired; actual_bytes = 0; while (desired_bytes) { int e; errno = 0; n = fread (buf, 1, desired_bytes, fp); actual_bytes += n; if (n == desired_bytes) break; e = errno; desired_bytes -= n; buf += n; clearerr (fp); #ifdef EINTR if ((e == EINTR) && (0 == SLang_handle_interrupt ())) continue; #endif _pSLerrno_errno = e; break; } if (actual_bytes % size) { /* Sigh. We failed to read a full object. */ } *actual = actual_bytes / size; return 0; }
static int perform_bind (int fd, struct sockaddr *addr, unsigned int len) { while (-1 == bind (fd, addr, len)) { #ifdef EINTR if (errno == EINTR) { if (-1 == SLang_handle_interrupt ()) return -1; continue; } #endif /* The manpage indicates EAGAIN will be returned if no free ports exist. * So allow the caller to handle that. */ throw_errno_error ("bind", errno); return -1; } return 0; }
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); }
/* This hook if a signal occurs while waiting for input. */ static int getkey_intr_hook (void) { return SLang_handle_interrupt (); }
static char *read_input_line (SLang_RLine_Info_Type *rline, char *prompt, int noecho) { char *line; #ifdef REAL_UNIX_SYSTEM int stdin_is_noecho = 0; #endif if (Use_Readline == 0) { char buf[1024]; char *b; fprintf (stdout, "%s", prompt); fflush (stdout); if (noecho) { #ifdef REAL_UNIX_SYSTEM if (isatty (fileno(stdin))) { (void) SLsystem ("stty -echo"); /* yuk */ stdin_is_noecho = 1; } #endif } line = buf; while (NULL == fgets (buf, sizeof (buf), stdin)) { #ifdef EINTR if (errno == EINTR) { if (-1 == SLang_handle_interrupt ()) { line = NULL; break; } continue; } #endif line = NULL; break; } #ifdef REAL_UNIX_SYSTEM if (stdin_is_noecho) (void) SLsystem ("stty echo"); #endif if (line == NULL) return NULL; /* Remove the final newline */ b = line; while (*b && (*b != '\n')) b++; *b = 0; return SLmake_string (line); } #if SYSTEM_SUPPORTS_SIGNALS init_tty (); #endif #if USE_GNU_READLINE (void) rline; if (noecho == 0) rl_redisplay_function = rl_redisplay; else { /* FIXME: What is the proper way to implement this in GNU readline? */ (void) fputs (prompt, stdout); (void) fflush (stdout); rl_redisplay_function = redisplay_dummy; } line = readline (prompt); rl_redisplay_function = rl_redisplay; #else SLtt_get_screen_size (); SLrline_set_display_width (rline, SLtt_Screen_Cols); (void) add_sigwinch_handlers (); Active_Rline_Info = rline; (void) SLrline_set_echo (rline, (noecho == 0)); line = SLrline_read_line (rline, prompt, NULL); Active_Rline_Info = NULL; #endif #if SYSTEM_SUPPORTS_SIGNALS reset_tty (); #else fputs ("\r\n", stdout); fflush (stdout); #endif return line; }