35 #include <sys/types.h> |
35 #include <sys/types.h> |
36 #include <sys/systm.h> |
36 #include <sys/systm.h> |
37 #include <sys/errno.h> |
37 #include <sys/errno.h> |
38 #include <sys/stream.h> |
38 #include <sys/stream.h> |
39 #include <sys/stropts.h> |
39 #include <sys/stropts.h> |
|
40 #include <sys/strsubr.h> |
40 #include <sys/strsun.h> |
41 #include <sys/strsun.h> |
|
42 #include <sys/sysmacros.h> |
41 #include <sys/cmn_err.h> |
43 #include <sys/cmn_err.h> |
42 |
44 |
43 void |
45 void |
44 merror(queue_t *wq, mblk_t *mp, int error) |
46 merror(queue_t *wq, mblk_t *mp, int error) |
45 { |
47 { |
241 |
243 |
242 iocmp->b_cont = newdatamp; |
244 iocmp->b_cont = newdatamp; |
243 freemsg(datamp); |
245 freemsg(datamp); |
244 return (0); |
246 return (0); |
245 } |
247 } |
|
248 |
|
249 /* Copy userdata into a new mblk_t */ |
|
250 mblk_t * |
|
251 mcopyinuio(struct stdata *stp, uio_t *uiop, ssize_t iosize, |
|
252 ssize_t maxblk, int *errorp) |
|
253 { |
|
254 mblk_t *head = NULL, **tail = &head; |
|
255 size_t offset = stp->sd_wroff; |
|
256 |
|
257 if (iosize == INFPSZ || iosize > uiop->uio_resid) |
|
258 iosize = uiop->uio_resid; |
|
259 |
|
260 if (maxblk == INFPSZ) |
|
261 maxblk = iosize; |
|
262 |
|
263 /* Nothing to do in these cases, so we're done */ |
|
264 if (iosize < 0 || maxblk < 0 || (maxblk == 0 && iosize > 0)) |
|
265 goto done; |
|
266 |
|
267 if (stp->sd_flag & STRCOPYCACHED) |
|
268 uiop->uio_extflg |= UIO_COPY_CACHED; |
|
269 |
|
270 /* |
|
271 * We will enter the loop below if iosize is 0; it will allocate an |
|
272 * empty message block and call uiomove(9F) which will just return. |
|
273 * We could avoid that with an extra check but would only slow |
|
274 * down the much more likely case where iosize is larger than 0. |
|
275 */ |
|
276 do { |
|
277 ssize_t blocksize; |
|
278 mblk_t *mp; |
|
279 |
|
280 blocksize = MIN(iosize, maxblk); |
|
281 ASSERT(blocksize >= 0); |
|
282 if ((mp = allocb_cred(offset + blocksize, CRED())) == NULL) { |
|
283 *errorp = ENOMEM; |
|
284 return (head); |
|
285 } |
|
286 mp->b_rptr += offset; |
|
287 mp->b_wptr = mp->b_rptr + blocksize; |
|
288 DB_CPID(mp) = curproc->p_pid; |
|
289 |
|
290 *tail = mp; |
|
291 tail = &mp->b_cont; |
|
292 |
|
293 /* uiomove(9F) either returns 0 or EFAULT */ |
|
294 if ((*errorp = uiomove(mp->b_rptr, (size_t)blocksize, |
|
295 UIO_WRITE, uiop)) != 0) { |
|
296 ASSERT(*errorp != ENOMEM); |
|
297 freemsg(head); |
|
298 return (NULL); |
|
299 } |
|
300 |
|
301 iosize -= blocksize; |
|
302 } while (iosize > 0); |
|
303 |
|
304 done: |
|
305 *errorp = 0; |
|
306 return (head); |
|
307 } |