xref: /illumos-gate/usr/src/lib/libc/port/gen/event_port.c (revision e86c3f00)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5f841f6adSraf  * Common Development and Distribution License (the "License").
6f841f6adSraf  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21f841f6adSraf 
227c478bd9Sstevel@tonic-gate /*
237257d1b4Sraf  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include "lint.h"
287c478bd9Sstevel@tonic-gate #include <sys/types.h>
297c478bd9Sstevel@tonic-gate #include <sys/stat.h>
307c478bd9Sstevel@tonic-gate #include <fcntl.h>
317c478bd9Sstevel@tonic-gate #include <unistd.h>
327c478bd9Sstevel@tonic-gate #include <sys/port_impl.h>
337c478bd9Sstevel@tonic-gate #include <errno.h>
347c478bd9Sstevel@tonic-gate #include <stdlib.h>
357c478bd9Sstevel@tonic-gate #include <sys/systm.h>
367c478bd9Sstevel@tonic-gate #include <libc.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate /*
397c478bd9Sstevel@tonic-gate  * The second argument of _portfs(PORT_CREATE, 0,,,) represents the version
407c478bd9Sstevel@tonic-gate  * number of the event ports framework. The version number is required to
417c478bd9Sstevel@tonic-gate  * identify possible changes/extensions of the port_event_t structure. If an
427c478bd9Sstevel@tonic-gate  * extension is required the port_create() function will be mapped to a second
437c478bd9Sstevel@tonic-gate  * library create function like port_create_v1(PORT_CREATE, VERSION,,,)
447c478bd9Sstevel@tonic-gate  * VERSION will be a number > 0.
457c478bd9Sstevel@tonic-gate  * As long as such an extension is not required the second argument will be
467c478bd9Sstevel@tonic-gate  * set to 0 and no check will be done in the kernel interface.
477c478bd9Sstevel@tonic-gate  */
487c478bd9Sstevel@tonic-gate int
port_create()497257d1b4Sraf port_create()
507c478bd9Sstevel@tonic-gate {
517c478bd9Sstevel@tonic-gate 	rval_t	r;
527c478bd9Sstevel@tonic-gate 	r.r_vals = _portfs(PORT_CREATE | PORT_SYS_NOPORT, 0, 0, 0, 0, 0);
537c478bd9Sstevel@tonic-gate 	return (r.r_val1);
547c478bd9Sstevel@tonic-gate }
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate int
port_associate(int port,int source,uintptr_t object,int events,void * user)577257d1b4Sraf port_associate(int port, int source, uintptr_t object, int events, void *user)
587c478bd9Sstevel@tonic-gate {
597c478bd9Sstevel@tonic-gate 	rval_t	r;
607c478bd9Sstevel@tonic-gate 	r.r_vals = _portfs(PORT_ASSOCIATE, port, source, object, events,
617c478bd9Sstevel@tonic-gate 	    (uintptr_t)user);
627c478bd9Sstevel@tonic-gate 	return (r.r_val1);
637c478bd9Sstevel@tonic-gate }
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate int
port_get(int port,port_event_t * pe,struct timespec * to)677257d1b4Sraf port_get(int port, port_event_t *pe, struct timespec *to)
687c478bd9Sstevel@tonic-gate {
697c478bd9Sstevel@tonic-gate 	rval_t	r;
707c478bd9Sstevel@tonic-gate 	if (to)
717c478bd9Sstevel@tonic-gate 		r.r_vals = _portfs(PORT_GET, port, (uintptr_t)pe, to->tv_sec,
727c478bd9Sstevel@tonic-gate 		    to->tv_nsec, (uintptr_t)to);
737c478bd9Sstevel@tonic-gate 	else
74*e86c3f00SToomas Soome 		r.r_vals = _portfs(PORT_GET, port, (uintptr_t)pe, 0, 0, 0);
757c478bd9Sstevel@tonic-gate 	return (r.r_val1);
767c478bd9Sstevel@tonic-gate }
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate int
port_getn(int port,port_event_t list[],uint_t max,uint_t * nget,struct timespec * timeout)797257d1b4Sraf port_getn(int port, port_event_t list[], uint_t max, uint_t *nget,
807c478bd9Sstevel@tonic-gate     struct timespec *timeout)
817c478bd9Sstevel@tonic-gate {
827c478bd9Sstevel@tonic-gate 	rval_t	r;
837c478bd9Sstevel@tonic-gate 	if (nget == NULL) {
847c478bd9Sstevel@tonic-gate 		errno = EINVAL;
857c478bd9Sstevel@tonic-gate 		return (-1);
867c478bd9Sstevel@tonic-gate 	}
877c478bd9Sstevel@tonic-gate 	r.r_vals = _portfs(PORT_GETN, port, (uintptr_t)list, max, *nget,
887c478bd9Sstevel@tonic-gate 	    (uintptr_t)timeout);
897c478bd9Sstevel@tonic-gate 	if (r.r_val1 == -1) {
907c478bd9Sstevel@tonic-gate 		/* global error, errno is already set */
917c478bd9Sstevel@tonic-gate 		return (-1);
927c478bd9Sstevel@tonic-gate 	}
937c478bd9Sstevel@tonic-gate 	*nget = r.r_val1;
947c478bd9Sstevel@tonic-gate 	if (r.r_val2 == ETIME) {
957c478bd9Sstevel@tonic-gate 		errno = ETIME;
967c478bd9Sstevel@tonic-gate 		return (-1);
977c478bd9Sstevel@tonic-gate 	}
987c478bd9Sstevel@tonic-gate 	return (r.r_val2);
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate int
port_dissociate(int port,int source,uintptr_t object)1027257d1b4Sraf port_dissociate(int port, int source, uintptr_t object)
1037c478bd9Sstevel@tonic-gate {
1047c478bd9Sstevel@tonic-gate 	rval_t	r;
1057c478bd9Sstevel@tonic-gate 	r.r_vals = _portfs(PORT_DISSOCIATE, port, source, object, 0, 0);
1067c478bd9Sstevel@tonic-gate 	return (r.r_val1);
1077c478bd9Sstevel@tonic-gate }
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate int
port_send(int port,int events,void * user)1107257d1b4Sraf port_send(int port, int events, void *user)
1117c478bd9Sstevel@tonic-gate {
1127c478bd9Sstevel@tonic-gate 	rval_t	r;
113*e86c3f00SToomas Soome 	r.r_vals = _portfs(PORT_SEND, port, events, (uintptr_t)user, 0, 0);
1147c478bd9Sstevel@tonic-gate 	return (r.r_val1);
1157c478bd9Sstevel@tonic-gate }
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate /*
118f841f6adSraf  * _port_dispatch() will block if there are not resources available to
1197c478bd9Sstevel@tonic-gate  * satisfy the request.
1207c478bd9Sstevel@tonic-gate  */
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate int
_port_dispatch(int port,int flags,int source,int events,uintptr_t object,void * user)1237c478bd9Sstevel@tonic-gate _port_dispatch(int port, int flags, int source, int events, uintptr_t object,
1247c478bd9Sstevel@tonic-gate     void *user)
1257c478bd9Sstevel@tonic-gate {
1267c478bd9Sstevel@tonic-gate 	rval_t	r;
1277c478bd9Sstevel@tonic-gate 	if (flags & PORT_SHARE_EVENT)
1287c478bd9Sstevel@tonic-gate 		r.r_vals = _portfs(PORT_DISPATCH, port, source, events, object,
1297c478bd9Sstevel@tonic-gate 		    (uintptr_t)user);
1307c478bd9Sstevel@tonic-gate 	else
1317c478bd9Sstevel@tonic-gate 		r.r_vals = _portfs(PORT_DISPATCH | PORT_SYS_NOSHARE, port,
1327c478bd9Sstevel@tonic-gate 		    source, events, object, (uintptr_t)user);
1337c478bd9Sstevel@tonic-gate 	return (r.r_val1);
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate int
port_sendn(int ports[],int errors[],uint_t nent,int events,void * user)1377257d1b4Sraf port_sendn(int ports[], int errors[], uint_t nent, int events, void *user)
1387c478bd9Sstevel@tonic-gate {
1397c478bd9Sstevel@tonic-gate 	rval_t	r;
1407c478bd9Sstevel@tonic-gate 	uint_t	offset;
1417c478bd9Sstevel@tonic-gate 	uint_t	lnent;
1427c478bd9Sstevel@tonic-gate 	uint_t	nevents;
1437c478bd9Sstevel@tonic-gate 	if (nent <= PORT_MAX_LIST) {
1447c478bd9Sstevel@tonic-gate 		r.r_vals = _portfs(PORT_SENDN | PORT_SYS_NOPORT,
1457c478bd9Sstevel@tonic-gate 		    (uintptr_t)ports, (uintptr_t)errors, nent, events,
1467c478bd9Sstevel@tonic-gate 		    (uintptr_t)user);
1477c478bd9Sstevel@tonic-gate 		return (r.r_val1);
1487c478bd9Sstevel@tonic-gate 	}
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	/* use chunks of max PORT_MAX_LIST elements per syscall */
1517c478bd9Sstevel@tonic-gate 	nevents = 0;
1527c478bd9Sstevel@tonic-gate 	for (offset = 0; offset < nent; ) {
1537c478bd9Sstevel@tonic-gate 		lnent = nent - offset;
1547c478bd9Sstevel@tonic-gate 		if (nent - offset > PORT_MAX_LIST)
1557c478bd9Sstevel@tonic-gate 			lnent = PORT_MAX_LIST;
1567c478bd9Sstevel@tonic-gate 		else
1577c478bd9Sstevel@tonic-gate 			lnent = nent - offset;
1587c478bd9Sstevel@tonic-gate 		r.r_vals = _portfs(PORT_SENDN | PORT_SYS_NOPORT,
1597c478bd9Sstevel@tonic-gate 		    (uintptr_t)&ports[offset], (uintptr_t)&errors[offset],
1607c478bd9Sstevel@tonic-gate 		    lnent, events, (uintptr_t)user);
1617c478bd9Sstevel@tonic-gate 		if (r.r_val2 == -1) {
1627c478bd9Sstevel@tonic-gate 			/* global error, return last no of events submitted */
1637c478bd9Sstevel@tonic-gate 			if (nevents)
1647c478bd9Sstevel@tonic-gate 				return (nevents);
1657c478bd9Sstevel@tonic-gate 			return (-1);
1667c478bd9Sstevel@tonic-gate 		}
1677c478bd9Sstevel@tonic-gate 		nevents += r.r_val1;
1687c478bd9Sstevel@tonic-gate 		offset += lnent;
1697c478bd9Sstevel@tonic-gate 	}
1707c478bd9Sstevel@tonic-gate 	/* list submitted */
1717c478bd9Sstevel@tonic-gate 	return (nevents);
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate int
port_alert(int port,int flags,int events,void * user)1757257d1b4Sraf port_alert(int port, int flags, int events, void *user)
1767c478bd9Sstevel@tonic-gate {
1777c478bd9Sstevel@tonic-gate 	rval_t	r;
178*e86c3f00SToomas Soome 	r.r_vals = _portfs(PORT_ALERT, port, flags, events, (uintptr_t)user, 0);
1797c478bd9Sstevel@tonic-gate 	return (r.r_val1);
1807c478bd9Sstevel@tonic-gate }
181