/* This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file. */

/* posix */
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

/* bsd extensions */
#include <sys/uio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>

#include <sys/plan9_helpers.h>

int __libc_accept4(int fd, __SOCKADDR_ARG addr, socklen_t *alen, int a4_flags)
{
	int nfd, lcfd;
	socklen_t n;
	Rock *r, *nr;
	struct sockaddr_in *ip;
	char name[Ctlsize];
	char file[8 + Ctlsize + 1];
	const char *net = 0;
	char listen[Ctlsize];
	int open_flags;

	r = _sock_findrock(fd, 0);
	if (r == 0) {
		errno = ENOTSOCK;
		return -1;
	}

	switch (r->domain) {
	case PF_INET:
		switch (r->stype) {
		case SOCK_DGRAM:
			net = "udp";
			break;
		case SOCK_STREAM:
			net = "tcp";
			break;
		}
		/* at this point, our FD is for the data file.  we need to open
		 * the listen file. */
		_sock_get_conv_filename(r, "listen", listen);
		open_flags = O_RDWR;
		/* This is for the listen - maybe don't block on open */
		open_flags |= (r->sopts & SOCK_NONBLOCK ? O_NONBLOCK : 0);
		/* This is for the ctl we get back - maybe CLOEXEC, based on
		 * what accept4 wants for the child */
		open_flags |= (a4_flags & SOCK_CLOEXEC ? O_CLOEXEC : 0);
		lcfd = open(listen, open_flags);
		if (lcfd < 0)
			return -1;
		/* at this point, we have a new conversation, and lcfd is its
		 * ctl fd.  nfd will be the FD for that conv's data file.
		 * sock_data will store our lcfd in the rock and return the data
		 * file fd.
		 *
		 * Note, we pass the listen socket's stype, but not it's sopts.
		 * The sopts (e.g. SOCK_NONBLOCK) apply to the original socket,
		 * not to the new one.  Instead, we pass the accept4 flags,
		 * which are the sopts for the new socket.  Note that this is
		 * just the sopts.  Both the listen socket and the new socket
		 * have the same stype. */
		nfd = _sock_data(lcfd, net, r->domain, a4_flags | r->stype,
		                 r->protocol, &nr);
		if (nfd < 0)
			return -1;

		/* get remote address */
		ip = (struct sockaddr_in *)&nr->raddr;
		_sock_ingetaddr(nr, ip, &n, "remote");
		if (addr.__sockaddr__) {
			memmove(addr.__sockaddr_in__, ip,
				sizeof(struct sockaddr_in));
			*alen = sizeof(struct sockaddr_in);
		}

		return nfd;
	case PF_UNIX:
		if (r->other >= 0) {
			errno = EINVAL;	// was EGREG
			return -1;
		}

		for (;;) {
			/* read path to new connection */
			n = read(fd, name, sizeof(name) - 1);
			if (n < 0)
				return -1;
			if (n == 0)
				continue;
			name[n] = 0;

			/* open new connection */
			_sock_srvname(file, name);
			open_flags = O_RDWR;
			/* This is for the listen - maybe don't block on open */
			open_flags |= (r->sopts &
				       SOCK_NONBLOCK ? O_NONBLOCK : 0);
			/* This is for the ctl we get back - maybe CLOEXEC,
			 * based on what accept4 wants for the child */
			open_flags |= (a4_flags & SOCK_CLOEXEC ? O_CLOEXEC : 0);
			nfd = open(file, open_flags);
			if (nfd < 0)
				continue;

			/* confirm opening on new connection */
			if (write(nfd, name, strlen(name)) > 0)
				break;

			close(nfd);
		}

		nr = _sock_newrock(nfd);
		if (nr == 0) {
			close(nfd);
			return -1;
		}
		nr->domain = r->domain;
		nr->stype = r->stype;
		nr->sopts = a4_flags;
		nr->protocol = r->protocol;

		return nfd;
	default:
		errno = EOPNOTSUPP;
		return -1;
	}
}
weak_alias(__libc_accept4, accept4)
