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); }
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; } } } } }
/* 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); }
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(); }
/* * Create the marker file descriptor by establishing a loopback connection * which we shutdown but do not close the fd. The result is an fd that * can be used for read/write. */ static int getMarkerFD() { int server_fd, child_fd, connect_fd; SOCKADDR him; int type, len, port; type = AF_INET; #ifdef AF_INET6 if (ipv6_available()) { type = AF_INET6; } #endif /* * Create listener on any port */ server_fd = JVM_Socket(type, SOCK_STREAM, 0); if (server_fd < 0) { return -1; } if (JVM_Listen(server_fd, 1) == -1) { JVM_SocketClose(server_fd); return -1; } len = SOCKADDR_LEN; if (JVM_GetSockName(server_fd, (struct sockaddr *)&him, &len) == -1) { JVM_SocketClose(server_fd); return -1; } port = NET_GetPortFromSockaddr((struct sockaddr *)&him); /* * Establish connection from client socket. * Server is bound to 0.0.0.0/X or ::/X * We connect to 127.0.0.1/X or ::1/X */ #ifdef AF_INET6 if (ipv6_available()) { struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)&him; jbyte caddr[16]; memset((char *) caddr, 0, 16); caddr[15] = 1; memset((char *)him6, 0, sizeof(struct sockaddr_in6)); memcpy((void *)&(him6->sin6_addr), caddr, sizeof(struct in6_addr) ); him6->sin6_port = htons((short) port); him6->sin6_family = AF_INET6; len = sizeof(struct sockaddr_in6) ; } else #endif /* AF_INET6 */ { struct sockaddr_in *him4 = (struct sockaddr_in*)&him; memset((char *) him4, 0, sizeof(struct sockaddr_in)); him4->sin_port = htons((short) port); him4->sin_addr.s_addr = (uint32_t) htonl(0x7f000001); him4->sin_family = AF_INET; len = sizeof(struct sockaddr_in); } connect_fd = JVM_Socket(type, SOCK_STREAM, 0); if (connect_fd < 0) { JVM_SocketClose(server_fd); return -1; } if (JVM_Connect(connect_fd, (struct sockaddr *) &him, len) == -1) { JVM_SocketClose(server_fd); JVM_SocketClose(connect_fd); return -1; } /* * Server accepts connection - do in in non-blocking mode to avoid * hanging if there's an error (should never happen!!!) */ SET_NONBLOCKING(server_fd); len = SOCKADDR_LEN; child_fd = JVM_Accept(server_fd, (struct sockaddr *)&him, (jint *)&len); if (child_fd == -1) { JVM_SocketClose(server_fd); JVM_SocketClose(connect_fd); return -1; } /* * Finally shutdown connect_fd (any reads to this fd will get * EOF; any writes will get an error). */ JVM_SocketShutdown(connect_fd, 2); JVM_SocketClose(child_fd); JVM_SocketClose(server_fd); return connect_fd; }