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