Ejemplo n.º 1
0
/*
 * UNIX socketpair() implementation. Why? Because Windows does not have it.
 * Return 0 on success, -1 on error.
 */
static int
my_socketpair(struct conn *c, int sp[2])
{
	struct sockaddr_in	sa;
	int			sock, ret = -1;
	socklen_t		len = sizeof(sa);

	(void) memset(&sa, 0, sizeof(sa));
	sa.sin_family 		= AF_INET;
	sa.sin_port		= htons(0);
	sa.sin_addr.s_addr	= htonl(INADDR_LOOPBACK);

	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		elog(E_LOG, c, "mysocketpair: socket(): %d", ERRNO);
	} else if (bind(sock, (struct sockaddr *) &sa, len) != 0) {
		elog(E_LOG, c, "mysocketpair: bind(): %d", ERRNO);
		(void) closesocket(sock);
	} else if (listen(sock, 1) != 0) {
		elog(E_LOG, c, "mysocketpair: listen(): %d", ERRNO);
		(void) closesocket(sock);
	} else if (getsockname(sock, (struct sockaddr *) &sa, &len) != 0) {
		elog(E_LOG, c, "mysocketpair: getsockname(): %d", ERRNO);
		(void) closesocket(sock);
	} else if ((sp[0] = socket(AF_INET, SOCK_STREAM, 6)) == -1) {
		elog(E_LOG, c, "mysocketpair: socket(): %d", ERRNO);
		(void) closesocket(sock);
	} else if (connect(sp[0], (struct sockaddr *) &sa, len) != 0) {
		elog(E_LOG, c, "mysocketpair: connect(): %d", ERRNO);
		(void) closesocket(sock);
		(void) closesocket(sp[0]);
	} else if ((sp[1] = accept(sock,(struct sockaddr *) &sa, &len)) == -1) {
		elog(E_LOG, c, "mysocketpair: accept(): %d", ERRNO);
		(void) closesocket(sock);
		(void) closesocket(sp[0]);
	} else {
		/* Success */
		ret = 0;
		(void) closesocket(sock);
		(void) set_non_blocking_mode(sp[0]);
		(void) set_non_blocking_mode(sp[1]);
	}

#ifndef _WIN32
	(void) fcntl(sp[0], F_SETFD, FD_CLOEXEC);
	(void) fcntl(sp[1], F_SETFD, FD_CLOEXEC);
#endif /* _WIN32*/

	return (ret);
}
Ejemplo n.º 2
0
static void close_socket_gracefully(SOCKET sock) {
  char buf[BUFSIZ];
  int n;

  // Send FIN to the client
  (void) shutdown(sock, SHUT_WR);
  set_non_blocking_mode(sock);

  // Read and discard pending data. If we do not do that and close the
  // socket, the data in the send buffer may be discarded. This
  // behaviour is seen on Windows, when client keeps sending data
  // when server decide to close the connection; then when client
  // does recv() it gets no data back.
  do {
    n = pull(sock, buf, sizeof(buf));
  } while (n > 0);

  // Now we know that our FIN is ACK-ed, safe to close
  (void) close(sock);
}