import less(1)
[unleashed/tickless.git] / usr / src / lib / libc / port / nsl / t_look.c
blob2a91d3da6b9f544f355e0fab9a24f5d21c522c38
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
24 /* All Rights Reserved */
27 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 * Copyright 2014 Gary Mills
32 #include "mt.h"
33 #include <errno.h>
34 #include <unistd.h>
35 #include <sys/stream.h>
36 #include <stropts.h>
37 #define _SUN_TPI_VERSION 2
38 #include <sys/tihdr.h>
39 #include <sys/timod.h>
40 #include <xti.h>
41 #include <assert.h>
42 #include "tx.h"
44 int
45 _tx_look(int fd, int api_semantics)
47 int state;
48 int sv_errno;
49 int do_expinline_peek; /* unusual XTI specific processing */
50 struct _ti_user *tiptr;
52 if ((tiptr = _t_checkfd(fd, 0, api_semantics)) == NULL)
53 return (-1);
54 sig_mutex_lock(&tiptr->ti_lock);
56 if (_T_IS_XTI(api_semantics))
57 do_expinline_peek = 1;
58 else
59 do_expinline_peek = 0;
60 state = _t_look_locked(fd, tiptr, do_expinline_peek, api_semantics);
62 sv_errno = errno;
64 sig_mutex_unlock(&tiptr->ti_lock);
65 errno = sv_errno;
66 return (state);
70 * _t_look_locked() assumes tiptr->ti_lock lock is already held and signals
71 * already blocked in MT case.
72 * Intended for use by other TLI routines only.
74 int
75 _t_look_locked(
76 int fd,
77 struct _ti_user *tiptr,
78 int do_expinline_peek,
79 int api_semantics
82 struct strpeek strpeek;
83 int retval;
84 union T_primitives *pptr;
85 t_scalar_t type;
86 t_scalar_t ctltype;
88 assert(MUTEX_HELD(&tiptr->ti_lock));
90 #ifdef notyet
91 if (_T_IS_XTI(api_semantics)) {
93 * XTI requires the strange T_GODATA and T_GOEXDATA
94 * events which are almost brain-damaged but thankfully
95 * not tested. Anyone feeling the need for those should
96 * consider the need for using non-blocking endpoint.
97 * Probably introduced at the behest of some weird-os
98 * vendor which did not understand the non-blocking endpoint
99 * option.
100 * We choose not to implment these mis-features.
101 * Here is the plan-of-action (POA)if we are ever forced
102 * to implement these.
103 * - When returning TFLOW set state to indicate if it was
104 * a normal or expedited data send attempt.
105 * - In routines that set TFLOW, clear the above set state
106 * on each entry/reentry
107 * - In this routine, if that state flag is set,
108 * do a I_CANPUT on appropriate band to to see if it
109 * is writeable. If that indicates that the band is
110 * writeable, return T_GODATA or T_GOEXDATA event.
112 * Actions are also influenced by whether T_EXDATA_REQ stays
113 * band 1 or goes to band 0 if EXPINLINE is set
115 * We will also need to sort out if "write side" events
116 * (such as T_GODATA/T_GOEXDATA) take precedence over
117 * all other events (all read side) or not.
120 #endif /* notyet */
122 strpeek.ctlbuf.maxlen = (int)sizeof (ctltype);
123 strpeek.ctlbuf.len = 0;
124 strpeek.ctlbuf.buf = (char *)&ctltype;
125 strpeek.databuf.maxlen = 0;
126 strpeek.databuf.len = 0;
127 strpeek.databuf.buf = NULL;
128 strpeek.flags = 0;
130 do {
131 retval = ioctl(fd, I_PEEK, &strpeek);
132 } while (retval < 0 && errno == EINTR);
134 if (retval < 0) {
136 * XTI semantics (also identical to documented
137 * TLI semantics).
139 t_errno = TSYSERR;
140 return (-1);
144 * if something there and cntl part also there
146 if ((tiptr->ti_lookcnt > 0) ||
147 ((retval > 0) && (strpeek.ctlbuf.len >=
148 (int)sizeof (t_scalar_t)))) {
149 /* LINTED pointer cast */
150 pptr = (union T_primitives *)strpeek.ctlbuf.buf;
151 if (tiptr->ti_lookcnt > 0) {
152 /* LINTED pointer cast */
153 type = *((t_scalar_t *)tiptr->ti_lookbufs.tl_lookcbuf);
155 * If message on stream head is a T_DISCON_IND, that
156 * has priority over a T_ORDREL_IND in the look
157 * buffer.
158 * (This assumes that T_ORDREL_IND can only be in the
159 * first look buffer in the list)
161 if ((type == T_ORDREL_IND) && retval &&
162 (pptr->type == T_DISCON_IND)) {
163 type = pptr->type;
165 * Blow away T_ORDREL_IND
167 _t_free_looklist_head(tiptr);
169 } else
170 type = pptr->type;
172 switch (type) {
174 case T_CONN_IND:
175 return (T_LISTEN);
177 case T_CONN_CON:
178 return (T_CONNECT);
180 case T_DISCON_IND:
181 return (T_DISCONNECT);
183 case T_DATA_IND: {
184 int event = T_DATA;
185 int retval, exp_on_q;
187 if (do_expinline_peek &&
188 (tiptr->ti_prov_flag & EXPINLINE)) {
189 assert(_T_IS_XTI(api_semantics));
190 retval = _t_expinline_queued(fd, &exp_on_q);
191 if (retval < 0) {
192 t_errno = TSYSERR;
193 return (-1);
195 if (exp_on_q)
196 event = T_EXDATA;
198 return (event);
201 case T_UNITDATA_IND:
202 return (T_DATA);
204 case T_EXDATA_IND:
205 return (T_EXDATA);
207 case T_UDERROR_IND:
208 return (T_UDERR);
210 case T_ORDREL_IND:
211 return (T_ORDREL);
213 default:
214 t_errno = TSYSERR;
215 errno = EPROTO;
216 return (-1);
221 * if something there put no control part
222 * it must be data on the stream head.
224 if ((retval > 0) && (strpeek.ctlbuf.len <= 0)) {
225 int event = T_DATA;
226 int retval, exp_on_q;
228 if (do_expinline_peek &&
229 (tiptr->ti_prov_flag & EXPINLINE)) {
230 assert(_T_IS_XTI(api_semantics));
231 retval = _t_expinline_queued(fd, &exp_on_q);
232 if (retval < 0)
233 return (-1);
234 if (exp_on_q)
235 event = T_EXDATA;
237 return (event);
241 * if msg there and control
242 * part not large enough to determine type?
243 * it must be illegal TLI message
245 if ((retval > 0) && (strpeek.ctlbuf.len > 0)) {
246 t_errno = TSYSERR;
247 errno = EPROTO;
248 return (-1);
250 return (0);