8354 sync regcomp(3C) with upstream (fix make catalog)
[unleashed/tickless.git] / usr / src / lib / libnsl / nsl / t_rcvvudata.c
blob3027a92dbbd8b341238bdd6979af12292f36d09c
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
24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 #pragma ident "%Z%%M% %I% %E% SMI"
31 * t_rcvudata.c and t_rcvvudata.c are very similar and contain common code.
32 * Any changes to either of them should be reviewed to see whether they
33 * are applicable to the other file.
35 #include "mt.h"
36 #include <string.h>
37 #include <stdlib.h>
38 #include <errno.h>
39 #include <stropts.h>
40 #include <sys/stream.h>
41 #define _SUN_TPI_VERSION 2
42 #include <sys/tihdr.h>
43 #include <sys/timod.h>
44 #include <xti.h>
45 #include <syslog.h>
46 #include <assert.h>
47 #include "tx.h"
50 int
51 _tx_rcvvudata(
52 int fd,
53 struct t_unitdata *unitdata,
54 struct t_iovec *tiov,
55 unsigned int tiovcount,
56 int *flags,
57 int api_semantics
60 struct strbuf ctlbuf;
61 struct strbuf databuf;
62 char *dataptr;
63 int retval;
64 union T_primitives *pptr;
65 struct _ti_user *tiptr;
66 int sv_errno;
67 int didalloc;
68 int flg = 0;
69 unsigned int nbytes;
71 assert(api_semantics == TX_XTI_XNS5_API);
73 if (tiovcount == 0 || tiovcount > T_IOV_MAX) {
74 t_errno = TBADDATA;
75 return (-1);
78 if ((tiptr = _t_checkfd(fd, 0, api_semantics)) == NULL)
79 return (-1);
80 sig_mutex_lock(&tiptr->ti_lock);
82 if (tiptr->ti_servtype != T_CLTS) {
83 t_errno = TNOTSUPPORT;
84 sig_mutex_unlock(&tiptr->ti_lock);
85 return (-1);
88 if (tiptr->ti_state != T_IDLE) {
89 t_errno = TOUTSTATE;
90 sig_mutex_unlock(&tiptr->ti_lock);
91 return (-1);
95 * check if there is something in look buffer
97 if (tiptr->ti_lookcnt > 0) {
98 sig_mutex_unlock(&tiptr->ti_lock);
99 t_errno = TLOOK;
100 return (-1);
104 * Acquire ctlbuf for use in sending/receiving control part
105 * of the message.
107 if (_t_acquire_ctlbuf(tiptr, &ctlbuf, &didalloc) < 0) {
108 sv_errno = errno;
109 sig_mutex_unlock(&tiptr->ti_lock);
110 errno = sv_errno;
111 return (-1);
114 *flags = 0;
116 nbytes = _t_bytecount_upto_intmax(tiov, tiovcount);
117 dataptr = NULL;
118 if (nbytes != 0 && ((dataptr = malloc(nbytes)) == NULL)) {
119 t_errno = TSYSERR;
120 goto err_out;
123 databuf.maxlen = nbytes;
124 databuf.len = 0;
125 databuf.buf = dataptr;
128 * This is a call that may block indefinitely so we drop the
129 * lock and allow signals in MT case here and reacquire it.
130 * Error case should roll back state changes done above
131 * (happens to be no state change here)
133 sig_mutex_unlock(&tiptr->ti_lock);
134 if ((retval = getmsg(fd, &ctlbuf, &databuf, &flg)) < 0) {
135 if (errno == EAGAIN)
136 t_errno = TNODATA;
137 else
138 t_errno = TSYSERR;
139 sv_errno = errno;
140 sig_mutex_lock(&tiptr->ti_lock);
141 errno = sv_errno;
142 goto err_out;
144 sig_mutex_lock(&tiptr->ti_lock);
147 * is there control piece with data?
149 if (ctlbuf.len > 0) {
150 if (ctlbuf.len < (int)sizeof (t_scalar_t)) {
151 t_errno = TSYSERR;
152 errno = EPROTO;
153 goto err_out;
156 /* LINTED pointer cast */
157 pptr = (union T_primitives *)ctlbuf.buf;
159 switch (pptr->type) {
161 case T_UNITDATA_IND:
162 if ((ctlbuf.len <
163 (int)sizeof (struct T_unitdata_ind)) ||
164 (pptr->unitdata_ind.OPT_length &&
165 (ctlbuf.len < (int)(pptr->unitdata_ind.OPT_length
166 + pptr->unitdata_ind.OPT_offset)))) {
167 t_errno = TSYSERR;
168 errno = EPROTO;
169 goto err_out;
172 if (unitdata->addr.maxlen > 0) {
173 if (TLEN_GT_NLEN(pptr->unitdata_ind.SRC_length,
174 unitdata->addr.maxlen)) {
175 t_errno = TBUFOVFLW;
176 goto err_out;
178 (void) memcpy(unitdata->addr.buf,
179 ctlbuf.buf + pptr->unitdata_ind.SRC_offset,
180 (size_t)pptr->unitdata_ind.SRC_length);
181 unitdata->addr.len =
182 pptr->unitdata_ind.SRC_length;
184 if (unitdata->opt.maxlen > 0) {
185 if (TLEN_GT_NLEN(pptr->unitdata_ind.OPT_length,
186 unitdata->opt.maxlen)) {
187 t_errno = TBUFOVFLW;
188 goto err_out;
190 (void) memcpy(unitdata->opt.buf, ctlbuf.buf +
191 pptr->unitdata_ind.OPT_offset,
192 (size_t)pptr->unitdata_ind.OPT_length);
193 unitdata->opt.len =
194 pptr->unitdata_ind.OPT_length;
196 if (retval & MOREDATA)
197 *flags |= T_MORE;
199 * No state changes happens on T_RCVUDATA
200 * event (NOOP). We do it only to log errors.
202 _T_TX_NEXTSTATE(T_RCVUDATA, tiptr,
203 "t_rcvvudata: invalid state event T_RCVUDATA");
205 if (didalloc)
206 free(ctlbuf.buf);
207 else
208 tiptr->ti_ctlbuf = ctlbuf.buf;
209 _t_scatter(&databuf, tiov, tiovcount);
210 if (dataptr != NULL)
211 free(dataptr);
212 sig_mutex_unlock(&tiptr->ti_lock);
213 return (databuf.len);
215 case T_UDERROR_IND:
216 if (_t_register_lookevent(tiptr, 0, 0, ctlbuf.buf,
217 ctlbuf.len) < 0) {
218 t_errno = TSYSERR;
219 errno = ENOMEM;
220 goto err_out;
222 t_errno = TLOOK;
223 goto err_out;
225 default:
226 break;
229 t_errno = TSYSERR;
230 errno = EPROTO;
231 goto err_out;
233 } else { /* else part of "if (ctlbuf.len > 0)" */
234 unitdata->addr.len = 0;
235 unitdata->opt.len = 0;
237 * only data in message no control piece
239 if (retval & MOREDATA)
240 *flags = T_MORE;
242 * No state transition occurs on
243 * event T_RCVUDATA. We do it only to
244 * log errors.
246 _T_TX_NEXTSTATE(T_RCVUDATA, tiptr,
247 "t_rcvvudata: invalid state event T_RCVUDATA");
248 if (didalloc)
249 free(ctlbuf.buf);
250 else
251 tiptr->ti_ctlbuf = ctlbuf.buf;
252 _t_scatter(&databuf, tiov, tiovcount);
253 if (dataptr != NULL)
254 free(dataptr);
255 sig_mutex_unlock(&tiptr->ti_lock);
256 return (databuf.len);
258 /* NOTREACHED */
259 err_out:
260 sv_errno = errno;
261 if (didalloc)
262 free(ctlbuf.buf);
263 else
264 tiptr->ti_ctlbuf = ctlbuf.buf;
265 if (dataptr != NULL)
266 free(dataptr);
267 sig_mutex_unlock(&tiptr->ti_lock);
268 errno = sv_errno;
269 return (-1);