int ei_writev_fill_t(int fd, const struct iovec *iov, int iovcnt, unsigned ms) { int i; int done; struct iovec *iov_base = NULL; struct iovec *current_iov; int current_iovcnt; int sum; for (sum = 0, i = 0; i < iovcnt; ++i) { sum += iov[i].iov_len; } if (ms != 0U) { SET_NONBLOCKING(fd); } current_iovcnt = iovcnt; current_iov = (struct iovec *) iov; done = 0; for (;;) { i = ei_writev_t(fd, current_iov, current_iovcnt, ms); if (i <= 0) { /* ei_writev_t should always return at least 1 */ if (ms != 0U) { SET_BLOCKING(fd); } if (iov_base != NULL) { free(iov_base); } return (i); } done += i; if (done < sum) { if (iov_base == NULL) { iov_base = malloc(sizeof(struct iovec) * iovcnt); memcpy(iov_base, iov, sizeof(struct iovec) * iovcnt); current_iov = iov_base; } while (i > 0) { if (i < current_iov[0].iov_len) { current_iov[0].iov_len -= i; i = 0; } else { i -= current_iov[0].iov_len; current_iov++; current_iovcnt--; } } } else { break; } } if (ms != 0U) { SET_BLOCKING(fd); } if (iov_base != NULL) { free(iov_base); } return (sum); }
/* * reset the terminal to the original settings on exit */ void sys_tty_reset(int exit_code) { if (using_oldshell && !replace_intr) { SET_BLOCKING(0); } else if (isatty(0)) { tcsetattr(0,TCSANOW,&initial_tty_mode); } }
/* write entire buffer on fd or fail (setting errno) */ int ei_write_fill_t(int fd, char *buf, int len, unsigned ms) { int i,done=0; if (ms != 0U) { SET_NONBLOCKING(fd); } do { i = ei_write_t(fd, buf+done, len-done, ms); if (i <= 0) { if (ms != 0U) { SET_BLOCKING(fd); } return (i); } done += i; } while (done < len); if (ms != 0U) { SET_BLOCKING(fd); } return (len); }
int ei_connect_t(int fd, void *sinp, int sin_siz, unsigned ms) { int res; int error; int s_res; struct timeval tv; fd_set writefds; fd_set exceptfds; if (ms == 0) { res = connect(fd, sinp, sin_siz); return (res < 0) ? -1 : res; } else { SET_NONBLOCKING(fd); res = connect(fd, sinp, sin_siz); error = GET_SOCKET_ERROR(); SET_BLOCKING(fd); if (!MEANS_SOCKET_ERROR(res)) { return (res < 0) ? -1 : res; } else { if (error != ERROR_WOULDBLOCK && error != ERROR_INPROGRESS) { return -1; } else { tv.tv_sec = (long) (ms/1000U); ms %= 1000U; tv.tv_usec = (long) (ms * 1000U); FD_ZERO(&writefds); FD_SET(fd,&writefds); FD_ZERO(&exceptfds); FD_SET(fd,&exceptfds); s_res = select(fd + 1, NULL, &writefds, &exceptfds, &tv); switch (s_res) { case 0: return -2; case 1: if (FD_ISSET(fd, &exceptfds)) { return -1; } else { return 0; /* Connect completed */ } default: return -1; } } } } }
void erts_do_break_handling(void) { struct termios temp_mode; int saved = 0; /* * Most functions that do_break() calls are intentionally not thread safe; * therefore, make sure that all threads but this one are blocked before * proceeding! */ erts_smp_thr_progress_block(); /* during break we revert to initial settings */ /* this is done differently for oldshell */ if (using_oldshell && !replace_intr) { SET_BLOCKING(1); } else if (isatty(0)) { tcgetattr(0,&temp_mode); tcsetattr(0,TCSANOW,&initial_tty_mode); saved = 1; } /* call the break handling function, reset the flag */ do_break(); ERTS_UNSET_BREAK_REQUESTED; fflush(stdout); /* after break we go back to saved settings */ if (using_oldshell && !replace_intr) { SET_NONBLOCKING(1); } else if (saved) { tcsetattr(0,TCSANOW,&temp_mode); } erts_smp_thr_progress_unblock(); }