1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <sys/select.h> 33 #include <sys/types.h> 34 #include <sys/time.h> 35 #include <sys/poll.h> 36 #include "rpc_mt.h" 37 38 39 /* 40 * Given an fd_set pointer and the number of bits to check in it, 41 * initialize the supplied pollfd array for RPC's use (RPC only 42 * polls for input events). We return the number of pollfd slots 43 * we initialized. 44 */ 45 int 46 __rpc_select_to_poll( 47 int fdmax, /* number of bits we must test */ 48 fd_set *fdset, /* source fd_set array */ 49 struct pollfd *p0) /* target pollfd array */ 50 { 51 int j; /* loop counter */ 52 int n; 53 struct pollfd *p = p0; 54 55 /* 56 * For each fd, if the appropriate bit is set convert it into 57 * the appropriate pollfd struct. 58 */ 59 j = ((fdmax >= FD_SETSIZE) ? FD_SETSIZE : fdmax); 60 for (n = 0; n < j; n++) { 61 if (FD_ISSET(n, fdset)) { 62 p->fd = n; 63 p->events = MASKVAL; 64 p->revents = 0; 65 p++; 66 } 67 } 68 return (p - p0); 69 } 70 71 /* 72 * Arguments are similar to rpc_select_to_poll() except that 73 * the second argument is pointer to an array of pollfd_t 74 * which is the source array which will be compressed and 75 * copied to the target array in p0. The size of the 76 * source argument is given by pollfdmax. The array can be 77 * sparse. The space for the target is allocated before 78 * calling this function. It should have atleast pollfdmax 79 * elements. This function scans the source pollfd array 80 * and copies only the valid ones to the target p0. 81 */ 82 int 83 __rpc_compress_pollfd(int pollfdmax, pollfd_t *srcp, pollfd_t *p0) 84 { 85 int n; 86 pollfd_t *p = p0; 87 88 for (n = 0; n < pollfdmax; n++) { 89 if (POLLFD_ISSET(n, srcp)) { 90 p->fd = srcp[n].fd; 91 p->events = srcp[n].events; 92 p->revents = 0; 93 p++; 94 } 95 } 96 return (p - p0); 97 } 98 99 /* 100 * Convert from timevals (used by select) to milliseconds (used by poll). 101 */ 102 int 103 __rpc_timeval_to_msec(struct timeval *t) 104 { 105 int t1, tmp; 106 107 /* 108 * We're really returning t->tv_sec * 1000 + (t->tv_usec / 1000) 109 * but try to do so efficiently. Note: 1000 = 1024 - 16 - 8. 110 */ 111 tmp = (int)t->tv_sec << 3; 112 t1 = -tmp; 113 t1 += t1 << 1; 114 t1 += tmp << 7; 115 if (t->tv_usec) 116 t1 += t->tv_usec / 1000; 117 118 return (t1); 119 } 120