--- /dev/null	Sun Aug  5 23:41:08 2018
+++ new/usr/src/man/man3c/connect.3c	Sun Aug  5 23:41:08 2018
@@ -0,0 +1,379 @@
+.\"
+.\" The contents of this file are subject to the terms of the
+.\" Common Development and Distribution License (the "License").
+.\" You may not use this file except in compliance with the License.
+.\"
+.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+.\" or http://www.opensolaris.org/os/licensing.
+.\" See the License for the specific language governing permissions
+.\" and limitations under the License.
+.\"
+.\" When distributing Covered Code, include this CDDL HEADER in each
+.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+.\" If applicable, add the following below this CDDL HEADER, with the
+.\" fields enclosed by brackets "[]" replaced with your own identifying
+.\" information: Portions Copyright [yyyy] [name of copyright owner]
+.\"
+.\"
+.\" Copyright 1989 AT&T  All Rights Reserved
+.\" Copyright (C) 2005, Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright (c) 2014, Joyent, Inc.
+.\" Copyright 2018 Nexenta Systems, Inc.
+.\"
+.Dd August 2, 2018
+.Dt CONNECT 3C
+.Os
+.Sh NAME
+.Nm connect
+.Nd initiate a connection on a socket
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.Ft int
+.Fo connect
+.Fa "int s"
+.Fa "const struct sockaddr *name"
+.Fa "socklen_t namelen"
+.Fc
+.Sh DESCRIPTION
+The parameter
+.Fa s
+is a socket.
+If it is of type
+.Dv SOCK_DGRAM ,
+.Fn connect
+specifies the peer with which the socket is to be associated.
+This address is the address to which datagrams are to be sent if a receiver is
+not explicitly designated.
+This address is the only address from which datagrams are to be received.
+If the socket
+.Fa s
+is of type
+.Dv SOCK_STREAM ,
+.Fn connect
+attempts to make a connection to another socket.
+The other socket is specified by
+.Fa name .
+.Fa name
+is an address in the communication space of the socket.
+Each communication space interprets the
+.Fa name
+parameter in its own way.
+If
+.Fa s
+is not bound, then
+.Fa s
+will be bound to an address selected by the underlying transport provider.
+Generally, stream sockets can successfully
+.Fn connect
+only once.
+Datagram sockets can use
+.Fn connect
+multiple times to change their association.
+Datagram sockets can dissolve the association by connecting to a null address.
+.Ss Non-blocking Sockets
+When a socket is created, it is by default a blocking socket.
+A socket may be configured to be non-blocking either at socket creation time or
+through the use of
+.Xr fcntl 2 .
+When a socket is set to be non-blocking, a call to
+.Fn connect
+initiates an asynchronous connection.
+If the connection cannot be completed without blocking, such as when making a
+TCP connection to a remote server, then  the connection attempt is made in the
+background and
+.Fn connect
+returns -1 and
+.Va errno
+is set to
+.Er EINPROGRESS .
+.Pp
+Applications can obtain the state of this connection attempt by polling the
+socket's file descriptor for
+.Dv POLLOUT .
+The event ports facility is the preferred means of polling on the file
+descriptor, see
+.Xr port_create 3C
+and
+.Xr port_get 3C
+for more information on event ports; however, applications may also use
+traditional portable routines like
+.Xr poll 2
+and
+.Xr select 3C .
+.Pp
+When an asynchronous connection has completed, the application must call
+.Xr getsockopt 3C
+using the macro
+.Dv SOL_SOCKET
+as the
+.Fa level
+argument and the macro
+.Dv SO_ERROR
+as the value of the
+.Fa option
+argument.
+If the value of the
+.Dv SO_ERROR
+socket option is zero, then the connect was successfully established.
+Otherwise, the connection could not be established and the value is the
+corresponding error code that would be commonly found in
+.Va errno .
+.Pp
+Even when a socket is in non-blocking mode, a call to
+.Fn connect
+may fail synchronously.
+If any error other than
+.Er EINPROGRESS
+or
+.Er EINTR
+occurs, then there is no need for the application to poll for asynchronous
+completion.
+Similarly, if a call to
+.Fn connect
+returns successfully, then the socket connection will be established and there
+is no need to poll for completion.
+.Sh RETURN VALUES
+If the connection or binding succeeds, 0 is returned.
+Otherwise, -1 is returned and sets
+.Va errno
+to indicate the error.
+.Sh EXAMPLES
+.Bl -tag -width Ds
+.It Sy Example 1 No Performing an asynchronous connection
+The following sample C program shows how to create and connect to a remote host
+using TCP.
+.Bd -literal
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <port.h>
+#include <unistd.h>
+#include <assert.h>
+
+int
+main(int argc, char *argv[])
+{
+	char *eptr;
+	long port;
+	int sock, ret, eport;
+	struct sockaddr_in6 sin6;
+
+	if (argc != 3) {
+		fprintf(stderr, "connect: <IP> <port>\\n");
+		return (1);
+	}
+
+	bzero(&sin6, sizeof (struct sockaddr_in6));
+	sin6.sin6_family = AF_INET6;
+
+	/*
+	 * Try to parse as an IPv6 address and then try v4.
+	 */
+	ret = inet_pton(AF_INET6, argv[1], &sin6.sin6_addr);
+	if (ret == -1) {
+		perror("inet_pton");
+		return (1);
+	} else if (ret == 0) {
+		struct in_addr v4;
+		ret = inet_pton(AF_INET, argv[1], &v4);
+		if (ret == -1) {
+			perror("inet_pton");
+			return (1);
+		} else if (ret == 0) {
+			fprintf(stderr, "connect: %s is not a valid "
+			    "IPv4 or IPv6 address\\n", argv[1]);
+			return (1);
+		}
+		/* N.B. Not a portable macro */
+		IN6_INADDR_TO_V4MAPPED(&v4, &sin6.sin6_addr);
+	}
+
+	errno = 0;
+	port = strtol(argv[2], &eptr, 10);
+	if (errno != 0 || *eptr != '\e0') {
+		fprintf(stderr, "failed to parse port %s\\n", argv[2]);
+		return (1);
+	}
+	if (port <= 0 || port > UINT16_MAX) {
+		fprintf(stderr, "invalid port: %ld\\n", port);
+		return (1);
+	}
+	sin6.sin6_port = htons(port);
+
+	sock = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0);
+	if (sock < 0) {
+		perror("socket");
+		return (1);
+	}
+
+	eport = port_create();
+	if (eport < 0) {
+		perror("port_create");
+		(void) close(sock);
+		return (1);
+	}
+
+	ret = connect(sock, (struct sockaddr *)&sin6,
+	    sizeof (struct sockaddr_in6));
+	if (ret != 0 && errno != EINPROGRESS && errno != EINTR) {
+		perror("connect");
+		(void) close(sock);
+		(void) close(eport);
+		return (1);
+	}
+
+	if (ret != 0) {
+		port_event_t pe;
+		int err;
+		socklen_t sz = sizeof (err);
+		if (port_associate(eport, PORT_SOURCE_FD, sock, POLLOUT,
+		    NULL) != 0) {
+			perror("port_associate");
+			(void) close(sock);
+			(void) close(eport);
+			return (1);
+		}
+		if (port_get(eport, &pe, NULL) != 0) {
+			perror("port_get");
+			(void) close(sock);
+			(void) close(eport);
+			return (1);
+		}
+		assert(pe.portev_source == PORT_SOURCE_FD);
+		assert(pe.portev_object == (uintptr_t)sock);
+		if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &sz) != 0) {
+			perror("getsockopt");
+			(void) close(sock);
+			(void) close(eport);
+			return (1);
+		}
+		if (err != 0) {
+			/* Asynch connect failed */
+			fprintf(stderr, "asnchronous connect: %s\\n",
+			    strerror(err));
+			(void) close(sock);
+			(void) close(eport);
+			return (1);
+		}
+	}
+
+	/* Read and write to the socket and then clean up */
+
+	return (0);
+}
+.Ed
+.El
+.Sh ERRORS
+The call fails if:
+.Bl -tag -width Er
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix of the pathname
+in
+.Fa name .
+.It Bq Er EADDRINUSE
+The address is already in use.
+.It Bq Er EADDRNOTAVAIL
+The specified address is not available on the remote machine.
+.It Bq Er EAFNOSUPPORT
+Addresses in the specified address family cannot be used with this socket.
+.It Bq Er EALREADY
+The socket is non-blocking,  and a previous connection attempt has not yet been
+completed.
+.It Bq Er EBADF
+.Fa s
+is not a valid descriptor.
+.It Bq Er ECONNREFUSED
+The attempt to connect was forcefully rejected.
+The calling program should
+.Xr close 2
+the socket descriptor, and issue another
+.Xr socket 3C
+call to obtain a new descriptor before attempting another
+.Fn connect
+call.
+.It Bq Er EINPROGRESS
+The socket is non-blocking, and the connection cannot be completed immediately.
+See the section on
+.Sx Non-blocking Sockets
+for more information.
+.It Bq Er EINTR
+The connection attempt was interrupted before any data arrived by the delivery
+of a signal.
+The connection, however, will be established asynchronously.
+.It Bq Er EINVAL
+.Fa namelen
+is not the size of a valid address for the specified address family.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.It Bq Er EISCONN
+The socket is already connected.
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating the pathname in
+.Fa name .
+.It Bq Er ENETUNREACH
+The network is not reachable from this host.
+.It Bq Er EHOSTUNREACH
+The remote host is not reachable from this host.
+.It Bq Er ENOENT
+A component of the path prefix of the pathname in
+.Fa name
+does not exist.
+.Pp
+The socket referred to by the pathname in
+.Fa name
+does not exist.
+.It Bq Er ENOSR
+There were insufficient STREAMS resources available to complete the operation.
+.It Bq Er ENXIO
+The server exited before the connection was complete.
+.It Bq Er ETIMEDOUT
+Connection establishment timed out without establishing a connection.
+.It Bq Er EWOULDBLOCK
+The socket is marked as non-blocking, and the requested operation would block.
+.El
+.Pp
+The following errors are specific to connecting names in the UNIX domain.
+These errors might not apply in future versions of the UNIX IPC domain.
+.Bl -tag -width Er
+.It Bq Er ENOTDIR
+A component of the path prefix of the pathname in
+.Fa name
+is not a directory.
+.It Bq Er ENOTSOCK
+.Fa s
+is not a socket.
+.It Bq Er EPROTOTYPE
+The file that is referred to by
+.Fa name
+is a socket of a type other than type
+.Fa s .
+For example,
+.Fa s
+is a
+.Dv SOCK_DGRAM
+socket, while
+.Fa name
+refers to a
+.Dv SOCK_STREAM
+socket.
+.El
+.Sh MT-LEVEL
+.Sy Safe
+.Sh SEE ALSO
+.Xr close 2 ,
+.Xr accept 3C ,
+.Xr getsockname 3C ,
+.Xr select 3C ,
+.Xr sockaddr 3C ,
+.Xr socket 3C ,
+.Xr socket.h 3HEAD ,
+.Xr attributes 5
