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 * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.8 */ 32 /* LINTLIBRARY */ 33 34 # include <errno.h> 35 # include <string.h> 36 # include <stropts.h> 37 38 # include "lp.h" 39 # include "msgs.h" 40 41 int Lp_prio_msg = 0; 42 43 static int _mwrite ( MESG * md , char * msgbuf , int ); 44 45 /* 46 * mflush() 47 * return 0 48 * if it successfully writes all the queued message(s), or 49 * if some of them (errno is EAGAIN in this case). 50 * return -1 (with errno) when it failed. 51 */ 52 53 int 54 mflush(MESG *md) 55 { 56 MQUE *p; 57 58 errno = 0; 59 if (md == NULL || md->mque == NULL) { 60 errno = ENXIO; 61 return (-1); 62 } 63 64 while ((p = md->mque) != NULL) { 65 if (_mwrite(md, p->dat->buf, p->dat->len) != 0) 66 return (errno == EAGAIN ? 0 : -1); 67 68 /* mwrite successful, get the next and free this entry */ 69 md->mque = p->next; 70 Free(p->dat->buf); 71 Free(p->dat); 72 Free(p); 73 } 74 75 return (0); 76 } 77 78 /* 79 * mwrite() 80 * return 0 81 * if it successfully writes the messages, or 82 * if it has been queued (errno is EAGAIN in this case) 83 * and md->mque is updated. 84 * return -1 (with errno) when it failed. 85 */ 86 87 int mwrite ( MESG * md, char * msgbuf ) 88 { 89 short size; 90 MQUE * p; 91 MQUE * q; 92 93 errno = 0; 94 if (md == NULL) 95 { 96 errno = ENXIO; 97 return(-1); 98 } 99 if (msgbuf == NULL) 100 { 101 errno = EINVAL; 102 return(-1); 103 } 104 105 size = stoh(msgbuf); 106 107 if (LAST_MESSAGE < stoh(msgbuf + MESG_TYPE)) 108 { 109 errno = EINVAL; 110 return (-1); 111 } 112 if (md->mque) 113 goto queue; /* if there is a queue already, try to write all */ 114 115 if (_mwrite(md, msgbuf, size) == 0) 116 return(0); 117 118 if (errno != EAGAIN) 119 return(-1); 120 121 /* 122 * fall through to queue the messages that cannot be sent now. 123 */ 124 125 queue: 126 if ((p = (MQUE *)Malloc(sizeof(MQUE))) == NULL 127 || (p->dat = (struct strbuf *)Malloc(sizeof(struct strbuf))) == NULL 128 || (p->dat->buf = (char *)Malloc(size)) == NULL) 129 { 130 errno = ENOMEM; 131 return(-1); 132 } 133 (void) memcpy(p->dat->buf, msgbuf, size); 134 p->dat->len = size; 135 p->next = 0; 136 137 if ((q = md->mque) != NULL) 138 { 139 /* insert the new one to tail */ 140 while (q->next) 141 q = q->next; 142 q->next = p; 143 144 while ((p = md->mque) != NULL) 145 { 146 if (_mwrite(md, p->dat->buf, p->dat->len) != 0) { 147 return (errno == EAGAIN ? 0 : -1); 148 } 149 150 /* mwrite successful, get the next and free this entry */ 151 md->mque = p->next; 152 Free(p->dat->buf); 153 Free(p->dat); 154 Free(p); 155 } 156 } 157 else 158 md->mque = p; 159 160 return(0); 161 } 162 163 int _mwrite ( MESG * md, char * msgbuf , int size ) 164 { 165 int flag = 0; 166 struct strbuf ctl; 167 struct strbuf dat; 168 169 switch (md->type) 170 { 171 case MD_CHILD: 172 case MD_STREAM: 173 case MD_BOUND: 174 if (size <= 0 || size > MSGMAX) 175 { 176 errno = EINVAL; 177 return(-1); 178 } 179 180 ctl.buf = "xyzzy"; 181 ctl.maxlen = ctl.len = strlen(ctl.buf)+1; 182 dat.buf = msgbuf; 183 dat.maxlen = dat.len = size; 184 flag = Lp_prio_msg; 185 Lp_prio_msg = 0; /* clean this up so there are no surprises */ 186 187 if (Putmsg(md, &ctl, &dat, flag) == 0) 188 return(0); 189 return(-1); 190 191 case MD_SYS_FIFO: 192 case MD_USR_FIFO: 193 switch (write3_2(md, msgbuf, size)) 194 { 195 case -1: 196 return(-1); 197 case 0: 198 break; 199 default: 200 return(0); 201 } 202 break; 203 204 default: 205 errno = EINVAL; 206 return(-1); 207 } 208 return 0; 209 } 210