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
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]
23 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
24 /* All Rights Reserved */
27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.5 */
38 #include <sys/stream.h>
39 #define _SUN_TPI_VERSION 2
40 #include <sys/tihdr.h>
41 #include <sys/timod.h>
48 _tx_rcvuderr(int fd
, struct t_uderr
*uderr
, int api_semantics
)
50 struct strbuf ctlbuf
, databuf
;
53 union T_primitives
*pptr
;
54 struct _ti_user
*tiptr
;
60 if ((tiptr
= _t_checkfd(fd
, 0, api_semantics
)) == NULL
)
62 sig_mutex_lock(&tiptr
->ti_lock
);
64 if (tiptr
->ti_servtype
!= T_CLTS
) {
65 t_errno
= TNOTSUPPORT
;
66 sig_mutex_unlock(&tiptr
->ti_lock
);
70 * is there a unitdata error indication in look buffer
72 if (tiptr
->ti_lookcnt
> 0) {
73 ctlbuf
.len
= tiptr
->ti_lookbufs
.tl_lookclen
;
74 ctlbuf
.buf
= tiptr
->ti_lookbufs
.tl_lookcbuf
;
75 /* Note: cltbuf.maxlen not used in this case */
77 /* LINTED pointer cast */
78 assert(((union T_primitives
*)ctlbuf
.buf
)->type
88 if ((retval
= _t_look_locked(fd
, tiptr
, 0,
89 api_semantics
)) < 0) {
91 sig_mutex_unlock(&tiptr
->ti_lock
);
95 if (retval
!= T_UDERR
) {
97 sig_mutex_unlock(&tiptr
->ti_lock
);
102 * Acquire ctlbuf for use in sending/receiving control part
105 if (_t_acquire_ctlbuf(tiptr
, &ctlbuf
, &didalloc
) < 0) {
107 sig_mutex_unlock(&tiptr
->ti_lock
);
119 * Since we already verified that a unitdata error
120 * indication is pending, we assume that this getmsg()
121 * will not block indefinitely.
123 if ((retval
= getmsg(fd
, &ctlbuf
, &databuf
, &flg
)) < 0) {
129 * did I get entire message?
139 /* LINTED pointer cast */
140 pptr
= (union T_primitives
*)ctlbuf
.buf
;
142 if ((ctlbuf
.len
< (int)sizeof (struct T_uderror_ind
)) ||
143 (pptr
->type
!= T_UDERROR_IND
)) {
150 if (_T_IS_TLI(api_semantics
) || uderr
->addr
.maxlen
> 0) {
151 if (TLEN_GT_NLEN(pptr
->uderror_ind
.DEST_length
,
152 uderr
->addr
.maxlen
)) {
156 (void) memcpy(uderr
->addr
.buf
, ctlbuf
.buf
+
157 pptr
->uderror_ind
.DEST_offset
,
158 (size_t)pptr
->uderror_ind
.DEST_length
);
160 (unsigned int)pptr
->uderror_ind
.DEST_length
;
162 if (_T_IS_TLI(api_semantics
) || uderr
->addr
.maxlen
> 0) {
163 if (TLEN_GT_NLEN(pptr
->uderror_ind
.OPT_length
,
164 uderr
->opt
.maxlen
)) {
168 (void) memcpy(uderr
->opt
.buf
, ctlbuf
.buf
+
169 pptr
->uderror_ind
.OPT_offset
,
170 (size_t)pptr
->uderror_ind
.OPT_length
);
172 (unsigned int)pptr
->uderror_ind
.OPT_length
;
174 uderr
->error
= pptr
->uderror_ind
.ERROR_type
;
177 _T_TX_NEXTSTATE(T_RCVUDERR
, tiptr
,
178 "t_rcvuderr: invalid state event T_RCVUDERR");
180 _t_free_looklist_head(tiptr
);
185 tiptr
->ti_ctlbuf
= ctlbuf
.buf
;
187 sig_mutex_unlock(&tiptr
->ti_lock
);
194 _t_free_looklist_head(tiptr
);
199 tiptr
->ti_ctlbuf
= ctlbuf
.buf
;
201 sig_mutex_unlock(&tiptr
->ti_lock
);