Esempio n. 1
0
static VALUE
my_connect(VALUE klass, int io_wait, int domain, void *addr, socklen_t addrlen)
{
	int fd = socket(domain, MY_SOCK_STREAM, 0);

	if (fd == -1) {
		switch (errno) {
		case EMFILE:
		case ENFILE:
#ifdef ENOBUFS
		case ENOBUFS:
#endif /* ENOBUFS */
			errno = 0;
			rb_gc();
			fd = socket(domain, MY_SOCK_STREAM, 0);
		}
		if (fd == -1)
			rb_sys_fail("socket");
	}

#ifndef SOCK_NONBLOCK
	if (fcntl(fd, F_SETFL, O_RDWR | O_NONBLOCK) == -1)
		close_fail(fd, "fcntl(F_SETFL, O_RDWR | O_NONBLOCK)");
#endif /* SOCK_NONBLOCK */

	if (connect(fd, addr, addrlen) == -1) {
		if (errno == EINPROGRESS) {
			VALUE io = sock_for_fd(klass, fd);

			if (io_wait) {
				errno = EAGAIN;
				(void)kgio_call_wait_writable(io);
			}
			return io;
		}
		close_fail(fd, "connect");
	}
	return sock_for_fd(klass, fd);
}
Esempio n. 2
0
static VALUE
my_connect(VALUE klass, int io_wait, int domain,
	const void *addr, socklen_t addrlen)
{
	int fd = my_socket(domain);

	if (connect(fd, addr, addrlen) < 0) {
		if (errno == EINPROGRESS) {
			VALUE io = sock_for_fd(klass, fd);

			if (io_wait) {
				errno = EAGAIN;
				(void)kgio_call_wait_writable(io);
			}
			return io;
		}
		close_fail(fd, "connect");
	}
	return sock_for_fd(klass, fd);
}
Esempio n. 3
0
/* try to use SOCK_NONBLOCK and SOCK_CLOEXEC */
static int my_socket(int domain)
{
	int fd;

retry:
	fd = socket(domain, MY_SOCK_STREAM, 0);

	if (fd < 0) {
		switch (errno) {
		case EMFILE:
		case ENFILE:
#ifdef ENOBUFS
		case ENOBUFS:
#endif /* ENOBUFS */
			errno = 0;
			rb_gc();
			fd = socket(domain, MY_SOCK_STREAM, 0);
			break;
		case EINVAL:
			if (MY_SOCK_STREAM != SOCK_STREAM) {
				MY_SOCK_STREAM = SOCK_STREAM;
				goto retry;
			}
		}
		if (fd < 0)
			rb_sys_fail("socket");
	}

	if (MY_SOCK_STREAM == SOCK_STREAM) {
		if (fcntl(fd, F_SETFL, O_RDWR | O_NONBLOCK) < 0)
			close_fail(fd, "fcntl(F_SETFL, O_RDWR | O_NONBLOCK)");
		rb_fd_fix_cloexec(fd);
	}

	return fd;
}