|
|
1.1 root 1: #define _DDI_DKI 1
2: #define _DDI_DKI_IMPL 1
3: #define _SYSV4 1
4:
5: /*
6: */
7:
8: #include <common/ccompat.h>
9: #include <kernel/fhsys.h>
10: #include <kernel/strmlib.h>
11: #include <sys/confinfo.h>
12: #include <sys/types.h>
13: #include <sys/kmem.h>
14: #include <sys/poll.h>
15: #include <sys/ksynch.h>
16: #include <sys/file.h>
17: #include <sys/uio.h>
18: #include <sys/cmn_err.h>
19: #include <sys/errno.h>
20: #include <sys/signal.h>
21: #include <stropts.h>
22: #include <string.h>
23: #include <poll.h>
24:
25: /*
26: * The following function (local to this module) is forward-referenced due to
27: * the mutual recursion between the final close process and the streams unlink
28: * code.
29: */
30:
31: __LOCAL__ int SHEAD_DO_CLOSE __PROTO ((shead_t * sheadp, int mode,
32: cred_t * credp));
33:
34:
35: lkinfo_t __stream_schedule_lkinfo = {
36: "STREAMS queue schedule", INTERNAL_LOCK
37: };
38:
39: lkinfo_t __stream_event_lkinfo = {
40: "STREAMS bufcall ()/esbbcall () event list", INTERNAL_LOCK
41: };
42:
43: __LOCAL__ lkinfo_t _stream_head_lkinfo = {
44: "stream head lock", INTERNAL_LOCK
45: };
46:
47:
48: /*
49: * Allocate and initialize a queue pair. This function only performs a partial
50: * initialization; many other fields are filled in by the caller, usually from
51: * fields supplied in the "streamtab" structure.
52: *
53: * Since at initial stream open time we we be allocating at least two queue
54: * pairs and one or two stream head structures, we try to satisfy all those
55: * allocations in one step here.
56: *
57: * The "npairs" argument indicates the number of queue pairs to be allocated.
58: * The "extra" argument is the number of additional bytes to allocate over and
59: * above the memory for the queue pairs.
60: *
61: * Call only from base level. This function may sleep.
62: */
63:
64: #if __USE_PROTO__
65: __LOCAL__ queue_t * (QUEUE_ALLOC) (int npairs, size_t extra)
66: #else
67: __LOCAL__ queue_t *
68: QUEUE_ALLOC __ARGS ((npairs, extra))
69: int npairs;
70: size_t extra;
71: #endif
72: {
73: queue_t * q;
74: queue_t * init;
75: int count;
76:
77: ASSERT (npairs > 0 && npairs < 3);
78:
79: /*
80: * We use kmem_zalloc () to allocate this space so we can sleaze our
81: * way out of most of the initialization work.
82: */
83:
84: if ((q = (queue_t *) kmem_zalloc (2 * npairs * sizeof (* q) + extra,
85: KM_SLEEP)) == NULL)
86: return NULL;
87:
88: init = q;
89: count = npairs;
90:
91: do {
92: /*
93: * First, initialise the read side of the queue. While we are
94: * at it, we link the "q_next" members of multiple queues for
95: * a read side; if we treat the value "q" that we are going to
96: * return to the caller as the stream head, the links run from
97: * the last entry we initialize towards the first one.
98: */
99:
100: if (count > 1)
101: (init + 2)->q_next = init;
102:
103: init->q_flag = QWANTR | QREADR | QPROCSOFF;
104:
105: SFREEZE_INIT (init);
106:
107: init ++;
108:
109:
110: /*
111: * Next, work on the write side. For multiple queues, the
112: * write size "q_next" links run from the "head" to the device.
113: */
114:
115: if (count > 1)
116: init->q_next = init + 2;
117:
118: init->q_flag = QWANTR | QPROCSOFF;
119:
120: SFREEZE_INIT (init);
121:
122: init ++;
123: } while (-- count > 0);
124:
125:
126: /*
127: * We put a pointer to any "extra" space that the caller requested in
128: * the "q_ptr" fields of the first two queues allocated, since they
129: * will almost always be the stream head queue pair.
130: */
131:
132: if (extra > 0) {
133:
134: q->q_ptr = (char *) q + 2 * sizeof (* q) * npairs;
135: W (q)->q_ptr = q->q_ptr;
136: }
137:
138: return q;
139: }
140:
141:
142: /*
143: * Set a queue's initial watermark data and some other stuff.
144: */
145:
146: #if __USE_PROTO__
147: __LOCAL__ void (QUEUE_INITOPT) (queue_t * q)
148: #else
149: __LOCAL__ void
150: QUEUE_INITOPT __ARGS ((q))
151: queue_t * q;
152: #endif
153: {
154: struct module_info
155: * mi = q->q_qinfo->qi_minfo;
156:
157: q->q_minpsz = mi->mi_minpsz;
158: q->q_maxpsz = mi->mi_maxpsz;
159: q->q_hiwat = mi->mi_hiwat;
160: q->q_lowat = mi->mi_lowat;
161: }
162:
163:
164: /*
165: * Set up a queue pair's initial options.
166: */
167:
168: typedef enum {
169: QI_NORMAL,
170: QI_MUX
171: } qiflag_t;
172:
173: #if __USE_PROTO__
174: __LOCAL__ void (QUEUE_INIT) (queue_t * q, struct streamtab * stab,
175: qiflag_t mux)
176: #else
177: void
178: QUEUE_INIT __ARGS ((q, stab, mux))
179: queue_t * q;
180: struct streamtab
181: * stab;
182: qiflag_t mux;
183: #endif
184: {
185: q->q_qinfo = mux == QI_NORMAL ? stab->st_rdinit : stab->st_muxrinit;
186: QUEUE_INITOPT (q);
187:
188: q = W (q);
189:
190: q->q_qinfo = mux == QI_NORMAL ? stab->st_wrinit : stab->st_muxwinit;
191: QUEUE_INITOPT (q);
192: }
193:
194:
195: /*
196: * This function is the dual to the QBAND_ALLOC () function, freeing any
197: * allocated "qband" structures associated with the given queue.
198: *
199: * The caller must have the queue frozen or not linked on any stream.
200: */
201:
202: #if __USE_PROTO__
203: void (QBAND_FREE) (queue_t * q)
204: #else
205: void
206: QBAND_FREE __ARGS ((q))
207: queue_t * q;
208: #endif
209: {
210: qband_t * scan;
211: qband_t * prev;
212: int nbands;
213:
214: QUEUE_TRACE (q, "QBAND_FREE");
215:
216: /*
217: * We use flags in the "qband" entries to locate allocation
218: * boundaries rather than trying to recover this information purely
219: * from comparing addresses (although since the address comparisons
220: * provide an extra check we do that too). In theory, an allocator
221: * might not need extra information stored in the arena yet might
222: * fail if adjacent allocations are coalesced into a single free ().
223: *
224: * I don't know of any allocators with this property, but one might
225: * exist.
226: *
227: * This code will work just fine under the allocation scheme which
228: * keeps the QBAND entries in a single vector, so we don't need to
229: * conditionalize this code at all.
230: */
231:
232: nbands = 0;
233:
234: for (prev = scan = q->q_bandp ; scan != NULL ; scan = scan->qb_next) {
235:
236: if ((scan->qb_flag & QB_FIRST) != 0) {
237:
238: ASSERT (nbands > 0);
239:
240: kmem_free (prev, sizeof (* prev) * nbands);
241:
242: nbands = 1;
243: prev = scan;
244: } else {
245:
246: ASSERT (scan == prev + nbands);
247: nbands ++;
248: }
249: }
250:
251: if (nbands > 0)
252: kmem_free (prev, sizeof (* prev) * nbands);
253: }
254:
255:
256: /*
257: * Destroy an individual queue.
258: */
259:
260: #if __USE_PROTO__
261: __LOCAL__ void (QUEUE_DESTROY) (queue_t * q)
262: #else
263: __LOCAL__ void
264: QUEUE_DESTROY __ARGS ((q))
265: queue_t * q;
266: #endif
267: {
268: mblk_t * mp;
269: mblk_t * next;
270:
271: QSCHED_UNSCHEDULE (q, str_mem->sm_sched);
272:
273: /*
274: * Free all the memory allocated to messages that remain on the queue.
275: */
276:
277: for (mp = q->q_first ; mp != NULL ; mp = next) {
278:
279: next = mp->b_next;
280: freemsg (mp);
281: }
282:
283: if ((q->q_flag & QWANTW) != 0)
284: QUEUE_BACKENAB (q);
285:
286: SFREEZE_DESTROY (q);
287:
288: if (q->q_nband > 0)
289: QBAND_FREE (q);
290: }
291:
292:
293: /*
294: * Destroy and release the memory for a queue pair or group of pairs. The
295: * arguments passed to this function should match those used to allocate a
296: * pair or group of pairs exactly. This can easily be done by recognising the
297: * various canonical forms for stream structures; modules are always lone
298: * queue pairs, regular streams match a driver and stream head (with
299: * associated extra data for the stream head), and stream pipes consist of
300: * two pairs of queue structures with two head structures.
301: */
302:
303: #if __USE_PROTO__
304: __LOCAL__ void (QUEUE_FREE) (queue_t * rq, int npairs, size_t extra)
305: #else
306: __LOCAL__ void
307: QUEUE_FREE __ARGS ((rq, npairs, extra))
308: queue_t * rq;
309: int npairs;
310: size_t extra;
311: #endif
312: {
313: queue_t * destroy;
314: int count;
315:
316: ASSERT (rq != NULL);
317: ASSERT (npairs > 0 && npairs < 3);
318:
319: destroy = rq;
320: count = npairs * 2;
321:
322: do {
323:
324: QUEUE_DESTROY (destroy);
325: destroy ++;
326: } while (-- count > 0);
327:
328: kmem_free (rq, 2 * sizeof (* rq) * npairs + extra);
329: }
330:
331:
332: /*
333: * STREAM HEAD MANAGEMENT NOTES:
334: *
335: * The management of stream head structures introduces some interesting
336: * synchronization problems arising from the interaction of the rules
337: * associated with driver close routines and the fact that stream head
338: * structures are dynamically allocated.
339: *
340: * The first problem is really one of specification; what does it mean for a
341: * driver close () entry point to return EINTR? System V does not talk about
342: * this case specifically, so we prohibit it by treating error returns from
343: * the close () entry point uniformly by still actually closing the device.
344: *
345: * The second problem is this; a driver should not be re-opened until the
346: * close process has completed. However, completion of the close process will
347: * normally involve deallocation of the stream head (where presumably the
348: * open routines are waiting).
349: *
350: * Our problem is that it is not possible to reliably determine whether there
351: * are any other contexts waiting on a sleep lock. While it might be possible
352: * to do so using SLEEP_LOCKAVAIL (), this would require that the calling
353: * context release the lock. Under a plausible implementation of SLEEP_LOCK ()
354: * where sleep locks are basically implemented with the sleep () and wakeup ()
355: * functions and a "locked" flag, there will be no way for a process to find
356: * out whether there are any functions waiting on the lock, since the unlock
357: * implementation could simply clear the "locked" flag and issue wakeup (),
358: * so that there could be any number of contexts waiting to run and test the
359: * "locked" flag, yet SLEEP_LOCKAVAIL () in the calling context would return
360: * true. Deallocating the lock at this time would be potentially disastrous.
361: *
362: * Actually, even a quality implementation of sleep locks (such as is provided
363: * with this STREAMS system) cannot be easily used this way, since it is very
364: * difficult to ensure that the information returned by SLEEP_LOCKAVAIL () is
365: * current.
366: *
367: * The situation can be resolved by maintaining a count of processes wishing
368: * to lock the item. The count can be maintained by using the basic-lock
369: * action associated with DDI/DKI synchronization variables, and the new
370: * SV_SIGNAL () operation can be used to pass the ownership of the lock to
371: * a waiting process reliably.
372: *
373: * Once this is in place, it becomes clear how the count of waiting processes
374: * can be used to simplify the destruction of stream heads; essentially,
375: * when a process wishes to release the "lock" on the stream head, if both
376: * the open count and the waiting count are 0, then the memory for the item
377: * can be safely released. Otherwise, control simply passes to the next
378: * waiting process.
379: *
380: * So, if a process is performing a final close on a stream, and some open
381: * requests are queued, the close will leave the stream's memory alone and
382: * simply pass it on to the waiting open (which can detect that the stream
383: * needs to be treated as new since the open count is 0). If the waiting open
384: * was interrupted by a signal, it would still have to decrement the count of
385: * waiting processes before it releases its lock, at which time it would know
386: * to remove the item from the directory and release the memory.
387: *
388: * For this to work properly takes some coordination in the policy for the
389: * directory; the basic lock used to guard lock operations should be held
390: * during searches of the directory to ensure that the count value is correct
391: * with respect to all processes; a process that has a pointer to the stream
392: * head (obtained from the directory) which it has not incremented the count
393: * for is an error. Note that this only applies to operations which might
394: * later affect the count, of course.
395: *
396: *
397: * STREAM OPERATIONS AND LOCKS:
398: *
399: * open () This operation cannot begin while there is a final close in
400: * progress. If this operation increments the "open count" before
401: * calling the device open routines, it is possible that it will
402: * also have to perform final close duties if a driver or module
403: * fails the open. This function may cause the creation of a new
404: * queue pair and directory entry.
405: *
406: * The multiprocessor DDI/DKI also mandates that a particular
407: * device number's open () routine only have one instance active
408: * at any given time.
409: *
410: * close () Normally, this does not require extended locking, but the case
411: * of beginning a final close is special, since only then will
412: * the queue drain and final close procedures begin. Since there
413: * cannot be outstanding ioctl ()s during final close, the timer
414: * code used to control ioctl ()s can be shared with this for
415: * timing out while waiting for a write queue to drain.
416: *
417: * read (), getmsg (), getpmsg ()
418: * Under normal circumstances, these functions require no special
419: * treatment. It would be desirable to support an extension to
420: * STREAMS which supported "safe" multiple readers, where the
421: * serialization of reads is guaranteed.
422: *
423: * write (), putmsg (), putpmsg ()
424: * These functions require little special treatment. It would be
425: * desirable to support an extension to STREAMS which guaranteed
426: * serialization of writes, for instance to guarantee unlimited-
427: * length atomic pipe writes.
428: *
429: * ioctl () Depending on the details of the operation, we may need
430: *
431: * a read lock on the stream head (eg. I_GETCLTIME).
432: * a write lock on the stream head (eg. I_SRDOPT).
433: * a block on open and pop (I_PUSH).
434: * a block on close and push (I_POP).
435: * a long-term lock on the message queue.
436: *
437: * The long-term lock operations revolve around the operations
438: * that send messages downstream : I_LINK, I_UNLINK, I_PLINK,
439: * I_PUNLINK, and I_STR. These operations are also special in
440: * that they are capable of timing out.
441: *
442: * Since the close or open routines invoked by an I_PUSH or I_POP
443: * operation may block, they require analagous locking to the
444: * open () and close () cases.
445: *
446: * LOCK SUMMARY:
447: * EXCLUSIVE LONG-TERM LOCK WITH OPTIONAL TIMEOUT:
448: * open/close category:
449: * open (), close (), I_PUSH, I_POP
450: * ioctl category:
451: * I_LINK, I_UNLINK, I_PLINK, I_PUNLINK, I_STR
452: *
453: * In theory, a single lock will do. However, once we take into
454: * account terminal behaviour w.r.t. CLOCAL and other similar
455: * situations, it seems that creating the subcategories above will
456: * suit us better.
457: *
458: * Final close is a special case that blocks all other cases, which
459: * can be distinguished fairly clearly.
460: *
461: * STREAM HEAD WRITE LOCK:
462: * I_SRDOPT, I_SETSIG, I_SWROPT, I_SETCLTIME
463: * Certain stream head message processing routines may also write
464: * lock the stream head, such as M_SETOPT processing.
465: *
466: * All other streams operations should acquire a stream head read lock
467: * before reading stream head variables.
468: */
469: /*
470: * STREAM HEAD WAIT NOTES:
471: *
472: * In addition to the above discussion about locking, there are other
473: * operations that may cause a process to block while at the stream head. For
474: * instance, read (), write (), I_RECVFD, and I_STR operations may cause the
475: * outer context to block until some kind of message arrives.
476: *
477: * The question we are immediately faced with is what level of specificity to
478: * provide in the arrangement of synchronization variables and basic locks.
479: * Until the implementation is complete and we can perform detailed
480: * measurements with a variety of (pathological) loads on a variety of
481: * systems, we really don't know. For simplicity, the current system performs
482: * all stream head blocking by sleeping on the "sh_wait_sv" synchronization
483: * variable that is also used by the above locking operations.
484: *
485: * However, to give some isolation from changes in this scheme, we mandate a
486: * generic layer to deal with this. Not only does this insulate operations
487: * from the details of synchronization, but it allows us to perform some
488: * simple optimizations that may allow this simple scheme to perform better.
489: */
490:
491:
492: /*
493: * Initialize a stream head structure, assuming that memory was allocated with
494: * kmem_zalloc () and so NULL pointers and 0-value fields need not be filled
495: * in.
496: *
497: * This function may sleep waiting for memory to become available to allocate
498: * the locks needed by the stream head.
499: */
500:
501: #if __USE_PROTO__
502: __LOCAL__ void (SHEAD_INIT) (shead_t * sheadp, struct streamtab * stabp,
503: n_dev_t dev, queue_t * rq)
504: #else
505: __LOCAL__ void
506: SHEAD_INIT __ARGS ((sheadp, stabp, dev, rq))
507: shead_t * sheadp;
508: struct streamtab
509: * stabp;
510: n_dev_t dev;
511: queue_t * rq;
512: #endif
513: {
514: ASSERT (sheadp != NULL);
515: ASSERT (rq != NULL);
516:
517: /*
518: * The sh_lock_count and sh_time_count members are initialized in the
519: * lock code.
520: */
521:
522: ASSERT (sheadp->sh_open_count == 0);
523: ASSERT (sheadp->sh_attach_count == 0);
524: ASSERT (sheadp->sh_lock_count == 0);
525: ASSERT (sheadp->sh_time_count == 0);
526: ASSERT (sheadp->sh_rerrcode == 0);
527: ASSERT (sheadp->sh_werrcode == 0);
528: ASSERT (sheadp->sh_wroff == 0);
529:
530: ASSERT (sheadp->sh_read_bufcall == 0);
531: ASSERT (sheadp->sh_timeout_id == 0);
532:
533: ASSERT (sheadp->sh_sigs == NULL);
534: ASSERT (sheadp->sh_linked == NULL);
535: ASSERT (sheadp->sh_ioc_msg == NULL);
536:
537: ASSERT (rq->q_ptr == sheadp);
538:
539: sheadp->sh_dev = dev;
540: sheadp->sh_tab = stabp;
541: sheadp->sh_head = rq;
542:
543: sheadp->sh_pollhead = phalloc (KM_SLEEP);
544: sheadp->sh_flags = SH_MASTER;
545: sheadp->sh_readopt = RNORM | RPROTNORM;
546:
547: sheadp->sh_basic_lockp = LOCK_ALLOC (stream_head_hierarchy, plstr,
548: & _stream_head_lkinfo, KM_SLEEP);
549: sheadp->sh_wait_sv = SV_ALLOC (KM_SLEEP);
550:
551: ASSERT (sheadp->sh_basic_lockp != NULL || sheadp->sh_wait_sv != NULL);
552:
553:
554: /*
555: * The default time to wait for a queue to drain while closing is 15s.
556: */
557:
558: sheadp->sh_cltime = drv_usectohz (15000000L);
559: }
560:
561:
562: /*
563: * Turn a stream head structure back into raw bits.
564: */
565:
566: #if __USE_PROTO__
567: __LOCAL__ void (SHEAD_DESTROY) (shead_t * sheadp)
568: #else
569: __LOCAL__ void
570: SHEAD_DESTROY __ARGS((sheadp))
571: shead_t * sheadp;
572: #endif
573: {
574: ASSERT (sheadp != NULL);
575: ASSERT (sheadp->sh_sigs == NULL);
576: ASSERT (sheadp->sh_linked == NULL);
577:
578: ASSERT (sheadp->sh_open_count == 0);
579: ASSERT (sheadp->sh_attach_count == 0);
580: ASSERT (sheadp->sh_lock_count == 0);
581:
582: ASSERT (sheadp->sh_timeout_id == 0);
583:
584: if (sheadp->sh_read_bufcall != 0)
585: unbufcall (sheadp->sh_read_bufcall);
586:
587: LOCK_DEALLOC (sheadp->sh_basic_lockp);
588: SV_DEALLOC (sheadp->sh_wait_sv);
589:
590: phfree (sheadp->sh_pollhead);
591: }
592:
593:
594: /*
595: * This function attempts to determine the appropriate id queue for a stream
596: * head based on cues in the stream head.
597: */
598:
599: #if __USE_PROTO__
600: __LOCAL__ slist_id_t (SHEAD_ID) (shead_t * sheadp)
601: #else
602: __LOCAL__ slist_id_t
603: SHEAD_ID __ARGS ((sheadp))
604: shead_t * sheadp;
605: #endif
606: {
607: ASSERT (sheadp != NULL);
608:
609: if (SHEAD_IS_PIPE (sheadp))
610: return PIPE_SLIST;
611:
612: return DEV_SLIST;
613: }
614:
615:
616: /*
617: * This function finds a stream head by looking up its device number, but
618: * nothing else. To call this function, the caller must have good reason to
619: * suspect that an open reference to the stream exists and isn't going to go
620: * away.
621: *
622: * If this routine returns NULL, then that is a serious error (which may be
623: * diagnosed by console messages), because it indicates that the caller has
624: * not got the claimed knowledge of the state of the system!
625: */
626:
627: #if __USE_PROTO__
628: shead_t * (SHEAD_FIND) (n_dev_t dev, slist_id_t id)
629: #else
630: shead_t *
631: SHEAD_FIND __ARGS ((dev, id))
632: n_dev_t dev;
633: slist_id_t id;
634: #endif
635: {
636: shead_t * scan;
637: pl_t prev_pl;
638:
639: prev_pl = RW_RDLOCK (str_mem->sm_head_lock, plstr);
640:
641: for (scan = str_mem->sm_streams [id] ; scan != NULL ;
642: scan = scan->sh_next) {
643:
644: if (scan->sh_dev == dev)
645: break;
646: }
647:
648: RW_UNLOCK (str_mem->sm_head_lock, prev_pl);
649:
650: if (scan == NULL)
651: cmn_err (CE_WARN, "Unable to locate stream in SHEAD_FIND ()");
652: else
653: ASSERT (SHEAD_ID (scan) == id);
654:
655: return scan;
656: }
657:
658:
659: /*
660: * This function attempts to locate an existing entry and increment its lock
661: * count atomically.
662: */
663:
664: #if __USE_PROTO__
665: __LOCAL__ shead_t * (SHEAD_FIND_AND_LOCK) (n_dev_t dev, slist_id_t id)
666: #else
667: __LOCAL__ shead_t *
668: SHEAD_FIND_AND_LOCK __ARGS ((dev, id))
669: n_dev_t dev;
670: slist_id_t id;
671: #endif
672: {
673: shead_t * scan;
674: pl_t prev_pl;
675:
676: prev_pl = RW_RDLOCK (str_mem->sm_head_lock, plstr);
677:
678: for (scan = str_mem->sm_streams [id] ; scan != NULL ;
679: scan = scan->sh_next) {
680:
681: if (scan->sh_dev == dev) {
682: /*
683: * Now we have found the entry we want, increment the
684: * reference count atomically. We know that it will
685: * not disappear because of the read lock we have on
686: * the containing list.
687: */
688:
689: (void) SHEAD_LOCK (scan);
690:
691: scan->sh_lock_count ++;
692: break;
693: }
694: }
695:
696: RW_UNLOCK (str_mem->sm_head_lock, prev_pl);
697: return scan;
698: }
699:
700:
701: /*
702: * This function adds a stream head to the global list. If an entry with the
703: * same ID is present on the list, this operation fails.
704: *
705: * The stream head should be locked against further opens at this point.
706: *
707: * The return value is 0 on success, -1 on error.
708: */
709:
710: #if __USE_PROTO__
711: __LOCAL__ int (SHEAD_ADD) (shead_t * sheadp)
712: #else
713: __LOCAL__ int
714: SHEAD_ADD __ARGS ((sheadp))
715: shead_t * sheadp;
716: #endif
717: {
718: pl_t prev_pl;
719: shead_t * scan;
720: slist_id_t id;
721:
722: id = SHEAD_ID (sheadp);
723:
724: ASSERT (sheadp->sh_ref_count == 1);
725: ASSERT ((sheadp->sh_lock_mask & SH_OPENCLOSE) != 0);
726:
727: prev_pl = RW_WRLOCK (str_mem->sm_head_lock, plstr);
728:
729: for (scan = str_mem->sm_streams [id] ; scan != NULL ;
730: scan = scan->sh_next) {
731:
732: if (scan->sh_dev == sheadp->sh_dev) {
733: /*
734: * We have found a conflict. Unlock the list and
735: * return an error.
736: */
737:
738: RW_UNLOCK (str_mem->sm_head_lock, prev_pl);
739: return -1;
740: }
741: }
742:
743: sheadp->sh_next = str_mem->sm_streams [id];
744: str_mem->sm_streams [id] = sheadp;
745:
746: RW_UNLOCK (str_mem->sm_head_lock, prev_pl);
747: return 0;
748: }
749:
750:
751: /*
752: * This function changes the device number of a stream head for a clone open
753: * situation. The "st_dev" field of the stream head has to be changed with
754: * the stream head list lock held for writing to avoid confusing anyone who
755: * is looking for the original device number.
756: *
757: * Furthermore, the rename can fail because the new number is already in use.
758: * The return value is -1 on error, or 0 on success.
759: */
760:
761: #if __USE_PROTO__
762: __LOCAL__ int (SHEAD_RENAME) (shead_t * sheadp, n_dev_t dev)
763: #else
764: __LOCAL__ int
765: SHEAD_RENAME __ARGS ((sheadp, dev))
766: shead_t * sheadp;
767: n_dev_t dev;
768: #endif
769: {
770: pl_t prev_pl;
771: shead_t * scan;
772: int ok = 0; /* flag whether stream is on list */
773: slist_id_t id;
774:
775: id = SHEAD_ID (sheadp);
776:
777: prev_pl = RW_WRLOCK (str_mem->sm_head_lock, plstr);
778:
779: for (scan = str_mem->sm_streams [id] ; scan != NULL ;
780: scan = scan->sh_next) {
781:
782: if (scan->sh_dev == dev) {
783: /*
784: * We have found a conflict. Unlock the list and
785: * return an error.
786: */
787:
788: RW_UNLOCK (str_mem->sm_head_lock, prev_pl);
789: return -1;
790: }
791:
792: if (scan == sheadp)
793: ok ++; /* Ok, we saw the item */
794: }
795:
796: /*
797: * All OK, now change the name of the original stream head.
798: */
799:
800: sheadp->sh_dev = dev;
801: RW_UNLOCK (str_mem->sm_head_lock, prev_pl);
802:
803: if (! ok)
804: cmn_err (CE_WARN, "SHEAD_RENAME () of unlisted stream head");
805:
806: return 0;
807: }
808:
809:
810: /*
811: * This function decrements the link count of the stream head; this may cause
812: * the stream head to become unreferened, which means that the memory will be
813: * reclaimed.
814: */
815:
816: #if __USE_PROTO__
817: __LOCAL__ void (SHEAD_UNREFERENCE) (shead_t * sheadp)
818: #else
819: __LOCAL__ void
820: SHEAD_UNREFERENCE __ARGS ((sheadp))
821: shead_t * sheadp;
822: #endif
823: {
824: slist_id_t id;
825: int unlink;
826:
827: SHEAD_ASSERT_LOCKED (sheadp);
828: ASSERT (sheadp == SHEAD_MASTER (sheadp));
829: ASSERT (sheadp->sh_lock_count > 0);
830:
831: id = SHEAD_ID (sheadp);
832:
833: /*
834: * We will delete a stream if there are no references holding it open,
835: * either pending locks or open references. If this is a stream pipe,
836: * then we need to check boths ends of the stream pipe. Because this
837: * function is called from the sleep-locking code, we know that
838: * "sheadp" points to the master end.
839: */
840:
841: unlink = sheadp->sh_open_count == 0 ||
842: (SHEAD_IS_PIPE (sheadp) &&
843: SHEAD_M2SLAVE (sheadp->sh_open_count) == 0);
844:
845: /*
846: * We normally assume that we won't be unlinking the stream, because
847: * to do that we need a lock on a global list (which is more expensive
848: * that a list on an individual stream).
849: *
850: * However, due to the relative hierarchy positions of the locks, if
851: * we discover we are likely to be the ones to dequeue the item, we
852: * take out a write lock then.
853: */
854:
855: if (sheadp->sh_lock_count > 1 && ! unlink) {
856: /*
857: * Take the short path out.
858: */
859:
860: sheadp->sh_lock_count --;
861: SHEAD_UNLOCK (sheadp, plbase);
862: return;
863: }
864:
865: /*
866: * Escalate to a write lock on the stream head; we will need
867: * to recheck to unlink condition after we escalate.
868: */
869:
870: SHEAD_UNLOCK (sheadp, plbase);
871:
872: (void) RW_WRLOCK (str_mem->sm_head_lock, plstr);
873: (void) SHEAD_LOCK (sheadp);
874:
875: unlink = -- sheadp->sh_lock_count == 0 &&
876: (sheadp->sh_open_count == 0 ||
877: (SHEAD_IS_PIPE (sheadp) &&
878: SHEAD_M2SLAVE (sheadp)->sh_open_count == 0));
879:
880: SHEAD_UNLOCK (sheadp, plstr);
881:
882: if (unlink) {
883: shead_t * scan;
884:
885: /*
886: * Remove from the singly-threaded list by searching for the
887: * immediate predecessor entry in the list (if any).
888: */
889:
890: if ((scan = str_mem->sm_streams [id]) == sheadp)
891: str_mem->sm_streams [id] = sheadp->sh_next;
892: else
893: do {
894: if (scan->sh_next == sheadp) {
895:
896: scan->sh_next = sheadp->sh_next;
897: break;
898: }
899: } while ((scan = scan->sh_next) != NULL);
900:
901: if (scan == NULL)
902: cmn_err (CE_WARN, "Failure unlinking stream from global directory");
903:
904: /*
905: * Note that stream pipes consist of four queues and
906: * two stream heads!
907: */
908:
909: SHEAD_DESTROY (sheadp);
910:
911: if (SHEAD_IS_PIPE (sheadp))
912: QUEUE_FREE (sheadp->sh_head, 4,
913: 2 * sizeof (* sheadp));
914: else
915: QUEUE_FREE (sheadp->sh_head, 2, sizeof (* sheadp));
916: }
917:
918: RW_UNLOCK (str_mem->sm_head_lock, plbase);
919: }
920:
921:
922: /*
923: * This function attempts to locate a stream linked below another stream based
924: * on the multiplexor ID. If the multiplexor ID is -1, then this function
925: * returns the first stream found linked below the given upper stream. In
926: * addition, the "cmd" value is used to distinguish between the persistent and
927: * regular multiplexor ID spaces.
928: */
929:
930: #if __USE_PROTO__
931: __LOCAL__ shead_t * (SHEAD_FIND_MUXID) (shead_t * upper, int cmd,
932: muxid_t muxid)
933: #else
934: __LOCAL__ shead_t *
935: SHEAD_FIND_MUXID __ARGS ((upper, cmd, muxid))
936: shead_t * upper;
937: int cmd;
938: muxid_t muxid;
939: #endif
940: {
941: shead_t * scan;
942: pl_t prev_pl;
943: int checklist;
944:
945: /*
946: * Precook "cmd" for easier testing below.
947: */
948:
949: cmd = (cmd == I_PLINK || cmd == I_PUNLINK) ? SH_PLINK : 0;
950:
951:
952: /*
953: * Now take out a lock to protect our list walking.
954: */
955:
956: prev_pl = RW_RDLOCK (str_mem->sm_head_lock, plstr);
957:
958: for (checklist = DEV_SLIST ; checklist < SLIST_MAX ; checklist ++) {
959:
960: for (scan = str_mem->sm_streams [checklist] ; scan != NULL ;
961: scan = scan->sh_next) {
962:
963: if (scan->sh_linked == upper &&
964: (scan->sh_flags & SH_PLINK) == cmd &&
965: ((scan->sh_muxid == muxid) || muxid == -1)) {
966:
967: goto done;
968: }
969: }
970: }
971:
972: done:
973: RW_UNLOCK (str_mem->sm_head_lock, prev_pl);
974:
975: return scan;
976: }
977:
978:
979: /*
980: * A local helper function for stream head timeouts.
981: */
982:
983: #if __USE_PROTO__
984: __LOCAL__ void shead_timer_func (_VOID * arg)
985: #else
986: __LOCAL__ void
987: shead_timer_func (arg)
988: _VOID * arg;
989: #endif
990: {
991: shead_t * sheadp = (shead_t *) arg;
992: unsigned locks;
993:
994: SHEAD_ASSERT_LOCKED (sheadp);
995:
996: SV_BROADCAST (sheadp->sh_wait_sv, 0);
997:
998: sheadp->sh_lock_mask &= ~ SH_TIMEFLAG;
999: sheadp->sh_timeout_id = 0;
1000: sheadp->sh_time_count = 0;
1001:
1002: /*
1003: * Note that we advance "sh_time_count" on behalf of the processes
1004: * that have the stream head locked.
1005: */
1006:
1007: locks = sheadp->sh_lock_mask & SH_LOCK_MASK;
1008:
1009: while (locks != 0) {
1010:
1011: if ((locks & 1) != 0)
1012: sheadp->sh_time_count ++;
1013: locks >>= 1;
1014: }
1015: }
1016:
1017:
1018: /*
1019: * This function is called when the time has come to actually initiate a
1020: * timeout.
1021: */
1022:
1023: #if __USE_PROTO__
1024: int (SHEAD_START_TIMEOUT) (shead_t * sheadp)
1025: #else
1026: int
1027: SHEAD_START_TIMEOUT __ARGS ((sheadp))
1028: shead_t * sheadp;
1029: #endif
1030: {
1031: __clock_t the_time;
1032:
1033: SHEAD_ASSERT_LOCKED (sheadp);
1034:
1035: if ((sheadp->sh_lock_mask & SH_TIMEFLAG) == 0 ||
1036: sheadp->sh_timeout_id != 0)
1037: return 1; /* do nothing */
1038:
1039: (void) drv_getparm (LBOLT, & the_time);
1040:
1041: sheadp->sh_timeout_id = ltimeout (shead_timer_func, sheadp,
1042: sheadp->sh_timeout_tick - the_time,
1043: sheadp->sh_basic_lockp, plstr);
1044:
1045: /*
1046: * If the timeout could not be scheduled, we return 0 to indicate to
1047: * the caller that it should timeout immediately, and run the timeout
1048: * function to fake a normal timeout.
1049: */
1050:
1051: if (sheadp->sh_timeout_id == 0) {
1052:
1053: shead_timer_func (sheadp);
1054: return 0;
1055: }
1056:
1057: return 1;
1058: }
1059:
1060:
1061: /*
1062: * Indicate that no timeout will be necessary for this lock item.
1063: */
1064:
1065: #if __USE_PROTO__
1066: void (SHEAD_NO_TIMEOUT) (shead_t * sheadp)
1067: #else
1068: void
1069: SHEAD_NO_TIMEOUT __ARGS ((sheadp))
1070: shead_t * sheadp;
1071: #endif
1072: {
1073: SHEAD_ASSERT_LOCKED (sheadp);
1074:
1075: ASSERT (sheadp->sh_time_count < sheadp->sh_lock_count);
1076:
1077: if (++ sheadp->sh_time_count == sheadp->sh_lock_count) {
1078: /*
1079: * Since we are the last process to register an end time, we
1080: * get to actually initiate a timeout for the stream head.
1081: */
1082:
1083: (void) SHEAD_START_TIMEOUT (sheadp);
1084: }
1085: }
1086:
1087:
1088: /*
1089: * Indicate that a timeout is desired for this lock item at the given clock
1090: * tick.
1091: */
1092:
1093: #if __USE_PROTO__
1094: int (SHEAD_LOCK_TIMEOUT) (shead_t * sheadp, __clock_t end_time)
1095: #else
1096: int
1097: SHEAD_LOCK_TIMEOUT __ARGS ((sheadp, end_time))
1098: shead_t * sheadp;
1099: __clock_t end_time;
1100: #endif
1101: {
1102: __clock_t the_time;
1103:
1104: SHEAD_ASSERT_LOCKED (sheadp);
1105:
1106: ASSERT (sheadp->sh_time_count < sheadp->sh_lock_count);
1107:
1108:
1109: /*
1110: * If our horizon falls before the current latest value (or if there
1111: * is no latest value), select our horizon time. If the horizon time
1112: * is *before* the current time, return 0.
1113: *
1114: * Comparing time values introduces the usual problems when dealing
1115: * with sequence spaces in C. While the following expression is not
1116: * as efficient as relying on the semantics of unsigned->signed
1117: * casting, avoiding implementation-defined behaviour is important.
1118: *
1119: * "clock_t" MUST be unsigned for this to work.
1120: */
1121:
1122: ASSERT ((__clock_t) -1 > 0);
1123:
1124: (void) drv_getparm (LBOLT, & the_time);
1125:
1126: if ((__clock_t) (the_time - end_time) < ((__clock_t) -1 >> 1)) {
1127: /*
1128: * The indicated time has already passed, so we return a
1129: * timeout indication directly.
1130: */
1131:
1132: sheadp->sh_time_count ++;
1133: return 0;
1134: }
1135:
1136:
1137: if ((sheadp->sh_lock_mask & SH_TIMEFLAG) == 0 ||
1138: (__clock_t) (sheadp->sh_timeout_tick - end_time) <
1139: ((__clock_t) -1 >> 1)) {
1140: /*
1141: * "end_time" will occur before the current latest time. If
1142: * a timeout has been scheduled, we cancel it because we want
1143: * to post a more recent one.
1144: */
1145:
1146: if (sheadp->sh_timeout_id != 0) {
1147:
1148: untimeout (sheadp->sh_timeout_id);
1149: sheadp->sh_timeout_id = 0;
1150: }
1151:
1152: sheadp->sh_lock_mask |= SH_TIMEFLAG;
1153: }
1154:
1155: if (++ sheadp->sh_time_count == sheadp->sh_lock_count) {
1156: /*
1157: * Since we are the last process to register an end time, we
1158: * get to actually initiate a timeout for the stream head.
1159: */
1160:
1161: return SHEAD_START_TIMEOUT (sheadp);
1162: } else {
1163: /*
1164: * We can go to sleep and rely on someone else to actually
1165: * intiate the timeout.
1166: */
1167:
1168: return 1;
1169: }
1170: }
1171:
1172:
1173: /*
1174: * This function is used when a process wants to cancel a timeout after having
1175: * registered one.
1176: */
1177:
1178: #if __USE_PROTO__
1179: void (SHEAD_END_TIMEOUT) (shead_t * sheadp)
1180: #else
1181: void
1182: SHEAD_END_TIMEOUT __ARGS ((sheadp))
1183: shead_t * sheadp;
1184: #endif
1185: {
1186: SHEAD_ASSERT_LOCKED (sheadp);
1187:
1188: if (sheadp->sh_timeout_id != 0) {
1189:
1190: ASSERT (sheadp->sh_time_count == sheadp->sh_lock_count + 1);
1191: sheadp->sh_time_count --;
1192: }
1193: }
1194:
1195:
1196: /*
1197: * This function is used when a lock holder wishes to sleep waiting for a
1198: * timeout.
1199: */
1200:
1201: #if __USE_PROTO__
1202: int (SHEAD_LOCKED_TIMEOUT) (shead_t * sheadp, __clock_t end_time)
1203: #else
1204: int
1205: SHEAD_LOCKED_TIMEOUT __ARGS ((sheadp, end_time))
1206: shead_t * sheadp;
1207: __clock_t end_time;
1208: #endif
1209: {
1210: SHEAD_ASSERT_LOCKED (sheadp);
1211:
1212: ASSERT (sheadp->sh_time_count > 0);
1213:
1214: sheadp->sh_time_count --;
1215:
1216: return SHEAD_LOCK_TIMEOUT (sheadp, end_time);
1217: }
1218:
1219:
1220: /*
1221: * Common code to test whether a stream has experienced an error condition.
1222: */
1223:
1224: #define _shead_error(sheadp,mode) \
1225: (SHEAD_ASSERT_LOCKED (sheadp), \
1226: sheadp->sh_linked != NULL ? EINVAL : \
1227: ((mode) & FWRITE) != 0 && sheadp->sh_werrcode != 0 ? \
1228: sheadp->sh_werrcode : \
1229: ((mode) & FREAD) != 0 ? sheadp->sh_rerrcode : 0)
1230:
1231: /*
1232: * This function tests for error or hangup conditions on the stream head given
1233: * by "sheadp". It assumes that the caller holds a basic lock on the stream
1234: * head. If an error or hangup condition exists then the basic lock is
1235: * unlocked and a non-zero error number is returned.
1236: */
1237:
1238: #if __USE_PROTO__
1239: __LOCAL__ int (SHEAD_ERRHUP_LOCKED) (shead_t * sheadp, int mode)
1240: #else
1241: __LOCAL__ int
1242: SHEAD_ERRHUP_LOCKED __ARGS ((sheadp, mode))
1243: shead_t * sheadp;
1244: int mode;
1245: #endif
1246: {
1247: int retval;
1248:
1249: SHEAD_ASSERT_LOCKED (sheadp);
1250:
1251: if ((retval = _shead_error (sheadp, mode)) != 0 ||
1252: ((mode & (FREAD | FWRITE)) != 0 &&
1253: (retval = ENXIO, SHEAD_HANGUP (sheadp) != 0))) {
1254:
1255: SHEAD_UNLOCK (sheadp, plbase);
1256: return retval;
1257: }
1258:
1259: return 0;
1260: }
1261:
1262:
1263: /*
1264: * Definitions use for the "interruptible" parameter to SHEAD_WAIT () and
1265: * SHEAD_LOCK ().
1266: */
1267:
1268: enum {
1269: DONT_SIGNAL = 0,
1270: CHECK_SIGNALS = 1
1271: };
1272:
1273:
1274: /*
1275: * This function is the common interface to waiting for an event at a stream
1276: * head. It borrows the same synchronization variable used by the stream head
1277: * locking code in this implementation.
1278: *
1279: * We return 0 on success or an error number on failure.
1280: */
1281:
1282: #if __USE_PROTO__
1283: __LOCAL__ int (SHEAD_WAIT) (shead_t * sheadp, int mode, cat_t category,
1284: int interruptible)
1285: #else
1286: __LOCAL__ int
1287: SHEAD_WAIT __ARGS ((sheadp, mode, category, interruptible))
1288: shead_t * sheadp;
1289: int mode;
1290: cat_t category;
1291: int interruptible;
1292: #endif
1293: {
1294: int retval;
1295:
1296: SHEAD_ASSERT_LOCKED (sheadp);
1297:
1298: /*
1299: * Test for error/hangup conditions before we sleep.
1300: */
1301:
1302: if ((retval = SHEAD_ERRHUP_LOCKED (sheadp, mode)) != 0)
1303: return retval;
1304:
1305: /*
1306: * Register our interest in the kind of event that we are waiting for.
1307: */
1308:
1309: sheadp->sh_lock_mask |= category;
1310:
1311: if (interruptible == CHECK_SIGNALS)
1312: return SV_WAIT_SIG (sheadp->sh_wait_sv, primed,
1313: sheadp->sh_basic_lockp) == 0 ? EINTR : 0;
1314: else {
1315: SV_WAIT (sheadp->sh_wait_sv, primed, sheadp->sh_basic_lockp);
1316: return 0;
1317: }
1318: }
1319:
1320:
1321: /*
1322: * This function is a slightly different interface to SHEAD_WAIT (), used when
1323: * the caller has been examining some property of a queue and wishes to go
1324: * to sleep atomically. A frozen queue is not suitable for passing to
1325: * SV_WAIT_SIG (), so we acquire the stream head global lock and then unfreeze
1326: * the queue on behalf of the caller. This yields correct behaviour because
1327: * SHEAD_WAKE () also attempts to acquire the stream head global lock; any
1328: * modification to a stream queue resulting in a wakeup request will follow
1329: * the same locking sequence.
1330: */
1331:
1332: #if __USE_PROTO__
1333: __LOCAL__ int (SHEAD_WAIT_NONBLOCK) (shead_t * sheadp, int mode,
1334: cat_t category, int interruptible)
1335: #else
1336: __LOCAL__ int
1337: SHEAD_WAIT_NONBLOCK __ARGS ((sheadp, mode, category, interruptible))
1338: shead_t * sheadp;
1339: int mode;
1340: cat_t category;
1341: int interruptible;
1342: #endif
1343: {
1344: SHEAD_ASSERT_LOCKED (sheadp);
1345:
1346: if ((mode & (FNDELAY | FNONBLOCK)) != 0) {
1347:
1348: SHEAD_UNLOCK (sheadp, plbase);
1349: return EAGAIN;
1350: }
1351:
1352: return SHEAD_WAIT (sheadp, mode, category, interruptible);
1353: }
1354:
1355:
1356: /*
1357: * This function is used by lower-level code to signal events to functions
1358: * that have waited via SHEAD_WAIT (), above.
1359: */
1360:
1361: #if __USE_PROTO__
1362: void (SHEAD_WAKE) (shead_t * sheadp, cat_t category)
1363: #else
1364: void
1365: SHEAD_WAKE __ARGS ((sheadp, category))
1366: shead_t * sheadp;
1367: cat_t category;
1368: #endif
1369: {
1370: pl_t prev_pl;
1371:
1372: prev_pl = SHEAD_LOCK (sheadp);
1373:
1374: if ((sheadp->sh_lock_mask & category) != 0) {
1375:
1376: sheadp->sh_lock_mask &= ~ category;
1377: SV_BROADCAST (sheadp->sh_wait_sv, 0);
1378: }
1379:
1380: SHEAD_UNLOCK (sheadp, prev_pl);
1381: }
1382:
1383:
1384: /*
1385: * Common code for locking stream head, shared between open-style locks (which
1386: * may need to allocate new head structures and need special coordination
1387: * with the stream head destruction code) and other kinds.
1388: *
1389: * We expect that the caller will have taken out a basic lock on the stream
1390: * head and that the caller will have incremented the lock count of the item
1391: * to prevent it from being deallocated while we wait.
1392: */
1393:
1394: #if __USE_PROTO__
1395: int (SHEAD_SLEEP_LOCKED) (shead_t * sheadp, cat_t category, __clock_t timeout,
1396: int interruptible)
1397: #else
1398: int
1399: SHEAD_SLEEP_LOCKED __ARGS ((sheadp, category, timeout, interruptible))
1400: shead_t * sheadp;
1401: cat_t category;
1402: __clock_t timeout;
1403: int interruptible;
1404: #endif
1405: {
1406: __clock_t end_time; /* LBOLT when we time out */
1407: n_dev_t devno;
1408: int retval;
1409:
1410: SHEAD_ASSERT_LOCKED (sheadp);
1411:
1412: /*
1413: * Since we expect the caller to have incremented the lock count, then
1414: * the caller must have selected the master end of the stream pipe.
1415: */
1416:
1417: ASSERT (sheadp == SHEAD_MASTER (sheadp));
1418:
1419: /*
1420: * If we are going to be (possibly) timing out, calculate the time
1421: * when that will happen.
1422: */
1423:
1424: if (timeout > 0) {
1425:
1426: (void) drv_getparm (LBOLT, & end_time);
1427: end_time += timeout;
1428: }
1429:
1430:
1431: /*
1432: * There is a special case that we have to note; in the case of a
1433: * clone open, the device number of a stream head may be altered by
1434: * the driver open routine. In this case, drivers waiting on the old
1435: * number will have to be notified and give up on their lock attempts.
1436: */
1437:
1438: devno = sheadp->sh_dev;
1439:
1440:
1441: /*
1442: * Now we begin the actual business of locking the stream head.
1443: */
1444:
1445: for (;;) {
1446: int sigflg;
1447:
1448: /*
1449: * Check to see whether our category is blocked. At this point
1450: * we hold "global_lock".
1451: *
1452: * An earlier verson of this code had an explicit check for
1453: * final close. I have no idea why, because if a stream is in
1454: * final close, what else can happen?
1455: */
1456:
1457: if ((sheadp->sh_lock_mask & category) == 0) {
1458: /*
1459: * We can acquire a lock on the stream head in our
1460: * chosen category, so we do so. Since we will not
1461: * need a timeout, we increment the timeout count.
1462: *
1463: * If during later processing we need a timeout, we
1464: * hook into this mechanism, but for simplicity we
1465: * assume we won't.
1466: */
1467:
1468: SHEAD_NO_TIMEOUT (sheadp);
1469:
1470: SHEAD_UNLOCK (sheadp, plbase);
1471:
1472: sheadp->sh_lock_mask |= category;
1473:
1474: return 0;
1475: }
1476:
1477:
1478: /*
1479: * We need to wait, interruptibly. We might also want to time
1480: * out at some stage.
1481: *
1482: * We (optionally) call a function to register the time we
1483: * want to expire; this function also takes care of checking
1484: * for timeout expiry.
1485: */
1486:
1487: if (timeout == 0)
1488: SHEAD_NO_TIMEOUT (sheadp);
1489: else if (SHEAD_LOCK_TIMEOUT (sheadp, end_time) == 0) {
1490: /*
1491: * Our horizon time has passed, so we return ETIME.
1492: */
1493:
1494: retval = ETIME;
1495: break;
1496: }
1497:
1498:
1499: /*
1500: * Now we can wait. No matter how we wake up, we will need
1501: * to relock the global basic lock.
1502: *
1503: * The caller may not want this wait to be interruptible; this
1504: * is reasonable when the lock is being acquired in some
1505: * nested context where things are difficult to back out.
1506: */
1507:
1508: if (interruptible != DONT_SIGNAL)
1509: sigflg = SV_WAIT_SIG (sheadp->sh_wait_sv, primed,
1510: sheadp->sh_basic_lockp);
1511: else {
1512: SV_WAIT (sheadp->sh_wait_sv, primed,
1513: sheadp->sh_basic_lockp);
1514: sigflg = 1;
1515: }
1516:
1517: (void) SHEAD_LOCK (sheadp);
1518:
1519: if (sigflg == 0) {
1520: /*
1521: * We have been interrupted by a signal, so bang out
1522: * to the caller with EINTR.
1523: */
1524:
1525: retval = EINTR;
1526: break;
1527: } else if (sheadp->sh_dev != devno) {
1528: /*
1529: * The device number has been altered. Flag the fact
1530: * to the caller and give up this lock attempt.
1531: */
1532:
1533: retval = ENODEV;
1534: break;
1535: }
1536:
1537:
1538: /*
1539: * Now we have the global basic lock, we can wrap around to
1540: * the start of the loop to recheck all our conditions.
1541: */
1542: }
1543:
1544:
1545: /*
1546: * For some reason we are aborting the lock attempt. The code which
1547: * make us take this exit path should have set "* retvalp" with an
1548: * error code.
1549: */
1550:
1551: if (sheadp->sh_time_count > sheadp->sh_lock_count) {
1552:
1553: sheadp->sh_time_count --;
1554: ASSERT (sheadp->sh_time_count == sheadp->sh_lock_count);
1555:
1556: SHEAD_START_TIMEOUT (sheadp);
1557: }
1558:
1559: SHEAD_UNREFERENCE (sheadp);
1560: return retval;
1561: }
1562:
1563:
1564: /*
1565: * Entry point for the stream head locking system for use by routines that
1566: * already have a reference to the stream head. This entry performs checks for
1567: * routine errors including linked streams.
1568: */
1569:
1570: #if __USE_PROTO__
1571: int (SHEAD_SLEEP_LOCK) (shead_t * sheadp, cat_t category, __clock_t timeout,
1572: int interruptible)
1573: #else
1574: int
1575: SHEAD_SLEEP_LOCK __ARGS ((sheadp, category, timeout, interruptible))
1576: shead_t * sheadp;
1577: cat_t category;
1578: __clock_t timeout;
1579: int interruptible;
1580: #endif
1581: {
1582: SHEAD_LOCK (sheadp);
1583:
1584: /*
1585: * The read and write lock modes are experimental. We have a mode bit
1586: * that says whether or not we are really interested in honouring
1587: * these lock types.
1588: */
1589:
1590: if (((sheadp->sh_flags & SH_RWLOCKING) == 0 &&
1591: (category & ~ (SH_READ_LOCK | SH_WRITE_LOCK)) == 0)) {
1592:
1593: SHEAD_UNLOCK (sheadp, plbase);
1594: return 0;
1595: }
1596:
1597:
1598: /*
1599: * If the caller wishes to lock a stream head that is part of a stream
1600: * pipe, we direct the lock attempt to the master stream head of the
1601: * pair that form the pipe. This ensures that any attempt to modify
1602: * the state of the pipe from either end will be properly single-
1603: * threaded.
1604: *
1605: * Note that we *must* perform a similar redirection in the unlock.
1606: */
1607:
1608: sheadp = SHEAD_MASTER (sheadp);
1609:
1610:
1611: /*
1612: * We have a pointer to the stream head and hold a global basic lock.
1613: *
1614: * With the protection of the basic lock, we increment the lock count.
1615: */
1616:
1617: sheadp->sh_lock_count ++;
1618:
1619: /*
1620: * Now we begin the actual business of locking the stream head.
1621: */
1622:
1623: return SHEAD_SLEEP_LOCKED (sheadp, category, timeout, interruptible);
1624: }
1625:
1626:
1627: /*
1628: * This is a special form of the stream head locking code for open () access,
1629: * which specially coordinates with the close code to discover when to
1630: * allocate a new stream head, and carefully avoids the problems that can
1631: * occur if the stream head were to be deallocated which we are waiting for
1632: * it to be unlocked.
1633: *
1634: * We also have to do some funky stuff here because of clone opens.
1635: */
1636:
1637: #if __USE_PROTO__
1638: shead_t * (SHEAD_OPEN_LOCK) (n_dev_t dev, struct streamtab * stabp,
1639: int * retvalp)
1640: #else
1641: shead_t *
1642: SHEAD_OPEN_LOCK __ARGS ((dev, stabp, retvalp))
1643: n_dev_t dev;
1644: struct streamtab
1645: * stabp;
1646: int * retvalp;
1647: #endif
1648: {
1649: shead_t * sheadp;
1650:
1651: ASSERT (retvalp != NULL);
1652:
1653: /*
1654: * PHASE 1: Locate the stream head. If the stream head did not
1655: * previously exist, we might be able to lock it immediately by virtue
1656: * of being able to create it that way. Of course, simultaneous open
1657: * attempts might result in this looping as only once of the created
1658: * stream heads will be entered in the stream directory.
1659: */
1660:
1661: * retvalp = 0;
1662:
1663: for (;;) {
1664: queue_t * q;
1665:
1666: /*
1667: * The first thing we need to do is *find* the stream. We call
1668: * a find routine that increments a reference count so that
1669: * we can be sure that the stream will not be deallocated
1670: * while we wait.
1671: */
1672:
1673: if ((sheadp = SHEAD_FIND_AND_LOCK (dev, DEV_SLIST)) != NULL) {
1674: /*
1675: * Sleep lock time; our call to SHEAD_FIND_AND_LOCK ()
1676: * will have incremented the lock count of the stream
1677: * head so it won't disappear underneath us.
1678: */
1679:
1680: * retvalp = SHEAD_SLEEP_LOCKED (sheadp, SH_OPENCLOSE,
1681: 0, CHECK_SIGNALS);
1682:
1683: if (retvalp != 0) {
1684: /*
1685: * If the lock attempt failed because of a
1686: * clone open changing the stream head's
1687: * device number, we need to try again.
1688: */
1689:
1690: sheadp = NULL;
1691:
1692: if (* retvalp == ENODEV)
1693: continue;
1694: }
1695:
1696: return sheadp;
1697: }
1698:
1699:
1700: /*
1701: * There ain't no such stream, so we have to allocate a queue
1702: * pair.
1703: */
1704:
1705: if ((q = QUEUE_ALLOC (2, sizeof (* sheadp))) == NULL) {
1706:
1707: * retvalp = ENFILE;
1708: return NULL;
1709: }
1710:
1711: sheadp = (shead_t *) q->q_ptr;
1712:
1713: SHEAD_INIT (sheadp, stabp, dev, q);
1714:
1715: sheadp->sh_ref_count = 1;
1716: sheadp->sh_lock_mask = SH_OPENCLOSE;
1717: sheadp->sh_time_count = sheadp->sh_lock_count = 1;
1718:
1719: if (SHEAD_ADD (sheadp) == 0)
1720: return sheadp;
1721:
1722: /*
1723: * The new queue could not be added to the stream
1724: * directory, presumably because of a nearly
1725: * simultaneous open attempt.
1726: *
1727: * We undo the allocation we wrought before retrying.
1728: */
1729:
1730: SHEAD_DESTROY (sheadp);
1731: QUEUE_FREE (q, 2, sizeof (* sheadp));
1732: }
1733: }
1734:
1735:
1736: /*
1737: * Unlock a stream head.
1738: */
1739:
1740: #if __USE_PROTO__
1741: void (SHEAD_SLEEP_UNLOCK) (shead_t * sheadp, cat_t category)
1742: #else
1743: void
1744: SHEAD_SLEEP_UNLOCK __ARGS ((sheadp, category))
1745: shead_t * sheadp;
1746: cat_t category;
1747: #endif
1748: {
1749: ASSERT (sheadp != NULL);
1750: ASSERT (category != 0);
1751:
1752: /*
1753: * See if locking is necessary for the read and write operations.
1754: */
1755:
1756: if ((sheadp->sh_flags & SH_RWLOCKING) == 0 &&
1757: (category & ~ (SH_READ_LOCK | SH_WRITE_LOCK)) == 0) {
1758: /*
1759: * Since we don't actually acquire any locks, we return early.
1760: */
1761:
1762: ASSERT (sheadp->sh_open_count > 0);
1763: return;
1764: }
1765:
1766: ASSERT (sheadp->sh_lock_count > 0);
1767: ASSERT ((sheadp->sh_lock_mask & category) == category);
1768:
1769:
1770: /*
1771: * We direct all locking operations on the slave part of a stream pipe
1772: * to the master end.
1773: */
1774:
1775: sheadp = SHEAD_MASTER (sheadp);
1776:
1777: (void) SHEAD_LOCK (sheadp);
1778:
1779:
1780: /*
1781: * Unlike SHEAD_WAKE (), we can assume that our category mask will not
1782: * be NULL because of the difference in interpretation between lock
1783: * flags (indicating a holder) and wait flags (indicating a waiter).
1784: */
1785:
1786: sheadp->sh_lock_mask &= ~ category;
1787: SV_BROADCAST (sheadp->sh_wait_sv, 0);
1788:
1789:
1790: /*
1791: * We don't use SHEAD_END_TIMEOUT () here since we are a lock holder
1792: * and shead_time_func () makes sure to keep our "sh_time_count" entry
1793: * greater than 0.
1794: */
1795:
1796: ASSERT (sheadp->sh_time_count > 0);
1797: sheadp->sh_time_count --;
1798:
1799: if (sheadp->sh_time_count == 0 && sheadp->sh_timeout_id != 0) {
1800: /*
1801: * Since there is no-one waiting for anything, cancel any
1802: * pending timeouts.
1803: */
1804:
1805: untimeout (sheadp->sh_timeout_id);
1806:
1807: sheadp->sh_lock_mask &= SH_TIMEFLAG;
1808: sheadp->sh_timeout_id = 0;
1809: }
1810:
1811:
1812: /*
1813: * Now that we have done everything that requires access to the stream
1814: * head, decrement the lock count.
1815: */
1816:
1817: SHEAD_UNREFERENCE (sheadp);
1818: }
1819:
1820:
1821: /*
1822: * This local function asserts that the caller holds a lock on the stream head.
1823: * Since we can't really determine that, we actually just assert that someone
1824: * has a lock on the stream head.
1825: */
1826:
1827: #if __USE_PROTO__
1828: __LOCAL__ void (ASSERT_SLEEP_LOCKED) (shead_t * sheadp, cat_t category)
1829: #else
1830: __LOCAL__ void
1831: ASSERT_SLEEP_LOCKED __ARGS ((sheadp, category))
1832: shead_t * sheadp;
1833: cat_t category;
1834: #endif
1835: {
1836: ASSERT (sheadp != NULL);
1837:
1838: if (SHEAD_IS_PIPE (sheadp))
1839: sheadp = SHEAD_MASTER (sheadp);
1840:
1841: ASSERT ((sheadp->sh_lock_mask & category) == category);
1842: }
1843:
1844:
1845: /*
1846: * Wait for a queue to drain. The caller must have the stream head locked when
1847: * calling this function.
1848: */
1849:
1850: #if __USE_PROTO__
1851: __LOCAL__ void (DRAIN_QUEUE) (shead_t * sheadp, queue_t * q)
1852: #else
1853: __LOCAL__ void
1854: DRAIN_QUEUE __ARGS ((sheadp, q))
1855: shead_t * sheadp;
1856: queue_t * q;
1857: #endif
1858: {
1859: __clock_t end_time;
1860:
1861: ASSERT_SLEEP_LOCKED (sheadp, SH_OPENCLOSE);
1862:
1863: /*
1864: * When we are in final close, the STREAMS specification says we
1865: * should wait for up to 15 seconds for the write-side queue to be
1866: * drained of data, unless we are in O_NONBLOCK mode.
1867: *
1868: * If we can't post the timeout, then don't wait.
1869: */
1870:
1871: if (sheadp->sh_cltime == 0)
1872: return;
1873:
1874: (void) drv_getparm (LBOLT, & end_time);
1875: end_time += sheadp->sh_cltime;
1876:
1877: for (;;) {
1878: /*
1879: * We need to acquire a basic lock to pass to SV_WAIT (), and
1880: * the code that wakes us up will attempt to acquire the same
1881: * lock (see QUEUE_DRAINED ()). Since the wakeup code must
1882: * acquire the lock while holding the stream frozen, we must
1883: * do things in the same order to prevent the possibility of
1884: * deadlock.
1885: */
1886:
1887: (void) QFREEZE_TRACE (q, "DRAIN_QUEUE");
1888:
1889: if (q->q_first == NULL) {
1890: /*
1891: * No messages on the queue => our job is done.
1892: */
1893:
1894: QUNFREEZE_TRACE (q, plbase);
1895: break;
1896: }
1897:
1898:
1899: /*
1900: * We are going to wait for this queue to become empty, so we
1901: * set a flag to indicate that we are interested in finding
1902: * out when that happens. Note that we don't ever clear the
1903: * flag in this routine; that is the responsibility of the
1904: * code which will wake us up.
1905: */
1906:
1907: q->q_flag |= QDRAIN;
1908:
1909:
1910: /*
1911: * We don't build on SHEAD_WAIT (), although we do expect to
1912: * be woken up via SHEAD_WAKE (). We transfer our lock from
1913: * the queue to the stream head.
1914: */
1915:
1916: (void) SHEAD_LOCK (sheadp);
1917:
1918: QUNFREEZE_TRACE (q, plstr);
1919:
1920:
1921: /*
1922: * Register when we want to time out. If that time has already
1923: * passed, then exit to the caller.
1924: */
1925:
1926: if (SHEAD_LOCKED_TIMEOUT (sheadp, end_time) == 0) {
1927:
1928: SHEAD_UNLOCK (sheadp, plbase);
1929: return;
1930: }
1931:
1932: sheadp->sh_lock_mask |= SH_DRAIN_WAIT;
1933:
1934: SV_WAIT (sheadp->sh_wait_sv, primed, sheadp->sh_basic_lockp);
1935:
1936: /*
1937: * We were signalled, so we try again.
1938: */
1939: }
1940: }
1941:
1942:
1943: /*
1944: * This function (used in the implementation of I_LIST ioctl ()) returns a
1945: * count of the number of modules on the stream, including the topmost driver.
1946: */
1947:
1948: #if __USE_PROTO__
1949: __LOCAL__ int (SHEAD_MODCOUNT) (shead_t * sheadp)
1950: #else
1951: __LOCAL__ int
1952: SHEAD_MODCOUNT __ARGS ((sheadp))
1953: shead_t * sheadp;
1954: #endif
1955: {
1956: pl_t prev_pl;
1957: int count;
1958: queue_t * scan;
1959:
1960: ASSERT (sheadp != NULL);
1961:
1962: /*
1963: * Note that we use SHEAD_MASTER () because this walk can be affected
1964: * by attempts to push or pop queues from either end of a stream pipe.
1965: * Using a single lock at the master end avoids problems with this.
1966: */
1967:
1968: prev_pl = SHEAD_LOCK (SHEAD_MASTER (sheadp));
1969:
1970: count = 0;
1971:
1972: for (scan = W (sheadp->sh_head)->q_next ; scan != NULL ;
1973: scan = scan->q_next) {
1974:
1975: if ((scan->q_flag & QPROCSOFF) == 0)
1976: count ++;
1977: }
1978:
1979: SHEAD_UNLOCK (SHEAD_MASTER (sheadp), prev_pl);
1980:
1981: return count;
1982: }
1983:
1984:
1985: /*
1986: * Utility routine to return the next write queue below the stream head. This
1987: * routine deals with locking the stream head for the duration of the walk and
1988: * also check whether the queue has been disabled with qprocsoff ().
1989: */
1990:
1991: #if __USE_PROTO__
1992: __LOCAL__ queue_t * (TOP_QUEUE) (shead_t * sheadp)
1993: #else
1994: __LOCAL__ queue_t *
1995: TOP_QUEUE __ARGS ((sheadp))
1996: shead_t * sheadp;
1997: #endif
1998: {
1999: pl_t prev_pl;
2000: queue_t * scan;
2001:
2002: ASSERT (sheadp != NULL);
2003:
2004: /*
2005: * Note that we use SHEAD_MASTER () because this walk can be affected
2006: * by attempts to push or pop queues from either end of a stream pipe.
2007: * Using a single lock at the master end avoids problems with this.
2008: */
2009:
2010: prev_pl = SHEAD_LOCK (SHEAD_MASTER (sheadp));
2011:
2012: scan = W (sheadp->sh_head)->q_next;
2013:
2014: while ((scan->q_flag & QPROCSOFF) != 0)
2015: if ((scan = scan->q_next) == NULL)
2016: cmn_err (CE_PANIC, "Off end of stream in TOP_QUEUE ()");
2017:
2018: SHEAD_UNLOCK (SHEAD_MASTER (sheadp), prev_pl);
2019:
2020: return scan;
2021: }
2022:
2023:
2024: /*
2025: * Utility routine for POP_MODULE () and the I_LOOK processing code that finds
2026: * the queue entry for the first module on the stream (if any).
2027: */
2028:
2029: #if __USE_PROTO__
2030: __LOCAL__ queue_t * (TOP_MODULE) (shead_t * sheadp)
2031: #else
2032: __LOCAL__ queue_t *
2033: TOP_MODULE __ARGS ((sheadp))
2034: shead_t * sheadp;
2035: #endif
2036: {
2037: queue_t * scan; /* module queue */
2038:
2039: /*
2040: * We return the queue pointer if and only if the thing below the
2041: * stream head is a module (not a driver) AND the module's read and
2042: * write queues are not interchanged (as they would be at the
2043: * crossover point of a STREAMS-based FIFO).
2044: */
2045:
2046: scan = TOP_QUEUE (sheadp);
2047:
2048: if ((scan->q_flag & QREADR) !=
2049: (W (sheadp->sh_head)->q_flag & QREADR))
2050: return NULL;
2051:
2052: /*
2053: * The test to see whether "scan" is a module or driver does not need
2054: * to involve QUEUE_NEXT (), since the exact value of 'q->q_next'
2055: * isn't important to us, just whether or not it's NULL.
2056: */
2057:
2058: {
2059: pl_t prev_pl;
2060: queue_t * next;
2061:
2062: prev_pl = QFREEZE_TRACE (scan, "TOP_MODULE");
2063:
2064: next = scan->q_next;
2065:
2066: QUNFREEZE_TRACE (scan, prev_pl);
2067:
2068: if (next == NULL)
2069: return NULL;
2070: }
2071:
2072: return R (scan);
2073: }
2074:
2075:
2076: /*
2077: * Code common to both POP_MODULE () and PUSH_MODULE () for removing and
2078: * deallocating a queue pair from a stream.
2079: */
2080:
2081: #if __USE_PROTO__
2082: __LOCAL__ void (POP_AND_FREE) (shead_t * sheadp, queue_t * module)
2083: #else
2084: __LOCAL__ void
2085: POP_AND_FREE __ARGS ((sheadp, module))
2086: shead_t * sheadp;
2087: queue_t * module;
2088: #endif
2089: {
2090: pl_t prev_pl;
2091: pl_t q_pl;
2092: queue_t * next;
2093:
2094:
2095: /*
2096: * Now we must unlink the module queue from the stream. To do this, we
2097: * freeze each queue before we change it. However, that is not enough
2098: * if we are on a stream pipe, since the stream head at the other end
2099: * of the pipe could be trying to modify the same stream, and thus the
2100: * same queue pointers that we are going to change.
2101: *
2102: * We work our way around this by defining a master/slave relationship
2103: * between the ends of a pipe, and requiring that the slave end
2104: * acquire an exclusive lock on the "sh_rwlockp" lock belonging to the
2105: * master. Since the master and slave contend for the same lock, we
2106: * can be confident no other concurrent modifications to the stream
2107: * are possible.
2108: */
2109:
2110: prev_pl = SHEAD_LOCK (SHEAD_MASTER (sheadp));
2111:
2112: next = W (sheadp->sh_head);
2113:
2114: ASSERT (next->q_next == W (module));
2115:
2116: q_pl = QFREEZE_TRACE (next, "POP_AND_FREE");
2117: next->q_next = W (module)->q_next;
2118: QUNFREEZE_TRACE (next, q_pl);
2119:
2120:
2121: next = OTHERQ (next->q_next);
2122:
2123: ASSERT (next->q_next == module);
2124:
2125: q_pl = QFREEZE_TRACE (next, "POP_AND_FREE");
2126: next->q_next = sheadp->sh_head;
2127: QUNFREEZE_TRACE (next, q_pl);
2128:
2129:
2130: SHEAD_UNLOCK (SHEAD_MASTER (sheadp), prev_pl);
2131:
2132:
2133: /*
2134: * Now we can de-initialize the queue pair and free the memory.
2135: */
2136:
2137: QUEUE_FREE (module, 1, 0);
2138: }
2139:
2140:
2141: /*
2142: * Pop a module from a stream. In order to request this, the caller must have
2143: * the stream head sleep-locked for modification (see SHEAD_SLEEP_LOCK ()
2144: * above).
2145: *
2146: * Returns 0 on success or an error number on failure.
2147: */
2148:
2149: #if __USE_PROTO__
2150: int (POP_MODULE) (shead_t * sheadp, queue_t * q, int mode, cred_t * credp)
2151: #else
2152: int
2153: POP_MODULE __ARGS ((sheadp, q, mode, credp))
2154: shead_t * sheadp;
2155: queue_t * q;
2156: int mode;
2157: cred_t * credp;
2158: #endif
2159: {
2160: int retval;
2161:
2162: ASSERT (q != NULL);
2163: ASSERT_SLEEP_LOCKED (sheadp, SH_OPENCLOSE);
2164:
2165: /*
2166: * When a module is popped, it is blown away. If the module needs to
2167: * be drained first (as in final close) then the caller has to do it.
2168: */
2169:
2170: retval = (* q->q_qinfo->qi_qclose) (q, mode, credp);
2171:
2172: if (retval != 0)
2173: cmn_err (CE_WARN, "module close returned %d in POP_MODULE",
2174: retval);
2175:
2176: /*
2177: * In case the module didn't turn off put and service routines.
2178: */
2179:
2180: if ((q->q_flag & QPROCSOFF) == 0) {
2181:
2182: cmn_err (CE_WARN, "Module %s did not call qprocsoff ()",
2183: q->q_qinfo->qi_minfo->mi_idname);
2184: qprocsoff (q);
2185: }
2186:
2187:
2188: /*
2189: * And now we can release the module. We do this whether or not the
2190: * caller returned an error.
2191: */
2192:
2193: POP_AND_FREE (sheadp, q);
2194:
2195: return retval;
2196: }
2197:
2198:
2199: /*
2200: * This function pushes the indicated module onto a stream. The caller must
2201: * have the stream head sleep-locked for modification.
2202: */
2203:
2204: #if __USE_PROTO__
2205: int (PUSH_MODULE) (shead_t * sheadp, int mode, cred_t * credp,
2206: modsw_t * module)
2207: #else
2208: int
2209: PUSH_MODULE __ARGS ((sheadp, mode, credp, module))
2210: shead_t * sheadp;
2211: int mode;
2212: cred_t * credp;
2213: modsw_t * module;
2214: #endif
2215: {
2216: queue_t * q;
2217: queue_t * prev;
2218: pl_t prev_pl;
2219: pl_t q_pl;
2220: int retval;
2221: n_dev_t dev;
2222: char * modname;
2223:
2224: ASSERT (module != NULL);
2225: ASSERT_SLEEP_LOCKED (sheadp, SH_OPENCLOSE);
2226:
2227: if ((q = QUEUE_ALLOC (1, 0)) == NULL)
2228: return ENOSR;
2229:
2230: QUEUE_INIT (q, module->mod_stream, QI_NORMAL);
2231:
2232: /*
2233: * First we have to link the module into the stream. The newly
2234: * allocated queues will have the QPROCSOFF flag set so that they are
2235: * ignored by other stream elements until the new module has been
2236: * opened.
2237: *
2238: * As above in POP_MODULE (), we acquire a write lock on the stream
2239: * head, which must be a master end if a stream pipe.
2240: */
2241:
2242: prev_pl = SHEAD_LOCK (SHEAD_MASTER (sheadp));
2243:
2244: prev = W (sheadp->sh_head);
2245: W (q)->q_next = prev->q_next;
2246:
2247: q_pl = QFREEZE_TRACE (prev, "PUSH_MODULE");
2248: prev->q_next = W (q);
2249: QUNFREEZE_TRACE (prev, q_pl);
2250:
2251: prev = OTHERQ (W (q)->q_next);
2252: q->q_next = sheadp->sh_head;
2253:
2254: ASSERT (prev->q_next == sheadp->sh_head);
2255:
2256: q_pl = QFREEZE_TRACE (prev, "PUSH_MODULE");
2257: prev->q_next = q;
2258: QUNFREEZE_TRACE (prev, q_pl);
2259:
2260: SHEAD_UNLOCK (SHEAD_MASTER (sheadp), prev_pl);
2261:
2262:
2263: /*
2264: * Ask the module to set itself up.
2265: */
2266:
2267: dev = sheadp->sh_dev;
2268:
2269: retval = (* q->q_qinfo->qi_qopen) (q, & dev, mode, MODOPEN,
2270: credp);
2271:
2272: modname = q->q_qinfo->qi_minfo->mi_idname;
2273:
2274: if (dev != sheadp->sh_dev)
2275: cmn_err (CE_WARN, "Module \"%s\" altered its \"dev\" parameter",
2276: modname);
2277:
2278: if (retval != 0) {
2279: /*
2280: * OK, don't really open this. The module should not have
2281: * turned on it's put and service routines.
2282: */
2283:
2284: if ((q->q_flag & QPROCSOFF) == 0) {
2285:
2286: cmn_err (CE_WARN, "PUSH_MODULE () : Module %s enabled queue!",
2287: modname);
2288: qprocson (q);
2289: }
2290:
2291: POP_AND_FREE (sheadp, q);
2292: } else if ((q->q_flag & QPROCSOFF) != 0) {
2293:
2294: cmn_err (CE_WARN, "PUSH_MODULE () : Module %s did not enable queue!",
2295: modname);
2296: qprocson (q);
2297: }
2298:
2299: return retval;
2300: }
2301:
2302:
2303: /*
2304: * This function sends an IOCTL message downstream, then blocks until either
2305: * a reply arrives at the stream head, the (optional) timeout has expired, or
2306: * a signal is received.
2307: *
2308: * The caller must have the stream head locked for ioctl () processing.
2309: */
2310:
2311: #if __USE_PROTO__
2312: mblk_t * (IOCTL_SEND) (shead_t * sheadp, int mode, mblk_t * msg,
2313: int * errretp, __clock_t timeout_time)
2314: #else
2315: mblk_t *
2316: IOCTL_SEND __ARGS ((sheadp, mode, msg, errretp, timeout_time))
2317: shead_t * sheadp;
2318: int mode;
2319: mblk_t * msg;
2320: int * errretp;
2321: __clock_t timeout_time;
2322: #endif
2323: {
2324: __clock_t end_time;
2325: int retval;
2326:
2327: ASSERT_SLEEP_LOCKED (sheadp, SH_IOCTL_LOCK);
2328: ASSERT (errretp != NULL);
2329: ASSERT (msg != NULL);
2330:
2331: /*
2332: * Set the optional timeout up first. If the timeout cannot be
2333: * allocated, we have to return failure.
2334: */
2335:
2336: if (timeout_time > 0) {
2337:
2338: (void) drv_getparm (LBOLT, & end_time);
2339: end_time += timeout_time;
2340: }
2341:
2342:
2343: /*
2344: * Now send the client's message downstream. We queue the message on
2345: * the write queue rather than directly putting it to avoid the
2346: * possibility of deadlock if an acknowledgement is sent back to us
2347: * while we are holding the basic lock below.
2348: *
2349: * We also have to check for the possibility that an error has occurred
2350: * on the stream.
2351: */
2352:
2353: (void) SHEAD_LOCK (sheadp);
2354:
2355: for (;;) {
2356: if (sheadp->sh_ioc_msg != NULL) {
2357: /*
2358: * If there is some stale ioctl () message lying
2359: * around, dispose of it.
2360: */
2361:
2362: freemsg (sheadp->sh_ioc_msg);
2363: sheadp->sh_ioc_msg = NULL;
2364: }
2365:
2366: if (msg != NULL)
2367: putq (W (sheadp->sh_head), msg);
2368:
2369: msg = NULL;
2370:
2371:
2372: /*
2373: * Before we go to sleep, we schedule our timeout.
2374: */
2375:
2376: if (timeout_time > 0 &&
2377: SHEAD_LOCKED_TIMEOUT (sheadp, end_time) == 0) {
2378: /*
2379: * We have timed out.
2380: */
2381:
2382: retval = ETIME;
2383: break;
2384: }
2385:
2386:
2387: if (sheadp->sh_open_count == 0) {
2388: /*
2389: * This is a kernel-generated ioctl () and signalling
2390: * is not allowed to interrupt us. We pass a NULL mode
2391: * to avoid detecting errors.
2392: */
2393:
2394: ASSERT_SLEEP_LOCKED (sheadp, SH_OPENCLOSE);
2395:
2396: retval = SHEAD_WAIT (sheadp, 0, SH_IOCTL_WAIT,
2397: DONT_SIGNAL);
2398: } else {
2399: /*
2400: * SHEAD_WAIT () checks for hangups as well, if the
2401: * mode includes read or write.
2402: */
2403:
2404: ASSERT ((mode & (FREAD | FWRITE)) != 0);
2405:
2406: retval = SHEAD_WAIT (sheadp, mode, SH_IOCTL_WAIT,
2407: CHECK_SIGNALS);
2408: }
2409:
2410:
2411: /*
2412: * We take out the basic lock here again so we can read
2413: * "sheadp->sh_ioc_msg" atomically.
2414: */
2415:
2416: (void) SHEAD_LOCK (sheadp);
2417:
2418: msg = sheadp->sh_ioc_msg;
2419: sheadp->sh_ioc_msg = NULL;
2420:
2421: if (retval != 0 || msg != NULL)
2422: break;
2423:
2424: /*
2425: * We have been woken up either by a timeout, or for some
2426: * activity at the stream head not related to us. We loop to
2427: * deal with this.
2428: */
2429: }
2430:
2431: if (retval != 0) {
2432:
2433: if (errretp != NULL)
2434: * errretp = retval;
2435:
2436: if (msg != NULL)
2437: freemsg (msg);
2438:
2439: msg = NULL;
2440: }
2441:
2442: SHEAD_UNLOCK (sheadp, plbase);
2443:
2444: return msg;
2445: }
2446:
2447:
2448: /*
2449: * This function manages transparent ioctl () processing; it sets itself up
2450: * to service M_COPYIN and M_COPYOUT requests from a driver until it sees an
2451: * M_IOCACK or M_IOCNAK.
2452: */
2453:
2454: typedef union {
2455: struct iocblk ioc;
2456: struct copyreq req;
2457: struct copyresp resp;
2458: } x_ioc_t;
2459:
2460: #if __USE_PROTO__
2461: __LOCAL__ int (TRANSPARENT_IOCTL) (shead_t * sheadp, int mode, int cmd,
2462: _VOID * arg, cred_t * credp, int * rvalp)
2463: #else
2464: __LOCAL__ int
2465: TRANSPARENT_IOCTL __ARGS ((sheadp, mode, cmd, arg, credp, rvalp))
2466: shead_t * sheadp;
2467: int mode;
2468: int cmd;
2469: _VOID * arg;
2470: cred_t * credp;
2471: int * rvalp;
2472: #endif
2473: {
2474: mblk_t * msg;
2475: mblk_t * data;
2476: int retval;
2477: x_ioc_t * ioc;
2478:
2479: ASSERT_SLEEP_LOCKED (sheadp, SH_IOCTL_LOCK);
2480:
2481: /*
2482: * The message block allocated for a transparent ioctl () must be
2483: * large enough to hold any of the ioctl-related message types so that
2484: * modules and drivers (and the stream head) can just change the
2485: * message type to reply to a message.
2486: */
2487:
2488: if ((msg = MSGB_ALLOC (sizeof (* ioc), BPRI_LO, KM_SLEEP)) == NULL)
2489: return ENOSR;
2490:
2491: ioc = (x_ioc_t *) msg->b_rptr;
2492: msg->b_wptr = (unsigned char *) (ioc + 1);
2493:
2494: msg->b_datap->db_type = M_IOCTL;
2495:
2496: ioc->ioc.ioc_cmd = cmd;
2497: ioc->ioc.ioc_cr = credp;
2498: ioc->ioc.ioc_id = ++ sheadp->sh_ioc_seq;
2499: ioc->ioc.ioc_count = TRANSPARENT;
2500: ioc->ioc.ioc_rval = ioc->ioc.ioc_error = 0;
2501:
2502:
2503: /*
2504: * A transparent ioctl () gets a single data block containing the
2505: * value of "arg".
2506: */
2507:
2508: if ((data = MSGB_ALLOC (sizeof (arg), BPRI_LO, KM_SLEEP)) == NULL) {
2509:
2510: retval = ENOSR;
2511: goto done;
2512: }
2513:
2514: * (_VOID **) data->b_rptr = arg;
2515: data->b_wptr += sizeof (arg);
2516:
2517:
2518: for (;;) {
2519: /*
2520: * Now we send the ioctl () and wait for the acknowledgement.
2521: * Transparent ioctl ()'s wait forever, but M_ERROR and
2522: * hangup events are interesting to us, so we can blow out.
2523: */
2524:
2525: if ((msg = IOCTL_SEND (sheadp, mode, msg, & retval,
2526: 0)) == NULL)
2527: return retval;
2528:
2529:
2530: /*
2531: * Transparent ioctl ()'s dont have to worry about data coming
2532: * back in the M_IOCACK message, they just have to process the
2533: * M_COPYIN and M_COPYOUT requests.
2534: */
2535:
2536: switch (msg->b_datap->db_type) {
2537:
2538: case M_IOCNAK:
2539: retval = ioc->ioc.ioc_error;
2540: goto done;
2541:
2542: case M_IOCACK:
2543: * rvalp = ioc->ioc.ioc_rval;
2544: retval = ioc->ioc.ioc_error;
2545:
2546: if (ioc->ioc.ioc_count > 0)
2547: cmn_err (CE_WARN, "Transparent ioctl () processing forbids data in M_IOCACK");
2548: goto done;
2549:
2550: case M_COPYIN:
2551: if ((data = msg->b_cont) != NULL)
2552: freemsg (data);
2553:
2554: /*
2555: * The STREAMS documentation is unclear as to whether
2556: * these blocks are split up or not, but it seems
2557: * unlikely.
2558: */
2559:
2560: if ((data = MSGB_ALLOC (ioc->req.cq_size, BPRI_LO,
2561: KM_SLEEP)) == NULL)
2562: retval = ENOSR;
2563: else if (copyin (ioc->req.cq_addr, data->b_rptr,
2564: ioc->req.cq_size) != 0) {
2565: freemsg (data);
2566: data = NULL;
2567: retval = EFAULT;
2568: } else {
2569:
2570: data->b_wptr = data->b_rptr +
2571: ioc->req.cq_size;
2572: retval = 0;
2573: }
2574:
2575: msg->b_cont = data;
2576: break;
2577:
2578: case M_COPYOUT:
2579: retval = 0;
2580:
2581: while (ioc->req.cq_size > 0 &&
2582: (data = msg->b_cont) != NULL) {
2583: size_t unit;
2584:
2585: /*
2586: * Copy a single M_DATA block at a time. After
2587: * copying, we free the block.
2588: */
2589:
2590: unit = data->b_wptr - data->b_rptr;
2591: if (unit > ioc->req.cq_size)
2592: unit = ioc->req.cq_size;
2593:
2594: if (copyout (data->b_rptr, ioc->req.cq_addr,
2595: unit) != 0) {
2596: retval = EFAULT;
2597: break;
2598: }
2599:
2600: ioc->req.cq_size -= unit;
2601: ioc->req.cq_addr += unit;
2602:
2603: msg->b_cont = data->b_cont;
2604: freeb (data);
2605: }
2606:
2607: /*
2608: * Throw away uncopied extra data.
2609: */
2610:
2611: if ((data = msg->b_cont) != NULL)
2612: freemsg (data);
2613:
2614: msg->b_cont = NULL;
2615: break;
2616:
2617: default:
2618: cmn_err (CE_WARN, "Invalid message type %d received during unlink processing",
2619: msg->b_datap->db_type);
2620: retval = ENXIO;
2621: goto done;
2622: }
2623:
2624: /*
2625: * In common code for M_COPYIN and M_COPYOUT, we turn around
2626: * the request message. If the request succeeded, we wrap
2627: * around to the top of the loop to serve the next request;
2628: * it there has been an error, we just put the message and
2629: * bail out.
2630: */
2631:
2632: msg->b_datap->db_type = M_IOCDATA;
2633: ioc->resp.cp_rval = (caddr_t) retval;
2634:
2635: if (retval != 0) {
2636:
2637: putq (W (sheadp->sh_head), msg);
2638: break;
2639: }
2640: }
2641:
2642: done:
2643: freemsg (msg);
2644:
2645: return retval;
2646: }
2647:
2648:
2649: /*
2650: * This function contains code common to the ioctl () message processing for
2651: * stream link and unlink commands. These ioctl ()s send messages downstream
2652: * which are all of a single common form.
2653: */
2654:
2655: #if __USE_PROTO__
2656: __LOCAL__ int (LINK_MESSAGE) (shead_t * upper, int mode, shead_t * lower,
2657: int cmd, int muxid, cred_t * credp,
2658: int * retvalp)
2659: #else
2660: __LOCAL__ int
2661: LINK_MESSAGE __ARGS ((upper, mode, lower, cmd, muxid, credp, retvalp))
2662: shead_t * upper;
2663: int mode;
2664: shead_t * lower;
2665: int cmd;
2666: int muxid;
2667: cred_t * credp;
2668: int * retvalp;
2669: #endif
2670: {
2671: mblk_t * msg;
2672: struct iocblk * ioc;
2673: struct linkblk * linkblk;
2674: int ackflag;
2675: queue_t * q;
2676:
2677: ASSERT_SLEEP_LOCKED (upper, SH_OPENCLOSE | SH_IOCTL_LOCK);
2678: ASSERT_SLEEP_LOCKED (lower, SH_OPENCLOSE | SH_IOCTL_LOCK);
2679: ASSERT (credp != NULL);
2680:
2681: /*
2682: * Set ourselves up for a STREAMS ioctl (). Note that since we keep
2683: * transparent ioctl () processing separate from normal I_STR code, we
2684: * don't have to allocate an initial message block that can be turned
2685: * into a "copyreq" or "copyresp" structure.
2686: */
2687:
2688:
2689: if ((msg = MSGB_ALLOC (sizeof (* ioc), BPRI_LO, KM_SLEEP)) == NULL)
2690: return ENOSR;
2691:
2692: ioc = (struct iocblk *) msg->b_rptr;
2693: msg->b_wptr = (unsigned char *) (ioc + 1);
2694:
2695: msg->b_datap->db_type = M_IOCTL;
2696:
2697: ioc->ioc_cmd = cmd;
2698: ioc->ioc_cr = credp;
2699: ioc->ioc_id = ++ upper->sh_ioc_seq;
2700: ioc->ioc_count = sizeof (struct linkblk);
2701: ioc->ioc_rval = ioc->ioc_error = 0;
2702:
2703:
2704: /*
2705: * Now we allocate and fill in the data part of the I_...LINK message.
2706: */
2707:
2708: if ((msg->b_cont = MSGB_ALLOC (sizeof (struct linkblk), BPRI_LO,
2709: KM_SLEEP)) == NULL) {
2710: freeb (msg);
2711: return ENOSR;
2712: }
2713:
2714: linkblk = (struct linkblk *) msg->b_cont->b_rptr;
2715: msg->b_cont->b_wptr = (unsigned char *) (linkblk + 1);
2716:
2717:
2718: /*
2719: * Find the bottom-most write queue on the upper stream. To make this
2720: * walk of the queue safe with respect to I_PUSH and I_POP, we take
2721: * out a read lock on the stream head. See the PUSH_MODULE () and
2722: * POP_MODULE () routines for more details on this.
2723: *
2724: * We don't use QUEUE_NEXT () because the intermediate modules are of
2725: * no interest to us; we just want the driver at the bottom.
2726: */
2727:
2728: {
2729: queue_t * next;
2730:
2731: (void) SHEAD_LOCK (upper);
2732:
2733: next = W (upper->sh_head);
2734:
2735: do {
2736: q = next;
2737:
2738: (void) QFREEZE_TRACE (q, "LINK_MESSAGE");
2739:
2740: next = q->q_next;
2741:
2742: QUNFREEZE_TRACE (q, plbase);
2743: } while (next != NULL);
2744:
2745: SHEAD_UNLOCK (upper, plbase);
2746: }
2747:
2748: linkblk->l_qtop = q;
2749: linkblk->l_qbot = lower->sh_head;
2750: linkblk->l_index = muxid;
2751:
2752:
2753: /*
2754: * Now we send the ioctl () and wait for the acknowledgement. Since
2755: * there is no mechanism for managing this timeout, we will use the
2756: * close timeout (which is appropriate given that this operation will
2757: * often be performed as the result of a close ()).
2758: */
2759:
2760: if ((msg = IOCTL_SEND (upper, mode, msg, retvalp,
2761: upper->sh_cltime)) == NULL)
2762: return 0; /* counts as a negative ack */
2763:
2764: /*
2765: * Now we see what kind of message the driver has send to us.
2766: */
2767:
2768: ioc = (struct iocblk *) msg->b_rptr;
2769:
2770: if (retvalp != NULL)
2771: * retvalp = ioc->ioc_error;
2772:
2773: switch (msg->b_datap->db_type) {
2774:
2775: case M_IOCNAK:
2776: ackflag = 0;
2777: break;
2778:
2779: case M_IOCACK:
2780: /*
2781: * We do not copy the "ioc_rval" member out because it is not
2782: * documented as forming the return value from such a link-
2783: * style ioctl () request.
2784: */
2785:
2786: /*
2787: * Since "arg" for an I_UNLINK or I_PUNLINK is not a pointer,
2788: * it makes no sense for a driver to attempt to return data
2789: * for the user. Since the canonical multiplexing driver code
2790: * clears ioc_count and simply turns around the message, it
2791: * is not a problem for there to be M_DATA messages following
2792: * the M_IOCACK, but it is a problem if "ioc_count" is greater
2793: * than 0.
2794: */
2795:
2796: ackflag = 1;
2797:
2798: if (ioc->ioc_count > 0)
2799: cmn_err (CE_WARN, "Driver %s returned data with link/unlink ioctl ()",
2800: q->q_qinfo->qi_minfo->mi_idname);
2801:
2802: break;
2803:
2804: default:
2805: cmn_err (CE_WARN, "Invalid message type %d received during link/unlink processing",
2806: msg->b_datap->db_type);
2807: * retvalp = ENXIO;
2808:
2809: ackflag = 0; /* treat as a negative ack */
2810: break;
2811: }
2812:
2813: freemsg (msg);
2814:
2815: return ackflag;
2816: }
2817:
2818:
2819: /*
2820: * Helper function for the link/unlink process to restore a stream to the
2821: * unlinked state.
2822: */
2823:
2824: #if __USE_PROTO__
2825: __LOCAL__ int (SHEAD_INIT_UNLINKED) (shead_t * sheadp)
2826: #else
2827: __LOCAL__ int
2828: SHEAD_INIT_UNLINKED __ARGS ((sheadp))
2829: shead_t * sheadp;
2830: #endif
2831: {
2832: pl_t prev_pl;
2833: int final_close;
2834:
2835: ASSERT_SLEEP_LOCKED (sheadp, SH_OPENCLOSE | SH_IOCTL_LOCK);
2836:
2837: /*
2838: * The driver is no longer using this stream; restore it to normal
2839: * operation. Note that we have to reset "q_ptr" back to point at the
2840: * stream head!
2841: */
2842:
2843: prev_pl = SHEAD_LOCK (sheadp);
2844:
2845: sheadp->sh_linked = NULL;
2846: sheadp->sh_flags &= ~ SH_PLINK;
2847:
2848: final_close = -- sheadp->sh_open_count == 0;
2849:
2850: SHEAD_UNLOCK (sheadp, prev_pl);
2851:
2852:
2853: prev_pl = QFREEZE_TRACE (sheadp->sh_head, "SHEAD_INIT_UNLINKED");
2854:
2855: sheadp->sh_head->q_ptr = sheadp;
2856: W (sheadp->sh_head)->q_ptr = sheadp;
2857:
2858: QUEUE_INIT (sheadp->sh_head, sheadp->sh_tab, QI_NORMAL);
2859:
2860: QUNFREEZE_TRACE (sheadp->sh_head, prev_pl);
2861:
2862: return final_close;
2863: }
2864:
2865:
2866: /*
2867: * This function takes care of unlinking a lower stream from an upper stream.
2868: *
2869: * The caller should have both the upper and lower stream heads locked for
2870: * open/close processing.
2871: */
2872:
2873: #if __USE_PROTO__
2874: __LOCAL__ int (LOCKED_UNLINK) (shead_t * upper, int mode, shead_t * lower,
2875: int cmd, cred_t * credp, int * retvalp)
2876: #else
2877: __LOCAL__ int
2878: LOCKED_UNLINK __ARGS ((upper, mode, lower, cmd, credp, retvalp))
2879: shead_t * upper;
2880: int mode;
2881: shead_t * lower;
2882: int cmd;
2883: cred_t * credp;
2884: int * retvalp;
2885: #endif
2886: {
2887: ASSERT_SLEEP_LOCKED (upper, SH_OPENCLOSE | SH_IOCTL_LOCK);
2888: ASSERT_SLEEP_LOCKED (lower, SH_OPENCLOSE | SH_IOCTL_LOCK);
2889:
2890: /*
2891: * Check that the right kind of unlink command is being issued.
2892: */
2893:
2894: if (lower->sh_linked != upper ||
2895: ((lower->sh_flags & SH_PLINK) != 0) == (cmd == I_PUNLINK))
2896: return EINVAL;
2897:
2898: /*
2899: * Send the message downstream and get the return result.
2900: */
2901:
2902: if (LINK_MESSAGE (upper, mode, lower, cmd, lower->sh_muxid, credp,
2903: retvalp)) {
2904: /*
2905: * The unlink was properly acknowledged. Note that this may
2906: * cause the lower stream to close.
2907: */
2908:
2909: if (SHEAD_INIT_UNLINKED (lower) != 0)
2910: SHEAD_DO_CLOSE (lower, mode, credp);
2911:
2912: return 1;
2913: }
2914:
2915: return 0;
2916: }
2917:
2918:
2919: /*
2920: * This function wraps up part of the required client functionality for
2921: * callers of SHEAD_UNLINK () by dealing with locking the lower stream head
2922: * and making appropriate calls to see if it needs closing.
2923: */
2924:
2925: #if __USE_PROTO__
2926: __LOCAL__ int (SHEAD_UNLINK) (shead_t * upper, shead_t * lower, int cmd,
2927: int mode, cred_t * credp, int * retvalp)
2928: #else
2929: __LOCAL__ int
2930: SHEAD_UNLINK __ARGS ((upper, lower, cmd, mode, credp, retvalp))
2931: shead_t * upper;
2932: shead_t * lower;
2933: int cmd;
2934: int mode;
2935: cred_t * credp;
2936: int * retvalp;
2937: #endif
2938: {
2939: int success;
2940:
2941: /*
2942: * In order to unlink this lower stream we first have to lock it. This
2943: * is necessary not only to ensure that we don't trip up other
2944: * operations affecting this stream (since there may be open file
2945: * descriptors referring to it, and/or it may be a stream pipe) but
2946: * since stream deallocations are checked for in the unlock code this
2947: * is necessary to ensure that an unlink of an otherwise unreferenced
2948: * stream does the right thing.
2949: */
2950:
2951: if ((* retvalp = SHEAD_SLEEP_LOCK (lower,
2952: SH_OPENCLOSE | SH_IOCTL_LOCK, 0,
2953: DONT_SIGNAL)) != 0) {
2954:
2955: cmn_err (CE_WARN, "Unable to lock stream in SHEAD_UNLINK (), error %d",
2956: * retvalp);
2957: return 1;
2958: }
2959:
2960:
2961: /*
2962: * OK, we unlink this lower stream, and do all the stuff we
2963: * need to do to ensure that the lower stream gets closed if
2964: * its time has come.
2965: */
2966:
2967: success = LOCKED_UNLINK (upper, mode, lower, cmd, credp, retvalp);
2968:
2969: SHEAD_SLEEP_UNLOCK (lower, SH_OPENCLOSE | SH_IOCTL_LOCK);
2970:
2971: return success;
2972: }
2973:
2974:
2975: /*
2976: * Loop-detection algorithm for use in SHEAD_LINK ().
2977: *
2978: * The STREAMS documentation is very vague about what constitutes a cycle in
2979: * the link graph, probably deliberately.
2980: *
2981: * For our purposes we consider a cycle to be caused by any path of links
2982: * which lead upwards (to user level) from the *device* indicated by "upper"
2983: * to the *device* indicated by "lower".
2984: *
2985: * Frankly, given the nature of multiplexing drivers in terms of routing
2986: * information, I really don't see much advantage in this; it is perfectly
2987: * easy for messages cycles to form other ways, and given the typical nature
2988: * of multiplexor services interfaces a cycle in the hierarchy need not cause
2989: * a loop. Still, that's the way it's specified.
2990: *
2991: * THIS IS A RECURSIVE ALGORITHM FOR DEPTH-FIRST SEARCH. This fact does not
2992: * really worry me in the slightest, because the depth of the recursion here
2993: * is no worse than the possible recursive depth of the multiplexor put ()
2994: * calls themselves.
2995: */
2996:
2997: #if __USE_PROTO__
2998: __LOCAL__ int (DETECT_LOOP) (shead_t * upper, shead_t * lower)
2999: #else
3000: __LOCAL__ int
3001: DETECT_LOOP __ARGS ((upper, lower))
3002: shead_t * upper;
3003: shead_t * lower;
3004: #endif
3005: {
3006: shead_t * scan;
3007:
3008: /*
3009: * We base our comparisons on the "sh_tab" member of the stream head
3010: * structure, since that is equivalent to the major part of the
3011: * (internal) device number.
3012: */
3013:
3014: if (upper->sh_tab == lower->sh_tab)
3015: return 1;
3016:
3017: /*
3018: * Now recursively work upward through the multiplexing configuration
3019: * calling DETECT_LOOP () for all the linked streams with the "sh_tab"
3020: * entry of the stream which "upper" is linked to (if "upper" is in
3021: * fact linked below another multiplexor).
3022: *
3023: * Since only device streams can be multiplexors, we only scan the
3024: * device stream list.
3025: */
3026:
3027: if ((upper = upper->sh_linked) == NULL)
3028: return 0;
3029:
3030: for (scan = str_mem->sm_streams [DEV_SLIST] ; scan != NULL ;
3031: scan = scan->sh_next) {
3032:
3033: if (scan->sh_tab == upper->sh_tab &&
3034: DETECT_LOOP (scan, lower))
3035: return 1;
3036: }
3037:
3038: return 0;
3039: }
3040:
3041:
3042: /*
3043: * This function deals with linking one stream below another. There are
3044: * numerous conditions which might prevent this from happening, including a
3045: * refusal from the multiplexing driver.
3046: *
3047: * The upper stream must be locked for open/close operations. The lower stream
3048: * will also be locked by this routine.
3049: */
3050:
3051: #if __USE_PROTO__
3052: int (SHEAD_LINK) (shead_t * upper, int mode, shead_t * lower, int cmd,
3053: cred_t * credp)
3054: #else
3055: int
3056: SHEAD_LINK __ARGS ((upper, mode, lower, cmd, credp))
3057: shead_t * upper;
3058: int mode;
3059: shead_t * lower;
3060: int cmd;
3061: cred_t * credp;
3062: #endif
3063: {
3064: int retval;
3065: muxid_t muxid;
3066:
3067: ASSERT (lower != NULL);
3068:
3069: ASSERT_SLEEP_LOCKED (upper, SH_OPENCLOSE | SH_IOCTL_LOCK);
3070:
3071: if (SHEAD_IS_PIPE (upper) ||
3072: upper->sh_tab->st_muxrinit == NULL ||
3073: upper->sh_tab->st_muxwinit == NULL)
3074: return EINVAL;
3075:
3076: /*
3077: * Perform some of the non-recursive setup (mainly locking) for the
3078: * cycle-detection algorithm. We use the read/write lock on the stream
3079: * head since the detection algorithm walks over the global stream
3080: * list many times. Note that this single-threads checking operations,
3081: * which we would also have to do if were were pushing marker bits
3082: * around in a non-recursive implementation.
3083: */
3084:
3085: (void) RW_WRLOCK (str_mem->sm_head_lock, plstr);
3086:
3087: retval = DETECT_LOOP (upper, lower);
3088:
3089: RW_UNLOCK (str_mem->sm_head_lock, plbase);
3090:
3091: if (retval != 0)
3092: return EINVAL;
3093:
3094: /*
3095: * Generate a suitable multiplexor ID for the link. We use the device
3096: * number of the lower stream as a suitable seed point.
3097: */
3098:
3099: for (muxid = (muxid_t) lower->sh_dev ;
3100: SHEAD_FIND_MUXID (upper, cmd, muxid) != NULL ; muxid ++)
3101: ; /* DO NOTHING */
3102:
3103: /*
3104: * We set up the lower now, before we send the I_LINK, so that by the
3105: * time the driver sees the I_LINK the stream is ready for use. We
3106: * NULL out the "q_ptr" member of the lower queue so that messages
3107: * arriving early can be correctly handled.
3108: *
3109: * We take a sleep lock on the lower stream. If we can't lock it,
3110: * return EINVAL since whatever error caused the failure isn't really
3111: * relevant to the stream the caller is dealing with.
3112: */
3113:
3114: if ((retval = SHEAD_SLEEP_LOCK (lower, SH_OPENCLOSE | SH_IOCTL_LOCK,
3115: 0, DONT_SIGNAL)) != 0)
3116: return EINVAL;
3117:
3118: /*
3119: * Note that the "q_ptr" field of the queue gets zeroed to avoid
3120: * communicating our state to the driver. In addition, we have to
3121: * count the link as an extra open now.
3122: *
3123: * Paranoia time; we check for errors, hangups and whether the lower
3124: * stream is linked at this late stage so the cutover is atomic. This
3125: * requires some cooperation from the stream head read side service
3126: * routine; look to see that it tests for "sh_linked" in the service
3127: * routine somewhere...
3128: */
3129:
3130: (void) SHEAD_LOCK (lower);
3131:
3132: if (SHEAD_HANGUP (lower) || _shead_error (lower, FREAD | FWRITE)) {
3133:
3134: SHEAD_UNLOCK (lower, plbase);
3135: SHEAD_SLEEP_UNLOCK (lower, SH_OPENCLOSE | SH_IOCTL_LOCK);
3136: return EINVAL;
3137: }
3138:
3139: lower->sh_open_count ++; /* duplicate reference */
3140:
3141: lower->sh_linked = upper;
3142: lower->sh_muxid = muxid;
3143:
3144: if (cmd == I_PLINK)
3145: lower->sh_flags |= SH_PLINK;
3146:
3147: SHEAD_UNLOCK (lower, plbase);
3148:
3149:
3150: (void) QFREEZE_TRACE (lower->sh_head, "LINK_STREAMS");
3151:
3152: lower->sh_head->q_ptr = NULL;
3153: W (lower->sh_head)->q_ptr = NULL;
3154:
3155: QUEUE_INIT (lower->sh_head, lower->sh_tab, QI_MUX);
3156:
3157: QUNFREEZE_TRACE (lower->sh_head, plbase);
3158:
3159:
3160: /*
3161: * Send the message downstream and get the return result.
3162: */
3163:
3164: if (LINK_MESSAGE (upper, mode, lower, cmd, muxid, credp,
3165: & retval) == 0) {
3166: int final;
3167:
3168: /*
3169: * The driver failed the link; restore the lower stream. This
3170: * won't cause the stream to close (because of our open
3171: * reference) but we take care to ensure that the counts are
3172: * properly maintained.
3173: */
3174:
3175: final = SHEAD_INIT_UNLINKED (lower);
3176:
3177: if (final != 0)
3178: cmn_err (CE_WARN, "Final close in SHEAD_LINK () ????");
3179: }
3180:
3181:
3182: /*
3183: * Unlock the lower stream for proper symmetry.
3184: */
3185:
3186: SHEAD_SLEEP_UNLOCK (lower, SH_OPENCLOSE | SH_IOCTL_LOCK);
3187: return retval;
3188: }
3189:
3190:
3191: /*
3192: * This function deals with a special case in SHEAD_DO_CLOSE () below where
3193: * the last close of a stream pipe end causes the other end to be detached
3194: * from all the filesystem entries it has been mounted over.
3195: */
3196:
3197: #if __USE_PROTO__
3198: __LOCAL__ void (SHEAD_PIPE_DETACH) (shead_t * __NOTUSED (other))
3199: #else
3200: __LOCAL__ void
3201: SHEAD_PIPE_DETACH __ARGS ((other))
3202: shead_t * other;
3203: #endif
3204: {
3205: /*
3206: * Until we know how attachments are going to be performed and what
3207: * kind of structure exists, we cannot implement this function.
3208: */
3209:
3210: cmn_err (CE_PANIC, "UNIMPLEMENTED : SHEAD_PIPE_DETACH ()");
3211: }
3212:
3213:
3214: /*
3215: * This module factors out some code from SHEAD_DO_CLOSE (). The final
3216: * close processing for a stream head is complicated a little because when a
3217: * stream pipe end is closed that side of the pipe is not actually closed
3218: * until the other end also closes.
3219: */
3220:
3221: #if __USE_PROTO__
3222: __LOCAL__ void (SHEAD_FINAL_CLOSE) (shead_t * sheadp, int mode,
3223: cred_t * credp)
3224: #else
3225: __LOCAL__ void
3226: SHEAD_FINAL_CLOSE __ARGS ((sheadp, mode, credp))
3227: shead_t * sheadp;
3228: int mode;
3229: cred_t * credp;
3230: #endif
3231: {
3232: shead_t * scan;
3233: queue_t * q;
3234: int retval;
3235:
3236: /*
3237: * Final close of a stream; the close steps are to be performed in
3238: * this order, as given in the DDI/DDK entry for close(D2DK).
3239: * Non-persistent multiplexor links are unlinked.
3240: * For each module and driver from the head to the driver:
3241: * Wait for the write queue to drain.
3242: * Call close () routine.
3243: * Remove module/driver from stream.
3244: * Free remaining messages.
3245: * Deallocate queue pair.
3246: *
3247: * Here we can behave as if we have an ioctl () lock on the stream
3248: * because during final close no other process can legitimately hold
3249: * another lock on the stream head (no other legal references to the
3250: * stream exist).
3251: */
3252:
3253: while ((scan = SHEAD_FIND_MUXID (sheadp, I_UNLINK, -1)) != NULL) {
3254:
3255: if (SHEAD_UNLINK (sheadp, scan, I_UNLINK, mode, credp,
3256: & retval) == 0) {
3257: /*
3258: * There is no good reason for a driver to fail an
3259: * I_UNLINK request.
3260: */
3261:
3262: cmn_err (CE_WARN, "Driver failed unlink () during final close (%d)",
3263: retval);
3264: scan->sh_linked = NULL;
3265: }
3266: }
3267:
3268:
3269: /*
3270: * Before draining the write side modules, drain the stream head.
3271: */
3272:
3273: DRAIN_QUEUE (sheadp, W (sheadp->sh_head));
3274:
3275:
3276: /*
3277: * Now pop all the modules from the stream.
3278: */
3279:
3280: while ((q = TOP_MODULE (sheadp)) != NULL) {
3281:
3282: DRAIN_QUEUE (sheadp, W (q));
3283:
3284: (void) POP_MODULE (sheadp, q, mode, credp);
3285: }
3286:
3287:
3288: /*
3289: * Now close the driver, unless this is a pipe. Once this has been
3290: * done there is no reason for any context to reference this object
3291: * except to unlock it.
3292: */
3293:
3294: if (! SHEAD_IS_PIPE (sheadp)) {
3295: q = TOP_QUEUE (sheadp);
3296:
3297: DRAIN_QUEUE (sheadp, q);
3298:
3299: q = R (q);
3300:
3301: retval = (* q->q_qinfo->qi_qclose) (q, mode, credp);
3302:
3303: if (retval != 0)
3304: cmn_err (CE_WARN, "Driver close returned %d", retval);
3305:
3306: if ((q->q_flag & QPROCSOFF) == 0) {
3307:
3308: cmn_err (CE_WARN, "Driver %s did not call qprocsoff ()",
3309: q->q_qinfo->qi_minfo->mi_idname);
3310: qprocsoff (q);
3311: }
3312: }
3313: }
3314:
3315:
3316: /*
3317: * This function does most of the close processing for a stream head. It is
3318: * used by regular stream close, and by stream open code if certain
3319: * irregularities are detected.
3320: *
3321: * The caller must have the stream head locked for close operations. If the
3322: * stream head being operated on is a pipe, that means both ends must be
3323: * locked (so that the caller can sequence the lock order on the basis of the
3324: * master/slave bits).
3325: */
3326:
3327: #if __USE_PROTO__
3328: __LOCAL__ int (SHEAD_DO_CLOSE) (shead_t * sheadp, int mode, cred_t * credp)
3329: #else
3330: __LOCAL__ int
3331: SHEAD_DO_CLOSE __ARGS ((sheadp, mode, credp))
3332: shead_t * sheadp;
3333: int mode;
3334: cred_t * credp;
3335: #endif
3336: {
3337: ASSERT (credp != NULL);
3338: ASSERT_SLEEP_LOCKED (sheadp, SH_OPENCLOSE | SH_IOCTL_LOCK);
3339:
3340: /*
3341: * If other processes have references to this stream head, then we can
3342: * just return doing no more work. Note that we keep the notion of
3343: * number of open references, number of filesystem attachments, and
3344: * multiplexor links completely separate, but any one qualifies as
3345: * a reason for keeping the stream around.
3346: *
3347: * Therefore, it follows that any code which manipulates any of these
3348: * quantities such that the next expression might become false needs
3349: * to call this function to ensure that the stream memory will be
3350: * properly reclaimed.
3351: */
3352:
3353: ASSERT (sheadp->sh_open_count == 0);
3354:
3355: if (SHEAD_IS_PIPE (sheadp)) {
3356: shead_t * other = SHEAD_OTHER (sheadp);
3357:
3358: /*
3359: * If this is a pipe, there are some extra things we should
3360: * worry about. First, the first end of a stream pipe to close
3361: * should send an M_HANGUP message to the other end rather
3362: * than actually closing. The other end then gets to destroy
3363: * both sides of the pipe when it finally closes.
3364: *
3365: * The second exception is that when an unattached end of a
3366: * streams pipe is closed, the other end is automatically
3367: * detached.
3368: *
3369: * Note that if the other end of the pipe is linked below a
3370: * multiplexor, we do not attempt to automatically unlink it.
3371: * This might seem entirely reasonable, but we cannot attempt
3372: * this without introducing a possibility of deadlock.
3373: */
3374:
3375: if (other->sh_attach_count > 0)
3376: SHEAD_PIPE_DETACH (other);
3377:
3378: if (other->sh_open_count > 0) {
3379: /*
3380: * The last close/detach/unlink of the other end will
3381: * clean everything up.
3382: */
3383:
3384: putctl (W (other->sh_head), M_HANGUP);
3385: return 0;
3386: }
3387:
3388: /*
3389: * Now we clean up the "other" end.
3390: */
3391:
3392: SHEAD_FINAL_CLOSE (other, mode, credp);
3393: }
3394:
3395: SHEAD_FINAL_CLOSE (sheadp, mode, credp);
3396:
3397: /*
3398: * We leave the last part of the cleanup (dallocating the queue pair
3399: * and any remaining messages) to the unlock call which the caller
3400: * will perform.
3401: */
3402:
3403: return 0;
3404: }
3405:
3406:
3407: /*
3408: * This function builds and send an M_FLUSH message down the stream.
3409: */
3410:
3411: #if __USE_PROTO__
3412: __LOCAL__ int (SHEAD_FLUSH) (shead_t * sheadp, int flag, uchar_t band)
3413: #else
3414: __LOCAL__ int
3415: SHEAD_FLUSH __ARGS ((sheadp, flag, band))
3416: shead_t * sheadp;
3417: int flag;
3418: uchar_t band;
3419: #endif
3420: {
3421: mblk_t * msg;
3422:
3423: if ((flag & FLUSHRW) == 0 || (flag & ~ FLUSHRW) != 0)
3424: return EINVAL;
3425: else if ((msg = MSGB_ALLOC (2, BPRI_LO, KM_SLEEP)) == NULL)
3426: return ENOSR;
3427: else {
3428: /*
3429: * Send the message downstream...
3430: */
3431:
3432: if (band > 0)
3433: flag |= FLUSHBAND;
3434:
3435: msg->b_datap->db_type = M_FLUSH;
3436: * msg->b_wptr ++ = (unsigned char) flag;
3437:
3438: if (band > 0)
3439: * msg->b_wptr ++ = band;
3440:
3441: put (W (sheadp->sh_head), msg);
3442: }
3443:
3444: return 0;
3445: }
3446:
3447:
3448: /*
3449: * This function locates a module's streamtab entry given the name. Only the
3450: * first FMNAMESZ characters are considered significant.
3451: */
3452:
3453: #if __USE_PROTO__
3454: modsw_t * (FIND_MODULE) (__CONST__ char * modname)
3455: #else
3456: modsw_t *
3457: FIND_MODULE __ARGS ((modname))
3458: __CONST__ char * modname;
3459: #endif
3460: {
3461: modsw_t * scan;
3462: modsw_t * end;
3463:
3464: for (scan = modsw, end = scan + nmodsw ; scan != end ; scan ++) {
3465: __CONST__ char * name;
3466:
3467: name = scan->mod_stream->st_rdinit->qi_minfo->mi_idname;
3468:
3469: if (name != NULL && strncmp (modname, name, FMNAMESZ) == 0)
3470: return scan;
3471: }
3472:
3473: return NULL;
3474: }
3475:
3476:
3477: /*
3478: * This function holds code to process an I_STR ioctl ().
3479: */
3480:
3481: #if __USE_PROTO__
3482: __LOCAL__ int (ISTR_IOCTL) (shead_t * sheadp, int mode,
3483: struct strioctl * strioc, cred_t * credp,
3484: int * rvalp)
3485: #else
3486: __LOCAL__ int
3487: ISTR_IOCTL __ARGS ((sheadp, mode, strioc, credp, rvalp))
3488: shead_t * sheadp;
3489: int mode;
3490: struct strioctl
3491: * strioc;
3492: cred_t * credp;
3493: int * rvalp;
3494: #endif
3495: {
3496: __clock_t ticks;
3497: mblk_t * msg;
3498: mblk_t * data;
3499: struct iocblk * ioc;
3500: int retval;
3501:
3502: ASSERT_SLEEP_LOCKED (sheadp, SH_IOCTL_LOCK);
3503:
3504: /*
3505: * Set up timeout; "ic_timeout" == -1 means infinite
3506: * timeout, while "ic_timeout" == 0 means default
3507: * (which is infinite).
3508: */
3509:
3510: if (strioc->ic_timeout != -1 && strioc->ic_timeout != 0) {
3511: /*
3512: * We take care to deal with overflow here.
3513: */
3514:
3515: if ((ticks = strioc->ic_timeout) > (__clock_t) -1 / 1000000L)
3516: ticks = (__clock_t) -1;
3517:
3518: ticks = drv_usectohz (ticks * 1000000L);
3519: } else
3520: ticks = 0;
3521:
3522: if ((msg = MSGB_ALLOC (sizeof (* ioc), BPRI_LO, KM_SLEEP)) == NULL)
3523: return ENOSR;
3524:
3525: ioc = (struct iocblk *) msg->b_rptr;
3526: msg->b_wptr = (unsigned char *) (ioc + 1);
3527:
3528: msg->b_datap->db_type = M_IOCTL;
3529:
3530: ioc->ioc_cmd = strioc->ic_cmd;
3531: ioc->ioc_cr = credp;
3532: ioc->ioc_id = ++ sheadp->sh_ioc_seq;
3533: ioc->ioc_count = strioc->ic_len;
3534: ioc->ioc_rval = ioc->ioc_error = 0;
3535:
3536:
3537: /*
3538: * If there is data to be sent downstream, we allocate a buffer to
3539: * hold it and copy the data into that buffer.
3540: */
3541:
3542: if (ioc->ioc_count > 0) {
3543:
3544: if ((data = MSGB_ALLOC (strioc->ic_len, BPRI_LO,
3545: KM_SLEEP)) == NULL) {
3546:
3547: retval = ENOSR;
3548: goto done;
3549: }
3550:
3551: msg->b_cont = data;
3552: data->b_wptr += strioc->ic_len;
3553:
3554: if (copyin (strioc->ic_dp, data->b_rptr,
3555: strioc->ic_len) != 0) {
3556:
3557: retval = EFAULT;
3558: goto done;
3559: }
3560: }
3561:
3562: /*
3563: * Now we send the ioctl () and wait for the acknowledgement.
3564: */
3565:
3566: if ((msg = IOCTL_SEND (sheadp, mode, msg, & retval, ticks)) == NULL)
3567: return retval;
3568:
3569:
3570: /*
3571: * What do we do with the results? We copy at most "ioc_count" bytes
3572: * of data back into the user's address space if this is M_IOCACK.
3573: */
3574:
3575: ioc = (struct iocblk *) msg->b_rptr;
3576:
3577: switch (msg->b_datap->db_type) {
3578:
3579: case M_IOCNAK:
3580: retval = ioc->ioc_error;
3581: break;
3582:
3583: case M_IOCACK:
3584: * rvalp = ioc->ioc_rval;
3585: retval = ioc->ioc_error;
3586:
3587: data = msg->b_cont;
3588:
3589: while (ioc->ioc_count > 0) {
3590: size_t len;
3591:
3592: if (data == NULL) {
3593:
3594: cmn_err (CE_WARN, "ISTR_IOCTL : Insufficient M_DATA blocks for ioc_count");
3595: break;
3596: }
3597:
3598: len = data->b_wptr - data->b_rptr;
3599:
3600: if (len > ioc->ioc_count)
3601: len = ioc->ioc_count;
3602:
3603: if (len > 0 &&
3604: copyout (data->b_rptr, strioc->ic_dp,
3605: len) != 0) {
3606:
3607: retval = EFAULT;
3608: goto done;
3609: }
3610:
3611: ioc->ioc_count -= len;
3612: data = data->b_cont;
3613: strioc->ic_dp += len;
3614: }
3615: break;
3616:
3617: default:
3618: cmn_err (CE_WARN, "Invalid message type %d received during unlink processing",
3619: msg->b_datap->db_type);
3620: retval = ENXIO;
3621: break;
3622: }
3623:
3624: done:
3625: freemsg (msg);
3626:
3627: return retval;
3628: }
3629:
3630:
3631: /*
3632: * Here are the details of the implementation of sigpoll_t.
3633: */
3634:
3635: struct sigpoll {
3636: sigpoll_t * sp_next; /* single-threaded */
3637: _VOID * sp_proc; /* from proc_ref () */
3638: short sp_events; /* events to signal per <stropts.h> */
3639: };
3640:
3641:
3642: /*
3643: * This function is used when an M_SIG or M_PCSIG message is processed at the
3644: * stream head.
3645: */
3646:
3647: #if __USE_PROTO__
3648: void (SHEAD_SIGNAL) (shead_t * sheadp, uchar_t signal)
3649: #else
3650: void
3651: SHEAD_SIGNAL __ARGS ((sheadp, signal))
3652: shead_t * sheadp;
3653: uchar_t signal;
3654: #endif
3655: {
3656: pl_t prev_pl;
3657:
3658: prev_pl = SHEAD_LOCK (sheadp);
3659:
3660: if (signal == SIGPOLL) {
3661: sigpoll_t * sigs;
3662:
3663: /*
3664: * SIGPOLL is only sent to those processes that have
3665: * registered to receive it with I_SETSIG.
3666: */
3667:
3668:
3669: for (sigs = sheadp->sh_sigs ; sigs != NULL ;
3670: sigs = sigs->sp_next) {
3671:
3672: if ((sigs->sp_events & S_MSG) != 0)
3673: proc_signal (sigs->sp_proc, signal);
3674: }
3675: } else {
3676: /*
3677: * Send a signal to the controlling process group for this
3678: * stream; if this stream is not a controlling tty, then no
3679: * signal is sent.
3680: */
3681:
3682: if (sheadp->sh_pgrp != 0)
3683: proc_kill_group (sheadp->sh_pgrp, signal);
3684: }
3685:
3686: SHEAD_UNLOCK (sheadp, prev_pl);
3687: }
3688:
3689:
3690: /*
3691: * This function encapsulates all user-level access to the front of the stream
3692: * head message queue. It deals with ensuring that the STREAMS scheduling
3693: * policy works (by managing QWANTR) and some other details such as dealing
3694: * with in-band processing of M_SIG messages.
3695: *
3696: * The stream head read queue should be frozen by the caller.
3697: */
3698:
3699: #if __USE_PROTO__
3700: __LOCAL__ mblk_t * (SHEAD_FIRSTMSG) (shead_t * sheadp)
3701: #else
3702: __LOCAL__ mblk_t *
3703: SHEAD_FIRSTMSG __ARGS ((sheadp))
3704: shead_t * sheadp;
3705: #endif
3706: {
3707: mblk_t * msg;
3708:
3709: QFROZEN_TRACE (sheadp->sh_head, "SHEAD_FIRSTMSG");
3710:
3711: while ((msg = sheadp->sh_head->q_first) != NULL) {
3712:
3713: if (msg->b_datap->db_type != M_SIG)
3714: return msg;
3715:
3716: rmvq (sheadp->sh_head, msg);
3717: SHEAD_SIGNAL (sheadp, * msg->b_rptr);
3718: freemsg (msg);
3719: }
3720:
3721: sheadp->sh_head->q_flag |= QWANTR;
3722:
3723: return NULL;
3724: }
3725:
3726:
3727: /*
3728: * This function does the necessary work to implement POLLWRBAND, which tests
3729: * to see if any of the previously written-to bands of flow in the next
3730: * downstream queue with a service procedure are not flow controlled.
3731: */
3732:
3733: #if __USE_PROTO__
3734: __LOCAL__ int (POLL_WRBAND) (queue_t * q)
3735: #else
3736: __LOCAL__ int
3737: POLL_WRBAND __ARGS ((q))
3738: queue_t * q;
3739: #endif
3740: {
3741: pl_t prev_pl;
3742: qband_t * qbandp;
3743:
3744: prev_pl = QFREEZE_TRACE (q, "POLL_WRBAND");
3745:
3746: do {
3747: q = QUEUE_NEXT (q);
3748:
3749: if (q == NULL)
3750: return 1;
3751:
3752: } while (q->q_qinfo->qi_srvp == NULL);
3753:
3754:
3755: /*
3756: * We have found a queue with a service procedure, and have it frozen.
3757: * If there are no bands, then we can write a band...
3758: */
3759:
3760: if (q->q_nband == 0) {
3761:
3762: QUNFREEZE_TRACE (q, prev_pl);
3763: return 1;
3764: }
3765:
3766: qbandp = QUEUE_BAND (q, q->q_nband);
3767:
3768: ASSERT (qbandp != NULL);
3769:
3770: /*
3771: * Since if a band is blocked implies lower bands are blocked, we can
3772: * simply test the highest-numbered band.
3773: */
3774:
3775: if ((qbandp->qb_flag & QB_FULL) != 0) {
3776:
3777: QUNFREEZE_TRACE (q, prev_pl);
3778: return 1;
3779: }
3780:
3781:
3782: /*
3783: * If all are full, request notification via back-enabling when the
3784: * highest band becomes writeable.
3785: */
3786:
3787: qbandp->qb_flag |= QB_WANTW;
3788:
3789: QUNFREEZE_TRACE (q, prev_pl);
3790: return 0;
3791: }
3792:
3793:
3794: /*
3795: * This function has responsibility for checking to see whether the event mask
3796: * for this SIGPOLL request is immediately satisfied.
3797: */
3798:
3799: #if __USE_PROTO__
3800: __LOCAL__ short (SHEAD_POLL_CHECK) (shead_t * sheadp, short events)
3801: #else
3802: __LOCAL__ short
3803: SHEAD_POLL_CHECK __ARGS ((sheadp, events))
3804: shead_t * sheadp;
3805: short events;
3806: #endif
3807: {
3808: short revents = 0;
3809: pl_t prev_pl;
3810: mblk_t * msg;
3811:
3812:
3813: /*
3814: * Check the conditions that do not depend on the status of the first
3815: * queued message (if any).
3816: *
3817: * For S_OUTPUT, using canputnext () is important because it sets the
3818: * back-enable flag so that we will be properly notified when the
3819: * condition becomes true.
3820: *
3821: * For S_WRBAND, things are a little more complex; this tests whether
3822: * *any* downstream priority band is writeable, which involves walking
3823: * over all the 'qband' structures allocated to the next stream with
3824: * a service procedure.
3825: */
3826:
3827: if ((events & __POLL_OUTPUT) != 0 && canputnext (W (sheadp->sh_head)))
3828: revents |= __POLL_OUTPUT;
3829:
3830: if ((events & __POLL_WRBAND) != 0 &&
3831: POLL_WRBAND (W (sheadp->sh_head)))
3832: revents |= __POLL_WRBAND;
3833:
3834:
3835: prev_pl = SHEAD_LOCK (sheadp);
3836:
3837: if ((events & S_ERROR) != 0 &&
3838: (sheadp->sh_rerrcode != 0 || sheadp->sh_werrcode != 0))
3839: revents |= POLLERR;
3840:
3841: if ((events & S_HANGUP) != 0 && (sheadp->sh_flags & SH_HANGUP) != 0)
3842: revents = (revents | POLLHUP) &
3843: ~ (__POLL_OUTPUT | __POLL_WRBAND);
3844:
3845: SHEAD_UNLOCK (sheadp, prev_pl);
3846:
3847:
3848: prev_pl = QFREEZE_TRACE (sheadp->sh_head, "SHEAD_POLL_CHECK");
3849:
3850: if ((msg = SHEAD_FIRSTMSG (sheadp)) != NULL &&
3851: datamsg (msg->b_datap->db_type)) {
3852:
3853: if (! pcmsg (msg->b_datap->db_type)) {
3854:
3855: if ((events & __POLL_INPUT) != 0)
3856: revents |= __POLL_INPUT;
3857:
3858: if ((events & __POLL_RDNORM) != 0 && msg->b_band == 0)
3859: revents |= __POLL_RDNORM;
3860:
3861: if ((events & __POLL_RDBAND) != 0 && msg->b_band > 0)
3862: revents |= __POLL_RDBAND;
3863: } else if ((events & __POLL_HIPRI) != 0)
3864: revents |= __POLL_HIPRI;
3865: }
3866:
3867: QUNFREEZE_TRACE (sheadp->sh_head, prev_pl);
3868:
3869: return revents;
3870: }
3871:
3872:
3873: /*
3874: * This function attempts to locate any sigpoll record for the current
3875: * process. The stream head needs to be locked out against modification of
3876: * the signal list, which means an IOCTL lock is sufficient.
3877: */
3878:
3879: #if __USE_PROTO__
3880: __LOCAL__ sigpoll_t * (FIND_SIGPOLL) (shead_t * sheadp)
3881: #else
3882: __LOCAL__ sigpoll_t *
3883: FIND_SIGPOLL __ARGS ((sheadp))
3884: shead_t * sheadp;
3885: #endif
3886: {
3887: _VOID * proc;
3888: sigpoll_t * scan;
3889:
3890: ASSERT_SLEEP_LOCKED (sheadp, SH_IOCTL_LOCK);
3891:
3892: /*
3893: * See if the process is already registered (so that we can modify or
3894: * free an existing record).
3895: */
3896:
3897: proc = proc_ref ();
3898:
3899: for (scan = sheadp->sh_sigs ; scan != NULL ; scan ++)
3900: if (scan->sp_proc == proc)
3901: break;
3902:
3903: proc_unref (proc);
3904:
3905: return scan;
3906: }
3907:
3908:
3909: /*
3910: * This function deals with (de)registering a process for SIGPOLL. The caller
3911: * should have an IOCTL lock on the stream head so that there are no other
3912: * contexts which could modify the list of registered signals.
3913: */
3914:
3915: #if __USE_PROTO__
3916: __LOCAL__ int (REGISTER_SIGPOLL) (shead_t * sheadp, short events)
3917: #else
3918: __LOCAL__ int
3919: REGISTER_SIGPOLL __ARGS ((sheadp, events))
3920: shead_t * sheadp;
3921: short events;
3922: #endif
3923: {
3924: _VOID * proc;
3925: sigpoll_t * scan;
3926: sigpoll_t * prev;
3927:
3928: ASSERT_SLEEP_LOCKED (sheadp, SH_IOCTL_LOCK);
3929:
3930: /*
3931: * See if the process is already registered (so that we can modify or
3932: * free an existing record). We don't use the FIND_SIGPOLL () routine
3933: * because we want to locate the previous record also.
3934: */
3935:
3936: proc = proc_ref ();
3937:
3938: for (prev = NULL, scan = sheadp->sh_sigs ; scan != NULL ;
3939: prev = scan, scan ++) {
3940:
3941: if (scan->sp_proc == proc) {
3942: /*
3943: * We have found a preexisting record... now modify
3944: * or free it.
3945: */
3946:
3947: proc_unref (proc);
3948:
3949: (void) SHEAD_LOCK (sheadp);
3950:
3951: if ((scan->sp_events = events) == 0) {
3952: /*
3953: * Free the cell after unlinking it from the
3954: * list of registered processes. We take out
3955: * a lock on the stream head to protect
3956: * against streams-level contexts walking the
3957: * list.
3958: */
3959:
3960: if (prev == NULL)
3961: sheadp->sh_sigs = scan->sp_next;
3962: else
3963: prev->sp_next = scan->sp_next;
3964:
3965: SHEAD_UNLOCK (sheadp, plbase);
3966:
3967: /*
3968: * We unlock the stream head before calling
3969: * the heap manager as a matter of courtesy.
3970: */
3971:
3972: kmem_free (scan, sizeof (* scan));
3973: proc_unref (proc);
3974: return 0;
3975: }
3976:
3977: SHEAD_UNLOCK (sheadp, plbase);
3978: goto sigcheck;
3979: }
3980: }
3981:
3982:
3983: if (events == 0) {
3984: /*
3985: * Not found, nothing to do. That is an error according to the
3986: * streamio (7) man pages.
3987: */
3988:
3989: return EINVAL;
3990: }
3991:
3992:
3993: /*
3994: * We need to make a new event.
3995: */
3996:
3997: if ((scan = (sigpoll_t *) kmem_alloc (sizeof (* scan),
3998: KM_SLEEP)) == NULL) {
3999:
4000: proc_unref (proc);
4001: return EAGAIN;
4002: }
4003:
4004: scan->sp_proc = proc;
4005: scan->sp_events = events;
4006: scan->sp_next = sheadp->sh_sigs;
4007:
4008: /*
4009: * Since we are the only process context modifying the list, we only
4010: * need to lock the last stage of the insert against interrupt-level
4011: * contexts walking the list.
4012: */
4013:
4014: (void) SHEAD_LOCK (sheadp);
4015:
4016: sheadp->sh_sigs = scan;
4017:
4018: SHEAD_UNLOCK (sheadp, plbase);
4019:
4020: sigcheck:
4021: if ((events = SHEAD_POLL_CHECK (sheadp, scan->sp_events)) != 0) {
4022: /*
4023: * We have a winner! Check for the SIGURG special case, and
4024: * otherwise/also send SIGPOLL via proc_signal ().
4025: */
4026:
4027: if ((events & __POLL_RDBAND) != 0 &&
4028: (scan->sp_events & S_BANDURG) != 0) {
4029:
4030: proc_signal (scan->sp_proc, SIGURG);
4031: events &= ~ __POLL_RDBAND;
4032: }
4033:
4034: if (events != 0)
4035: proc_signal (scan->sp_proc, SIGPOLL);
4036: }
4037:
4038: return 0;
4039: }
4040:
4041:
4042: /*
4043: * This function maps a file descriptor into a stream head by calling upon the
4044: * abstract file-description functions declared in <sys/fhsys.h>. The caller
4045: * must lock the stream somehow.
4046: */
4047:
4048: #if ! _NO_INSTALLABLE_FILESYSTEMS
4049:
4050: extern fprocs_t streams_fsys;
4051:
4052: #endif
4053:
4054:
4055: #if __USE_PROTO__
4056: __LOCAL__ shead_t * (FH_TO_STREAM) (int fd, int * retvalp)
4057: #else
4058: __LOCAL__ shead_t *
4059: FH_TO_STREAM __ARGS ((fd, retvalp))
4060: int fd;
4061: int * retvalp;
4062: #endif
4063: {
4064: fhandle_t * handle;
4065: scookie_t * cookie;
4066:
4067: ASSERT (retvalp != NULL);
4068:
4069: if ((handle = fd_get_handle (fd)) == NULL) {
4070:
4071: * retvalp = EBADF;
4072: return NULL;
4073: #if ! _NO_INSTALLABLE_FILESYSTEMS
4074: } else if (fh_procs (handle) == & streams_fsys) {
4075:
4076: * retvalp = EINVAL;
4077: return NULL;
4078: #endif
4079: }
4080:
4081: cookie = (scookie_t *) fh_get_cookie (handle);
4082:
4083: ASSERT (cookie != NULL);
4084:
4085: if (cookie->sheadp == NULL)
4086: cmn_err (CE_WARN, "Bad cookie in streams");
4087:
4088: return cookie->sheadp;
4089: }
4090:
4091:
4092: /*
4093: * The following structure is used by the routines below to deal with the
4094: * M_PASSFP message type. The structure of the data contained in that message
4095: * is completely opaque to STREAMS routines, so we keep the definition local.
4096: */
4097:
4098: struct passfp {
4099: sftab_t * sftab; /* system file table entry address */
4100: n_uid_t uid;
4101: n_gid_t gid;
4102: };
4103:
4104:
4105: /*
4106: * This function attempts to retrieve a file descriptor sent by an I_SENDFD
4107: * ioctl () and create a local file descriptor referring to the same file.
4108: */
4109:
4110: #if __USE_PROTO__
4111: __LOCAL__ int (FH_RECV) (shead_t * sheadp, int mode, struct strrecvfd * recvp)
4112: #else
4113: __LOCAL__ int
4114: FH_RECV __ARGS ((sheadp, mode, recvp))
4115: shead_t * sheadp;
4116: int mode;
4117: struct strrecvfd
4118: * recvp;
4119: #endif
4120: {
4121: mblk_t * msg;
4122: struct passfp * fp;
4123: int retval;
4124:
4125: ASSERT (sheadp != NULL);
4126: ASSERT (recvp != NULL);
4127:
4128: if (! SHEAD_IS_PIPE (sheadp))
4129: return EINVAL;
4130:
4131: if ((mode & FREAD) == 0)
4132: return EBADF;
4133:
4134: mode &= ~ FWRITE;
4135:
4136:
4137: /*
4138: * Look at the stream head to see if a message is present.
4139: */
4140:
4141: for (;;) {
4142: int retval;
4143:
4144: (void) QFREEZE_TRACE (sheadp->sh_head, "FH_RECV");
4145:
4146: if ((msg = SHEAD_FIRSTMSG (sheadp)) != NULL)
4147: break;
4148:
4149: /*
4150: * Use the STREAMS flag to indicate that we have found the
4151: * queue empty.
4152: */
4153:
4154: (void) SHEAD_LOCK (sheadp);
4155:
4156: QUNFREEZE_TRACE (sheadp->sh_head, plstr);
4157:
4158: /*
4159: * We need to wait (unless O_NDELAY or O_NONBLOCK has been
4160: * specified), or the stream has been hung up.
4161: */
4162:
4163: if ((retval = SHEAD_WAIT_NONBLOCK (sheadp, mode, SH_READ_WAIT,
4164: CHECK_SIGNALS)) != 0)
4165: return retval;
4166:
4167: /*
4168: * Check again...
4169: */
4170: }
4171:
4172: if (msg->b_datap->db_type != M_PASSFP)
4173: retval = EBADMSG;
4174: else if (! fd_can_add ())
4175: retval = EMFILE;
4176: else {
4177:
4178: retval = 0;
4179: rmvq (sheadp->sh_head, msg);
4180: }
4181:
4182: QUNFREEZE_TRACE (sheadp->sh_head, plbase);
4183:
4184: if (retval != 0)
4185: return retval;
4186:
4187: /*
4188: * After this point, "msg" is our responsibility and we either have to
4189: * free it or put it back if there is an error.
4190: */
4191:
4192: fp = (struct passfp *) msg->b_rptr;
4193:
4194: if ((retval = fd_add_sftab (fp->sftab, & recvp->fd)) == 0 &&
4195: ((recvp->uid = (o_uid_t) fp->uid) != fp->uid ||
4196: (recvp->gid = (o_gid_t) fp->gid) != fp->gid))
4197: retval = EOVERFLOW;
4198:
4199: freemsg (msg);
4200: return retval;
4201: }
4202:
4203:
4204: /*
4205: * This function attempts to send a file descriptor to another process at the
4206: * other end of a stream pipe.
4207: */
4208:
4209: #if __USE_PROTO__
4210: __LOCAL__ int (FH_SEND) (shead_t * sheadp, int fd, cred_t * credp)
4211: #else
4212: __LOCAL__ int
4213: FH_SEND __ARGS ((sheadp, fd, credp))
4214: shead_t * sheadp;
4215: int fd;
4216: cred_t * credp;
4217: #endif
4218: {
4219: mblk_t * msg;
4220: struct passfp * fp;
4221: sftab_t * sftab;
4222: shead_t * other;
4223: int retval;
4224:
4225: ASSERT (sheadp != NULL);
4226: ASSERT (credp != NULL);
4227:
4228: if (! SHEAD_IS_PIPE (sheadp))
4229: return EINVAL;
4230:
4231: /*
4232: * We are passed a file descriptor (a user-level abstract entity);
4233: * here we turn that into a kernel-level abstract entity.
4234: */
4235:
4236: if ((sftab = fd_get_sftab (fd)) == NULL)
4237: return EBADF;
4238:
4239: other = SHEAD_OTHER (sheadp);
4240:
4241: if (! canput (W (other->sh_head)) ||
4242: (msg = MSGB_ALLOC (sizeof (* fp), BPRI_LO, KM_SLEEP)) == NULL)
4243: return EAGAIN;
4244:
4245: /*
4246: * Fill in the new message block and put the message to the other
4247: * side. After this point we have to free the message block if there
4248: * is a problem.
4249: */
4250:
4251: fp = (struct passfp *) msg->b_rptr;
4252: msg->b_wptr = (unsigned char *) (fp + 1);
4253:
4254: msg->b_datap->db_type = M_PASSFP;
4255:
4256: fp->sftab = sftab;
4257: fp->uid = credp->cr_uid;
4258: fp->gid = credp->cr_gid;
4259:
4260: (void) SHEAD_LOCK (sheadp);
4261:
4262: if ((retval = SHEAD_ERRHUP_LOCKED (sheadp, FWRITE)) == 0) {
4263:
4264: putq (W (other->sh_head), msg);
4265:
4266: SHEAD_UNLOCK (sheadp, plbase);
4267: } else
4268: freemsg (msg);
4269:
4270: return retval;
4271: }
4272:
4273:
4274: /*
4275: * This function factors out the details of copying data out from kernel space
4276: * into a "strbuf" stream buffer structure in user space.
4277: *
4278: * The return value of this function is 0 on success or -1 on error.
4279: */
4280:
4281: enum {
4282: CONTROL_PART,
4283: DATA_PART
4284: };
4285:
4286: #if __USE_PROTO__
4287: __LOCAL__ int (COPYOUT_BUF) (struct strbuf * bufp, mblk_t ** mpp, int data)
4288: #else
4289: __LOCAL__ int
4290: COPYOUT_BUF __ARGS ((bufp, mpp, data))
4291: struct strbuf * bufp;
4292: mblk_t ** mpp;
4293: int data;
4294: #endif
4295: {
4296: mblk_t * prev;
4297: mblk_t * scan;
4298: int remaining;
4299: caddr_t outaddr;
4300:
4301: ASSERT (mpp != NULL);
4302:
4303: /*
4304: * The first thing we do is check some special values; if a "strbuf"
4305: * entry is NULL or has its "maxlen" member set to "-1", we do nothing
4306: * with the message.
4307: */
4308:
4309: if (bufp == NULL || bufp->maxlen == -1)
4310: return 0;
4311:
4312: /*
4313: * Next, if this is a data-part copy, skip any intial M_PROTO or
4314: * M_PCPROTO message blocks. There *should* only ever be one of these
4315: * at the front of a message, but we are required to effectively
4316: * coalesce multiple control blocks.
4317: */
4318:
4319: prev = NULL;
4320: scan = * mpp;
4321:
4322: if (data == DATA_PART) {
4323: /*
4324: * Find the data portion of the message, if any.
4325: */
4326:
4327: while (scan != NULL) {
4328:
4329: if (scan->b_datap->db_type == M_DATA)
4330: break;
4331: scan = (prev = scan)->b_cont;
4332: }
4333: } else
4334: if (scan->b_datap->db_type == M_DATA)
4335: scan = NULL;
4336:
4337: /*
4338: * If there is no control (or data, as appropriate) part to the
4339: * message, then we set the "len" member of the "strbuf" to -1.
4340: */
4341:
4342: if (scan == NULL) {
4343:
4344: bufp->len = -1;
4345: return 0;
4346: }
4347:
4348:
4349: /*
4350: * Now be do the actual copy; the form of this loop is organized so
4351: * that zero-length message blocks will be consumed if "maxlen" is
4352: * set to 0. This is important not only to comply with the manual page
4353: * for getmsg ()/getpmsg (), but also ensures that trailing zero-
4354: * length blocks at the end of a message get cleaned up properly.
4355: */
4356:
4357: bufp->len = 0;
4358: remaining = bufp->maxlen;
4359: outaddr = (caddr_t) bufp->buf;
4360:
4361: for (;;) {
4362: size_t copylen = scan->b_wptr - scan->b_rptr;
4363: mblk_t * next;
4364:
4365: if (copylen > remaining)
4366: copylen = remaining;
4367:
4368: if (copylen > 0) {
4369: /*
4370: * Copy the data to the user. Don't forget that
4371: * copyout () is like bcopy () in that the arguments
4372: * are src, dest, len !
4373: */
4374:
4375: if (copyout (scan->b_rptr, outaddr, copylen) != 0)
4376: return EFAULT;
4377:
4378: bufp->len += copylen;
4379: scan->b_rptr += copylen;
4380: remaining -= copylen;
4381: }
4382:
4383: if (scan->b_rptr != scan->b_wptr) {
4384: /*
4385: * Since this message block was not fully consumed, we
4386: * can infer that we have copied all the data we can.
4387: */
4388:
4389: ASSERT (remaining == 0);
4390: break;
4391: }
4392:
4393:
4394: /*
4395: * This message block has been consumed; unlink and free it.
4396: */
4397:
4398: next = scan->b_cont;
4399: if (prev == NULL)
4400: * mpp = next;
4401: else
4402: prev->b_cont = next;
4403: freeb (scan);
4404:
4405:
4406: /*
4407: * Get ready to go around the loop again; if we are copying
4408: * the control part of a message, we have to test for the end
4409: * of the control part here.
4410: */
4411:
4412: if ((scan = next) == NULL)
4413: break;
4414:
4415: if (data == CONTROL_PART && scan->b_datap->db_type == M_DATA)
4416: break;
4417: }
4418:
4419: return 0;
4420: }
4421:
4422:
4423: /*
4424: * This is a buffer callback function used by SHEAD_PEEK () to deal with
4425: * dupmsg () failures via bufcall ().
4426: */
4427:
4428: #if __USE_PROTO__
4429: __LOCAL__ void peek_bufcall_func (_VOID * arg)
4430: #else
4431: __LOCAL__ void
4432: peek_bufcall_func (arg)
4433: _VOID * arg;
4434: #endif
4435: {
4436: pl_t prev_pl;
4437: shead_t * sheadp = (shead_t *) arg;
4438:
4439: /*
4440: * We freeze the stream head read queue to synchronize ourselves with
4441: * the SHEAD_PEEK () and avoid race conditions where we try and wake
4442: * up the process that scheduled us before they have slept.
4443: */
4444:
4445: prev_pl = QFREEZE_TRACE (sheadp->sh_head, "peek_bufcall_func");
4446:
4447: sheadp->sh_read_bufcall = 0;
4448:
4449: SHEAD_WAKE (sheadp, SH_PEEK_WAIT);
4450:
4451: QUNFREEZE_TRACE (sheadp->sh_head, prev_pl);
4452: }
4453:
4454:
4455: /*
4456: * This is a helper function for I_PEEK and read ()-like functions who want
4457: * to recover from an out-of-memory situation by performing a short sleep.
4458: *
4459: * This function takes care of scheduling and cancelling the bufcall. The
4460: * caller must have the stream head locked when calling this function.
4461: *
4462: * This function returns with the stream head read queue unlocked, and with
4463: * the value 0 on success and an error number on error.
4464: */
4465:
4466: #if __USE_PROTO__
4467: __LOCAL__ int (SHEAD_READ_BUFCALL) (shead_t * sheadp, int __NOTUSED (mode))
4468: #else
4469: __LOCAL__ int
4470: SHEAD_READ_BUFCALL __ARGS ((sheadp, mode))
4471: shead_t * sheadp;
4472: int mode;
4473: #endif
4474: {
4475: SHEAD_ASSERT_LOCKED (sheadp);
4476:
4477: if (sheadp->sh_read_bufcall == 0 &&
4478: (sheadp->sh_read_bufcall = bufcall (1024, BPRI_LO,
4479: peek_bufcall_func,
4480: sheadp)) == 0) {
4481: SHEAD_UNLOCK (sheadp, plbase);
4482: return ENOSR;
4483: }
4484:
4485: return SHEAD_WAIT_NONBLOCK (sheadp, FREAD, SH_PEEK_WAIT,
4486: CHECK_SIGNALS);
4487: }
4488:
4489:
4490: /*
4491: * This function implements I_PEEK read-ahead for streams. The caller should
4492: * have the stream head locked for read/write access.
4493: */
4494:
4495: #if __USE_PROTO__
4496: __LOCAL__ int (SHEAD_PEEK) (shead_t * sheadp, struct strpeek * peek,
4497: int * rvalp)
4498: #else
4499: __LOCAL__ int
4500: SHEAD_PEEK __ARGS ((sheadp, peek, rvalp))
4501: shead_t * sheadp;
4502: struct strpeek * peek;
4503: int * rvalp;
4504: #endif
4505: {
4506: mblk_t * msg;
4507: int retval;
4508:
4509: ASSERT (sheadp != NULL);
4510: ASSERT (peek != NULL);
4511: ASSERT (rvalp != NULL);
4512:
4513: if (peek->flags != 0 && peek->flags != RS_HIPRI)
4514: return EINVAL;
4515:
4516: /*
4517: * Look at the stream head to see if there are any queued messages.
4518: *
4519: * Some notes about this are in order; as mentioned in the discussion
4520: * on locking elsewhere, the possibility of page fault resolution
4521: * during copies to user space complicates life, because copy routines
4522: * may sleep while a page is made resident.
4523: *
4524: * This affects routines which read from the stream head in various
4525: * ways, some of which are outlined in the general section on locking.
4526: * Other than data consistency, it also affects the way message are
4527: * deallocated; this routine wants to take a copy of the data in a
4528: * message, but we need to ensure that the message will not be
4529: * deallocated not just by other processes but also by actions at the
4530: * stream level such as M_FLUSH.
4531: *
4532: * Other than getting into a web of locking flags and reference counts
4533: * (there are already too many of those), the simplest ways of dealing
4534: * with this are a) create a duplicate reference to the message data
4535: * with dupmsg (), and b) simply dequeue the message and put it back
4536: * when we're done.
4537: *
4538: * Neither alternative is without unpleasant consequences; a) has to
4539: * deal with a lack of available storage to duplicate the message
4540: * blocks, and b) has to deal with such things as reads blocking while
4541: * the message is dequeued.
4542: *
4543: * a) and b) seem to have more-or-less equal implementation costs, but
4544: * while a) is guaranteed to maintain the semantics of all stream
4545: * operations, b) is not. Unless we can predict all the consequences
4546: * of b) and either work around them or determine that they are benign
4547: * then a) seems preferable.
4548: */
4549:
4550: for (;;) {
4551: (void) QFREEZE_TRACE (sheadp->sh_head, "SHEAD_PEEK");
4552:
4553: if ((msg = SHEAD_FIRSTMSG (sheadp)) == NULL) {
4554: no_message:
4555: /*
4556: * No go; arrange for the value 0 to be returned to
4557: * the caller of the ioctl ().
4558: */
4559:
4560: QUNFREEZE_TRACE (sheadp->sh_head, plbase);
4561: * rvalp = 0;
4562:
4563: return 0;
4564: }
4565:
4566: switch (msg->b_datap->db_type) {
4567:
4568: case M_DATA:
4569: case M_PROTO:
4570: /*
4571: * If the caller has asked for high-priority messages
4572: * only, then we arrange to return 0.
4573: */
4574:
4575: if ((peek->flags & RS_HIPRI) != 0)
4576: goto no_message;
4577: break;
4578:
4579: case M_PCPROTO:
4580: break;
4581:
4582: default:
4583: QUNFREEZE_TRACE (sheadp->sh_head, plbase);
4584: return EBADMSG;
4585: }
4586:
4587:
4588: /*
4589: * Attempt to obtain a duplicate reference to this message.
4590: */
4591:
4592: if ((msg = dupmsg (msg)) != NULL) {
4593:
4594: QUNFREEZE_TRACE (sheadp->sh_head, plbase);
4595: break;
4596: }
4597:
4598:
4599: /*
4600: * Wait a short time for buffers to be available. To do this,
4601: * we transfer our locking attention from the queue to the
4602: * stream head.
4603: */
4604:
4605: (void) SHEAD_LOCK (sheadp);
4606:
4607: QUNFREEZE_TRACE (sheadp->sh_head, plstr);
4608:
4609: if ((retval = SHEAD_READ_BUFCALL (sheadp, FREAD)) != 0)
4610: return retval;
4611: }
4612:
4613:
4614: /*
4615: * Now we have a duplicate copy of a message to transfer to user
4616: * space. From this point on, any attempt to exit from this routine
4617: * must take care of freeing this message. However, we don't have to
4618: * touch the queue again.
4619: */
4620:
4621: peek->flags = msg->b_datap->db_type == M_PCPROTO ? RS_HIPRI : 0;
4622:
4623: retval = (COPYOUT_BUF (& peek->ctlbuf, & msg, CONTROL_PART) != 0 ||
4624: COPYOUT_BUF (& peek->databuf, & msg,
4625: DATA_PART) != 0) ? EFAULT : 0;
4626:
4627: if (msg != NULL)
4628: freemsg (msg);
4629:
4630: * rvalp = 1;
4631:
4632: return retval;
4633: }
4634:
4635:
4636: /*
4637: * Helper function to atomically read the stream head write offset.
4638: */
4639:
4640: #if __USE_PROTO__
4641: __LOCAL__ short (SHEAD_WRITEOFFSET) (shead_t * sheadp)
4642: #else
4643: __LOCAL__ short
4644: SHEAD_WRITEOFFSET __ARGS ((sheadp))
4645: shead_t * sheadp;
4646: #endif
4647: {
4648: pl_t prev_pl;
4649: short opt;
4650:
4651: prev_pl = SHEAD_LOCK (sheadp);
4652:
4653: opt = sheadp->sh_readopt;
4654:
4655: SHEAD_UNLOCK (sheadp, prev_pl);
4656:
4657: return opt;
4658: }
4659:
4660:
4661: /*
4662: * This function tests for errors on a stream and optionally also waits for
4663: * flow control to be relieved.
4664: */
4665:
4666: #if __USE_PROTO__
4667: __LOCAL__ int (SHEAD_WRITE_TEST) (shead_t * sheadp, int mode, int band,
4668: int hipri)
4669: #else
4670: __LOCAL__ int
4671: SHEAD_WRITE_TEST __ARGS ((sheadp, mode, band, hipri))
4672: shead_t * sheadp;
4673: int mode;
4674: int band;
4675: int hipri;
4676: #endif
4677: {
4678: int retval;
4679:
4680: do {
4681: (void) SHEAD_LOCK (sheadp);
4682:
4683: if ((retval = SHEAD_ERRHUP_LOCKED (sheadp, mode)) != 0)
4684: break;
4685:
4686: if (hipri != 0 || bcanputnext (W (sheadp->sh_head), band)) {
4687:
4688: SHEAD_UNLOCK (sheadp, plbase);
4689: break;
4690: }
4691: } while ((retval = SHEAD_WAIT_NONBLOCK (sheadp, mode, SH_WRITE_WAIT,
4692: CHECK_SIGNALS)) == 0);
4693:
4694: return retval;
4695: }
4696:
4697:
4698: /*
4699: * This function deals with all the grunge of creating a message for sending
4700: * down a stream. There are many conditions that need to be checked, including
4701: * whether the message fits within the size limits given by the downstream
4702: * queue.
4703: *
4704: * Since the message is going to be written to the stream, we also deal with
4705: * waiting for flow control here. We only allocate memory for the user's data
4706: * when we have an indication that it will be valid to write it... this may
4707: * not be an optimal choice for a high-performance system with vast amounts
4708: * of STREAMS buffer space.
4709: */
4710:
4711: #if __USE_PROTO__
4712: __LOCAL__ mblk_t * (SHEAD_MAKEMSG) (shead_t * sheadp, int mode,
4713: struct strbuf * ctlbuf,
4714: struct strbuf * databuf,
4715: int flags, int band, int * retvalp)
4716: #else
4717: __LOCAL__ mblk_t *
4718: SHEAD_MAKEMSG __ARGS ((sheadp, mode, ctlbuf, databuf, flags, band, retvalp))
4719: shead_t * sheadp;
4720: int mode;
4721: struct strbuf * ctlbuf;
4722: struct strbuf * databuf;
4723: int flags;
4724: int band;
4725: int * retvalp;
4726: #endif
4727: {
4728: queue_t * q;
4729: int ctlsize;
4730: int datasize;
4731: int wroff;
4732: mblk_t * ctlmsg;
4733: mblk_t * datamsg;
4734:
4735: ASSERT (sheadp != NULL);
4736: ASSERT (retvalp != NULL);
4737:
4738: /*
4739: * The "flags" value specifies one of the constants MSG_BAND or
4740: * MSG_HIPRI. Despite being arranged as flags, only one is allowed to
4741: * be given.
4742: */
4743:
4744: if (flags != MSG_BAND && flags != MSG_HIPRI) {
4745:
4746: * retvalp = EINVAL;
4747: return NULL;
4748: }
4749:
4750: if ((mode & FWRITE) == 0) {
4751:
4752: * retvalp = EBADF;
4753: return NULL;
4754: }
4755:
4756: mode &= ~ FREAD;
4757:
4758:
4759: /*
4760: * The absolute maximum possible size for the control or data parts of
4761: * a STREAMS message are configured system-wide.
4762: */
4763:
4764: ctlsize = ctlbuf == NULL ? -1 : ctlbuf->len;
4765: datasize = databuf == NULL ? -1 : databuf->len;
4766: wroff = SHEAD_WRITEOFFSET (sheadp);
4767:
4768: q = TOP_QUEUE (sheadp);
4769:
4770: if (ctlsize > str_mem->sm_maxctlsize ||
4771: (datasize + wroff) > str_mem->sm_maxdatasize ||
4772: (datasize + wroff) < q->q_minpsz ||
4773: (datasize + wroff) > q->q_maxpsz) {
4774:
4775: * retvalp = ERANGE;
4776: return NULL;
4777: }
4778:
4779:
4780: /*
4781: * You can't send a high-priority message without a control part, or a
4782: * high-priority message with a non-zero band number.
4783: *
4784: * Otherwise, if no data at all is specified, then no message will be
4785: * sent.
4786: */
4787:
4788: if (flags == MSG_HIPRI) {
4789:
4790: if (ctlsize < 0 || band != 0) {
4791:
4792: * retvalp = EINVAL;
4793: return NULL;
4794: }
4795: } else if (datasize < 0 && ctlsize < 0) {
4796:
4797: * retvalp = 0;
4798: return NULL;
4799: }
4800:
4801:
4802: /*
4803: * Let's see if the stream is flow controlled; if it is, we either
4804: * block or return EAGAIN depending on the FNDELAY/FNONBLOCK setting.
4805: */
4806:
4807: if ((* retvalp = SHEAD_WRITE_TEST (sheadp, mode, band, flags)) != 0)
4808: return NULL;
4809:
4810: /*
4811: * Now we allocate data space for the messages. If the size of a
4812: * component is -1, then we don't allocate any space for that part,
4813: * otherwise we allocate a component of length 0.
4814: *
4815: * Don't forget that copyin () has arguments in the bcopy () order,
4816: * ie. src, dest, len
4817: */
4818:
4819: if (ctlsize >= 0) {
4820: /*
4821: * Special case; the stream head is required to ensure that
4822: * the control part of any message has at least 64 bytes of
4823: * space. This is specified in the putmsg (2) manual page!
4824: */
4825:
4826: if ((ctlmsg = MSGB_ALLOC (ctlsize < 64 ? 64 : ctlsize,
4827: BPRI_LO, KM_SLEEP)) == NULL) {
4828: * retvalp = ENOSR;
4829: return NULL;
4830: }
4831:
4832: ctlmsg->b_datap->db_type = flags == MSG_HIPRI ? M_PCPROTO :
4833: M_PROTO;
4834: ctlmsg->b_band = band;
4835:
4836: if (ctlsize > 0 &&
4837: copyin (ctlbuf->buf, ctlmsg->b_rptr, ctlsize) != 0) {
4838:
4839: freeb (ctlmsg);
4840: * retvalp = EFAULT;
4841: return NULL;
4842: }
4843:
4844: ctlmsg->b_wptr += ctlsize;
4845: } else
4846: ctlmsg = NULL; /* paranoia */
4847:
4848: if (datasize >= 0) {
4849:
4850: if ((datamsg = MSGB_ALLOC (datasize + wroff, BPRI_LO,
4851: KM_SLEEP)) == NULL) {
4852: if (ctlsize >= 0)
4853: freeb (ctlmsg);
4854:
4855: * retvalp = ENOSR;
4856: return NULL;
4857: }
4858:
4859: if (ctlsize < 0)
4860: ctlmsg = datamsg;
4861: else
4862: ctlmsg->b_cont = datamsg;
4863:
4864: datamsg->b_band = band;
4865: datamsg->b_wptr = datamsg->b_wptr = datamsg->b_rptr + wroff;
4866:
4867: if (datasize > 0 &&
4868: copyin (databuf->buf, datamsg->b_rptr, datasize) != 0) {
4869:
4870: freemsg (ctlmsg);
4871:
4872: * retvalp = EFAULT;
4873: return NULL;
4874: }
4875:
4876: datamsg->b_wptr += datasize;
4877: }
4878:
4879:
4880: /*
4881: * Since the allocation requests could have blocked for memory to
4882: * become available, and the copy requests could have blocked to
4883: * resolve page faults, we could actually be a fair way down the track
4884: * by now.
4885: *
4886: * If we were paranoid, we would recheck the flow control parameters
4887: * and a bunch of other stuff, but there doesn't seem to be a whole
4888: * lot of point to that. As long as we don't use data that could have
4889: * changed while we waited, we're fine.
4890: */
4891:
4892: * retvalp = 0;
4893: return ctlmsg;
4894: }
4895:
4896:
4897: /*
4898: * This function implements the I_FDINSERT ioctl ().
4899: */
4900:
4901: #if __USE_PROTO__
4902: __LOCAL__ int (SHEAD_FDINSERT) (shead_t * sheadp, int mode,
4903: struct strfdinsert * fdinsp)
4904: #else
4905: __LOCAL__ int
4906: SHEAD_FDINSERT __ARGS ((sheadp, mode, fdinsp))
4907: shead_t * sheadp;
4908: int mode;
4909: struct strfdinsert
4910: * fdinsp;
4911: #endif
4912: {
4913: int retval;
4914: shead_t * other;
4915: mblk_t * msg;
4916:
4917: ASSERT (sheadp != NULL);
4918: ASSERT (fdinsp != NULL);
4919:
4920: /*
4921: * There are a large number of error conditions to check for this
4922: * function. Don't lose sight of the fact that the big set of chained
4923: * conditions below computes "other" for us.
4924: */
4925: /*
4926: * ALIGNMENT-DEPENDENT CODE.
4927: */
4928:
4929: if ((fdinsp->flags != 0 && fdinsp->flags != RS_HIPRI) ||
4930: ((unsigned) fdinsp->offset & ~ sizeof (int)) != 0 ||
4931: fdinsp->offset + sizeof (queue_t *) > fdinsp->ctlbuf.len ||
4932: (other = FH_TO_STREAM (fdinsp->fildes, & retval)) != 0) {
4933: /*
4934: * A failure of any of the above returns EINVAL; according to
4935: * streamio (7) EINVAL rather than EBADF results from a bad
4936: * file descriptor.
4937: */
4938:
4939: return EINVAL;
4940: }
4941:
4942: /*
4943: * Make a band 0 message (possibly high-priority). This can fail if
4944: * the requested message is too large for the advertised limits set
4945: * by the next thing downstream.
4946: *
4947: * IMPORANT: we *rely* on this function making a message with a single
4948: * large control block at least as big as the advertised size. If we
4949: * cannot rely on this function we have to do lots of extra checking
4950: * which I'd rather avoid.
4951: */
4952:
4953: msg = SHEAD_MAKEMSG (sheadp, mode, & fdinsp->ctlbuf,
4954: & fdinsp->databuf,
4955: fdinsp->flags ? MSG_HIPRI : MSG_BAND, 0,
4956: & retval);
4957: if (msg == NULL)
4958: return retval;
4959:
4960: /*
4961: * Note that we don't recheck for hangups even though we could have
4962: * waited a poentially long time in SHEAD_MAKEMSG (). The hangup
4963: * condition has plenty of slop in it with the time it takes write
4964: * messages to move down the queue anyway; drivers and modules have to
4965: * be able to cope.
4966: */
4967:
4968: * (queue_t **) (msg->b_rptr + fdinsp->offset) = other->sh_head;
4969:
4970: putq (W (sheadp->sh_head), msg);
4971:
4972: return 0;
4973: }
4974:
4975:
4976: /*
4977: * This function implements the I_FIND ioctl ().
4978: */
4979:
4980: #if __USE_PROTO__
4981: __LOCAL__ int (SHEAD_FIND_MODINFO) (shead_t * sheadp, char * modname,
4982: int * rvalp)
4983: #else
4984: __LOCAL__ int
4985: SHEAD_FIND_MODINFO __ARGS ((sheadp, modname, rvalp))
4986: shead_t * sheadp;
4987: char * modname;
4988: int * rvalp;
4989: #endif
4990: {
4991: modsw_t * module;
4992:
4993: /*
4994: * First try to find the module in the global list of modules, then
4995: * attempt to find that module's info on the stream.
4996: */
4997:
4998: if ((module = FIND_MODULE (modname)) == NULL)
4999: return EINVAL;
5000: else {
5001: queue_t * scan;
5002: pl_t prev_pl;
5003:
5004: /*
5005: * Walk down the write side of the stream until either the
5006: * write side module info matches -or- a cross-point is found.
5007: */
5008:
5009: scan = W (sheadp->sh_head);
5010:
5011: prev_pl = SHEAD_LOCK (sheadp);
5012:
5013: while (scan->q_next != NULL) {
5014: if ((scan->q_flag & QREADR) !=
5015: (scan->q_next->q_flag & QREADR)) {
5016: /*
5017: * Set scan to NULL to flag an unsuccessful
5018: * search.
5019: */
5020:
5021: scan = NULL;
5022: break;
5023: }
5024:
5025: scan = scan->q_next;
5026:
5027: if ((scan->q_flag & QPROCSOFF) != 0)
5028: continue;
5029:
5030: if (scan->q_qinfo == module->mod_stream->st_wrinit)
5031: break;
5032: }
5033:
5034: SHEAD_UNLOCK (sheadp, prev_pl);
5035:
5036: * rvalp = scan != NULL;
5037: }
5038:
5039: return 0;
5040: }
5041:
5042:
5043: /*
5044: * This function implements the I_LIST ioctl () for the case where the user
5045: * supplies a buffer to copy the module/driver names into.
5046: */
5047:
5048: #if __USE_PROTO__
5049: __LOCAL__ int (SHEAD_LIST) (shead_t * sheadp, struct str_list * slistp,
5050: int * rvalp)
5051: #else
5052: __LOCAL__ int
5053: SHEAD_LIST __ARGS ((sheadp, slistp, rvalp))
5054: shead_t * sheadp;
5055: struct str_list
5056: * slistp;
5057: int * rvalp;
5058: #endif
5059: {
5060: queue_t * scan;
5061: int modcount;
5062: int i;
5063: struct str_mlist
5064: * buf;
5065: struct str_mlist
5066: * temp;
5067:
5068: if (slistp->sl_nmods < 1)
5069: return EINVAL;
5070:
5071: /*
5072: * The EAGAIN error documented for I_LIST in streamio (7) is
5073: * suggestive of how it is implemented; rather than get involved in
5074: * tricky synchronization issues, copy the module names into a kernel
5075: * buffer and then copy that to user level.
5076: */
5077:
5078: modcount = SHEAD_MODCOUNT (sheadp);
5079:
5080: if (modcount > slistp->sl_nmods)
5081: modcount = slistp->sl_nmods;
5082:
5083:
5084: /*
5085: * If we were paranoid, we'd user kmem_zalloc () to ensure that the
5086: * data we copy to user space contains no sensitive information. As it
5087: * happens, because of the fact we user strncpy () to fill the buffer
5088: * with data, we are guaranteed that we have overwritten all of the
5089: * contents.
5090: */
5091:
5092: if ((buf = (struct str_mlist *) kmem_alloc (modcount * sizeof (* buf),
5093: KM_SLEEP)) == NULL)
5094: return EAGAIN;
5095:
5096: /*
5097: * Now fill the buffer in by moving down the stream. We don't worry
5098: * about the race between the calculation of the buffer size and the
5099: * time we fill it in, because the problem also exists for the user;
5100: * in order to know how much space to allocate at user level, some
5101: * arrangement must have been made to ensure things are stable.
5102: */
5103:
5104: i = 0;
5105: scan = W (sheadp->sh_head);
5106: temp = buf;
5107:
5108: (void) SHEAD_LOCK (sheadp);
5109:
5110: while (scan->q_next != NULL &&
5111: ((scan->q_flag & QREADR) == (scan->q_next->q_flag & QREADR))) {
5112:
5113: scan = scan->q_next;
5114:
5115: if ((scan->q_flag & QPROCSOFF) != 0)
5116: continue;
5117:
5118: if (i ++ > modcount)
5119: break;
5120:
5121: /*
5122: * Now actually copy the module name. Note that we count on
5123: * strncpy () null-padding the target for security.
5124: */
5125:
5126: strncpy (temp->l_name, scan->q_qinfo->qi_minfo->mi_idname,
5127: sizeof (temp->l_name) - 1);
5128: temp->l_name [sizeof (temp->l_name) - 1] = 0;
5129: }
5130:
5131: SHEAD_UNLOCK (sheadp, plbase);
5132:
5133: /*
5134: * After unlocking we can safely call copyout (), which we could not
5135: * use inside the loop because it may sleep resolving a page fault.
5136: * Don't forget that copyout () is like bcopy (), not memcpy ()!
5137: */
5138:
5139: * rvalp = i;
5140:
5141: i = copyout (buf, slistp->sl_modlist, i * sizeof (* buf));
5142:
5143: kmem_free (buf, modcount * sizeof (* buf));
5144:
5145: return i == 0 ? 0 : EFAULT;
5146: }
5147:
5148:
5149: /*
5150: * This function deals with setting the stream head read mode flag bits in
5151: * M_SETOPT messages or from an I_SRDOPT ioctl ().
5152: */
5153:
5154: #if __USE_PROTO__
5155: int (SHEAD_SRDOPT) (shead_t * sheadp, int flag)
5156: #else
5157: int
5158: SHEAD_SRDOPT __ARGS ((sheadp, flag))
5159: shead_t * sheadp;
5160: int flag;
5161: #endif
5162: {
5163: int newflag;
5164:
5165: SHEAD_ASSERT_LOCKED (sheadp);
5166:
5167: if ((newflag = flag & RMODEMASK) == __RINVAL)
5168: return EINVAL;
5169:
5170: /*
5171: * The streamio (7) man pages seem ambiguous about whether an
5172: * application is permitted to, has to, or cannot diagnose a request
5173: * to set multiple read options.
5174: *
5175: * Arbitrarily, we choose not to.
5176: */
5177:
5178: newflag |= (flag & RPROTNORM) != 0 ? RPROTNORM :
5179: (flag & RPROTDAT) != 0 ? RPROTDAT :
5180: (flag & RPROTDIS) != 0 ? RPROTDIS :
5181: (sheadp->sh_readopt & ~ RMODEMASK);
5182:
5183: sheadp->sh_readopt = newflag;
5184:
5185: return 0;
5186: }
5187:
5188:
5189: /*
5190: * This table determines how many bytes to copy from user space at the start
5191: * of ioctl () processing and how many bytes to copy to user space at the end
5192: * of processing (presuming no other errors have occurred yet).
5193: */
5194:
5195: #define BADLEN ((unsigned short) -1)
5196:
5197: typedef enum {
5198: IO_NOLOCK = 0,
5199: IO_BASIC_LOCK,
5200: IO_READFREEZE,
5201: IO_SLEEP_LOCK
5202: } iolock_t;
5203:
5204: enum { NOHUP,
5205: HUP
5206: };
5207:
5208: static struct ioinfo {
5209: iolock_t lock; /* lock type */
5210: cat_t cat; /* category flag */
5211: unsigned short in_len; /* bytes to copy in */
5212: unsigned short out_len; /* bytes to copy out */
5213: unsigned char hup_chk; /* check for hangup */
5214: } _ioctl_table [] = {
5215: { IO_NOLOCK, SH_NONE, BADLEN, BADLEN, NOHUP },
5216: /* illegal */
5217: { IO_READFREEZE, SH_NONE, sizeof (size_t), NOHUP },
5218: /* I_NREAD */
5219: { IO_SLEEP_LOCK, SH_OPENCLOSE | SH_IOCTL_LOCK,
5220: FMNAMESZ + 1, 0, HUP }, /* I_PUSH */
5221: { IO_SLEEP_LOCK, SH_OPENCLOSE | SH_IOCTL_LOCK, 0, 0, HUP },
5222: /* I_POP */
5223: { IO_NOLOCK, SH_NONE, FMNAMESZ + 1, FMNAMESZ + 1, NOHUP },
5224: /* I_LOOK */
5225: { IO_NOLOCK, SH_NONE, 0, 0, HUP }, /* I_FLUSH */
5226: { IO_BASIC_LOCK, SH_NONE, 0, 0, NOHUP },/* I_SRDOPT */
5227: { IO_BASIC_LOCK, SH_NONE, 0, sizeof (int), NOHUP },
5228: /* I_GRDOPT */
5229: { IO_SLEEP_LOCK, SH_IOCTL_LOCK, sizeof (struct strioctl),
5230: sizeof (struct strioctl), HUP },/* I_STR */
5231: { IO_SLEEP_LOCK, SH_IOCTL_LOCK, 0, 0, NOHUP },
5232: /* I_SETSIG */
5233: { IO_SLEEP_LOCK, SH_IOCTL_LOCK, 0, sizeof (int), NOHUP },
5234: /* I_GETSIG */
5235: { IO_NOLOCK, SH_NONE, FMNAMESZ + 1, 0, NOHUP },
5236: /* I_FIND */
5237: { IO_SLEEP_LOCK, SH_IOCTL_LOCK, 0, 0, HUP },
5238: /* I_LINK */
5239: { IO_SLEEP_LOCK, SH_IOCTL_LOCK, 0, 0, HUP },
5240: /* I_UNLINK */
5241: { IO_SLEEP_LOCK, SH_READ_LOCK, 0, sizeof (struct strrecvfd), HUP },
5242: /* I_RECVFD */
5243: { IO_SLEEP_LOCK, SH_READ_LOCK, sizeof (struct strpeek),
5244: sizeof (struct strpeek), NOHUP },/* I_PEEK */
5245: { IO_NOLOCK, SH_NONE, sizeof (struct strfdinsert), 0, NOHUP },
5246: /* I_FDINSERT */
5247: { IO_NOLOCK, SH_NONE, 0, 0, HUP }, /* I_SENDFD */
5248: { IO_NOLOCK, SH_NONE, BADLEN, BADLEN, NOHUP },
5249: /* --- */
5250: { IO_BASIC_LOCK, SH_NONE, 0, 0, NOHUP },/* I_SWROPT */
5251: { IO_BASIC_LOCK, SH_NONE, 0, sizeof (int), NOHUP },
5252: /* I_GWROPT */
5253: { IO_NOLOCK, SH_NONE, 0, 0, NOHUP }, /* I_LIST */ /* special */
5254: { IO_BASIC_LOCK, SH_OPENCLOSE | SH_IOCTL_LOCK, 0, 0, HUP },
5255: /* I_PLINK */
5256: { IO_BASIC_LOCK, SH_OPENCLOSE | SH_IOCTL_LOCK, 0, 0, HUP },
5257: /* I_PUNLINK */
5258: { IO_NOLOCK, SH_NONE, BADLEN, BADLEN, NOHUP },
5259: /* I_SETEV */
5260: { IO_NOLOCK, SH_NONE, BADLEN, BADLEN, NOHUP },
5261: /* I_GETEV */
5262: { IO_NOLOCK, SH_NONE, BADLEN, BADLEN, NOHUP },
5263: /* I_STREV */
5264: { IO_NOLOCK, SH_NONE, BADLEN, BADLEN, NOHUP },
5265: /* I_UNSTREV */
5266: { IO_NOLOCK, SH_NONE, sizeof (struct bandinfo), 0, HUP },
5267: /* I_FLUSHBAND */
5268: { IO_READFREEZE, SH_NONE, 0, 0, NOHUP },/* I_CKBAND */
5269: { IO_READFREEZE, SH_NONE, 0, sizeof (int), NOHUP },
5270: /* I_GETBAND */
5271: { IO_READFREEZE, SH_NONE, 0, 0, NOHUP },/* I_ATMARK */
5272: { IO_BASIC_LOCK, SH_NONE, sizeof (__clock_t), 0, NOHUP },
5273: /* I_SETCLTIME */
5274: { IO_BASIC_LOCK, SH_NONE, 0, sizeof (__clock_t), NOHUP },
5275: /* I_GETCLTIME */
5276: { IO_NOLOCK, SH_NONE, 0, 0, HUP } /* I_CANPUT */
5277: };
5278:
5279: struct ioinfo _transparent = {
5280: IO_SLEEP_LOCK, SH_IOCTL_LOCK, 0, 0, HUP
5281: };
5282:
5283:
5284: /*
5285: * Symbol for accessing the default ioctl () and close timeouts. Consider
5286: * making this a static variable and initializing it at boot time.
5287: */
5288:
5289: #define IOCTL_TIMEOUT drv_usectohz ((__clock_t) 15000000L)
5290:
5291:
5292: /*
5293: * Main ioctl () processing for STREAMS files and pipes.
5294: *
5295: * This switch+table is an abomination, but trying to emulate C++ style in C
5296: * to subsume the switch and the above table would probably kill me. This
5297: * probably is about as short as it can really be.
5298: */
5299:
5300: #if __USE_PROTO__
5301: int (STREAMS_IOCTL) (shead_t * sheadp, int cmd, _VOID * arg, int mode,
5302: cred_t * credp, int * rvalp)
5303: #else
5304: int
5305: STREAMS_IOCTL (sheadp, cmd, arg, mode, credp, rvalp)
5306: shead_t * sheadp;
5307: int cmd;
5308: _VOID * arg;
5309: int mode;
5310: cred_t * credp;
5311: int * rvalp;
5312: #endif
5313: {
5314: union {
5315: int i_int;
5316: __clock_t i_clock;
5317: size_t i_size;
5318: char i_modname [FMNAMESZ + 1];
5319: struct strioctl i_strioc;
5320: struct strrecvfd i_recvfd;
5321: struct strbuf i_strbuf;
5322: struct strfdinsert
5323: i_fdinsert;
5324: struct str_list i_list;
5325: struct bandinfo i_band;
5326: struct strpeek i_peek;
5327: } iocbuf;
5328: int retval;
5329: struct ioinfo * info;
5330:
5331: ASSERT (sheadp != NULL);
5332:
5333: /*
5334: * We start out by copying in the data specified by the table, which
5335: * means we also get to range-check the ioctl entry if it has the
5336: * magic STREAMS id.
5337: */
5338:
5339: if ((cmd & ~ 0xFF) == STREAM_I) {
5340: int index = cmd & 0xFF;
5341:
5342: if (index >= sizeof (_ioctl_table) / sizeof (* info))
5343: return EINVAL;
5344:
5345: info = & _ioctl_table [index];
5346: } else
5347: info = & _transparent;
5348:
5349: if (info->in_len == BADLEN)
5350: return EINVAL;
5351:
5352: /*
5353: * We *must* do the copy before the lock! Never forget that
5354: * copyin ()/copyout () can block in page fault resolution.
5355: */
5356:
5357: if (info->in_len > 0 && copyin (arg, & iocbuf, info->in_len) != 0)
5358: return EFAULT;
5359:
5360: /*
5361: * We may wish to check for a hangup or error before proceeding.
5362: */
5363:
5364: (void) SHEAD_LOCK (sheadp);
5365:
5366: if (info->hup_chk == HUP &&
5367: (retval = SHEAD_ERRHUP_LOCKED (sheadp, mode)) != 0)
5368: return ENXIO;
5369:
5370: if (info->lock != IO_BASIC_LOCK)
5371: SHEAD_UNLOCK (sheadp, plbase);
5372:
5373: switch (info->lock) {
5374:
5375: case IO_BASIC_LOCK:
5376: /* stay holding on to the basic lock */
5377: break;
5378:
5379: case IO_READFREEZE:
5380: (void) QFREEZE_TRACE (sheadp->sh_head, "STREAMS_IOCTL");
5381: break;
5382:
5383: case IO_SLEEP_LOCK:
5384: if ((retval = SHEAD_SLEEP_LOCK (sheadp, info->cat,
5385: IOCTL_TIMEOUT,
5386: CHECK_SIGNALS)) != 0)
5387: return retval;
5388: break;
5389:
5390: default:
5391: break;
5392: }
5393:
5394: retval = 0;
5395:
5396: switch (cmd) {
5397:
5398: case I_NREAD: /* Get message length, count */
5399: {
5400: mblk_t * scan;
5401: mblk_t * first = NULL;
5402:
5403: * rvalp = 0;
5404:
5405: for (scan = SHEAD_FIRSTMSG (sheadp) ; scan != NULL ;
5406: scan = scan->b_next) {
5407:
5408: if (datamsg (scan->b_datap->db_type)) {
5409:
5410: if (first == NULL)
5411: first = scan;
5412: (* rvalp) ++;
5413: }
5414: }
5415:
5416: if (first != NULL)
5417: iocbuf.i_int = msgdsize (first);
5418: else
5419: iocbuf.i_int = 0;
5420: }
5421: break;
5422:
5423: case I_PUSH: /* push named module */
5424: {
5425: modsw_t * module;
5426:
5427: if ((module = FIND_MODULE (iocbuf.i_modname)) == NULL)
5428: retval = EINVAL;
5429: else
5430: retval = PUSH_MODULE (sheadp, mode, credp,
5431: module);
5432: }
5433: break;
5434:
5435: case I_POP: /* pop topmost module */
5436: {
5437: queue_t * q;
5438:
5439: if ((q = TOP_MODULE (sheadp)) == NULL)
5440: retval = EINVAL;
5441: else
5442: retval = POP_MODULE (sheadp, q, mode, credp);
5443: }
5444: break;
5445:
5446: case I_LOOK: /* get topmost module name */
5447: {
5448: queue_t * q;
5449:
5450: if ((q = TOP_MODULE (sheadp)) == NULL)
5451: retval = EINVAL;
5452: else {
5453: /*
5454: * Copy the module name, taking care to
5455: * 0-terminate it at FMNAMESZ bytes long.
5456: */
5457:
5458: strncpy (iocbuf.i_modname,
5459: q->q_qinfo->qi_minfo->mi_idname,
5460: FMNAMESZ);
5461: iocbuf.i_modname [FMNAMESZ] = 0;
5462: }
5463: }
5464: break;
5465:
5466: case I_FLUSH: /* flush read and/or write side */
5467: retval = SHEAD_FLUSH (sheadp, (int) arg, 0);
5468: break;
5469:
5470: case I_SRDOPT: /* set read options */
5471: retval = SHEAD_SRDOPT (sheadp, (int) arg);
5472: break;
5473:
5474: case I_GRDOPT: /* retrieve read options */
5475: iocbuf.i_int = sheadp->sh_readopt;
5476: break;
5477:
5478: case I_STR: /* send ioctl () data down a stream */
5479: if ((iocbuf.i_strioc.ic_cmd & ~ 0xFF) == STREAM_I ||
5480: (unsigned) iocbuf.i_strioc.ic_len == TRANSPARENT) {
5481: /*
5482: * We do not permit I_STR to send STREAMS ioctl ()
5483: * codes downstream; in certain cases such as I_LINK
5484: * this could produce disastrous results.
5485: *
5486: * We also do not permit TRANSPARENT length I_STR
5487: * messages. While the STREAMS documentation neither
5488: * explicitly permits or forbids this, we keep the
5489: * transparent ioctl () behaviour separate.
5490: */
5491:
5492: retval = EINVAL;
5493: break;
5494:
5495: }
5496:
5497: retval = ISTR_IOCTL (sheadp, mode, & iocbuf.i_strioc, credp,
5498: rvalp);
5499: break;
5500:
5501: case I_SETSIG: /* register events for SIGPOLL signal */
5502: {
5503: int events = (short) (ulong_t) arg;
5504:
5505: if ((events & ~ __POLL_MASK) != 0)
5506: retval = EINVAL;
5507: else
5508: retval = REGISTER_SIGPOLL (sheadp, events);
5509: }
5510: break;
5511:
5512: case I_GETSIG: /* return registered event mask */
5513: {
5514: sigpoll_t * sigs;
5515:
5516: if ((sigs = FIND_SIGPOLL (sheadp)) == NULL)
5517: retval = EINVAL;
5518: else
5519: * rvalp = sigs->sp_events;
5520: }
5521: break;
5522:
5523: case I_FIND: /* determine if module exists on stream */
5524: retval = SHEAD_FIND_MODINFO (sheadp, iocbuf.i_modname, rvalp);
5525: break;
5526:
5527: case I_LINK: /* link stream below another */
5528: case I_PLINK: /* create a persistent link */
5529: {
5530: shead_t * lower;
5531:
5532: if ((lower = FH_TO_STREAM ((int) arg,
5533: & retval)) != NULL) {
5534: retval = SHEAD_LINK (sheadp, mode, lower, cmd,
5535: credp);
5536:
5537: if (retval == 0)
5538: * rvalp = lower->sh_muxid;
5539: }
5540: }
5541: break;
5542:
5543: case I_UNLINK: /* remove a (or all) link(s) below a stream */
5544: case I_PUNLINK: /* undo a single or all persistent link(s) */
5545: do {
5546: shead_t * lower;
5547:
5548: if ((lower = SHEAD_FIND_MUXID (sheadp, cmd,
5549: (int) arg)) == NULL) {
5550: /*
5551: * We return EINVAL if a specific mux ID was
5552: * given, 0 otherwise.
5553: */
5554:
5555: retval = (int) arg == -1 ? 0 : EINVAL;
5556: break;
5557:
5558: }
5559:
5560: (void) SHEAD_UNLINK (sheadp, lower, cmd, mode, credp,
5561: & retval);
5562: } while ((int) arg == -1);
5563: break;
5564:
5565: case I_RECVFD: /* receive a file descriptor from stream */
5566: retval = FH_RECV (sheadp, mode, & iocbuf.i_recvfd);
5567: break;
5568:
5569: case I_PEEK: /* examine data at stream head */
5570: retval = SHEAD_PEEK (sheadp, & iocbuf.i_peek, rvalp);
5571: break;
5572:
5573: case I_FDINSERT: /* send read queue pointer down stream */
5574: retval = SHEAD_FDINSERT (sheadp, mode, & iocbuf.i_fdinsert);
5575: break;
5576:
5577: case I_SENDFD: /* send a file descriptor down a pipe */
5578: retval = FH_SEND (sheadp, (int) arg, credp);
5579: break;
5580:
5581: case I_SWROPT: /* set write options for stream */
5582: {
5583: int flag = (int) arg;
5584:
5585: if ((flag & ~ SNDZERO) != 0)
5586: retval = EINVAL;
5587: else
5588: sheadp->sh_wropt = flag;
5589: }
5590: break;
5591:
5592: case I_GWROPT: /* retrieve write options for stream */
5593: iocbuf.i_int = sheadp->sh_wropt;
5594: break;
5595:
5596: case I_LIST: /* get names of all modules/drivers */
5597: /*
5598: * The value of "arg" is a pointer to a structure for this
5599: * entry, but since a NULL value is legal we don't copy the
5600: * data in automatically.
5601: *
5602: * Here we select the call type and copy in the structure for
5603: * the non-NULL case.
5604: */
5605:
5606: if (arg == NULL)
5607: * rvalp = SHEAD_MODCOUNT (sheadp);
5608: else if (copyin (arg, & iocbuf, sizeof (iocbuf.i_list)) != 0)
5609: retval = EFAULT;
5610: else
5611: retval = SHEAD_LIST (sheadp, & iocbuf.i_list, rvalp);
5612: break;
5613:
5614: case I_SETEV: /* The meaning of these ioctl ()'s is not */
5615: case I_GETEV: /* documented, although their names and */
5616: case I_STREV: /* numeric values are given in the System */
5617: case I_UNSTREV: /* V ABI. */
5618: retval = EINVAL;
5619: break;
5620:
5621: case I_FLUSHBAND: /* flush messages in a priority band */
5622: retval = SHEAD_FLUSH (sheadp, iocbuf.i_band.bi_flag,
5623: iocbuf.i_band.bi_pri);
5624: break;
5625:
5626: case I_CKBAND: /* check for existence of band on stream */
5627: if ((uchar_t) (ulong_t) arg != (ulong_t) arg)
5628: retval = EINVAL;
5629: else {
5630: mblk_t * scan;
5631:
5632: for (scan = SHEAD_FIRSTMSG (sheadp) ; scan != NULL ;
5633: scan = scan->b_next)
5634: if (datamsg (scan->b_datap->db_type) &&
5635: scan->b_band == (uchar_t) (ulong_t) arg)
5636: break;
5637:
5638: * rvalp = scan != NULL;
5639: }
5640: break;
5641:
5642: case I_GETBAND: /* get the band number of the first message */
5643: {
5644: mblk_t * scan;
5645:
5646: for (scan = SHEAD_FIRSTMSG (sheadp) ; scan != NULL ;
5647: scan = scan->b_next) {
5648:
5649: if (datamsg (scan->b_datap->db_type))
5650: break;
5651: }
5652:
5653: if (scan == NULL)
5654: retval = ENODATA;
5655: else
5656: iocbuf.i_int = scan->b_band;
5657: }
5658: break;
5659:
5660: case I_ATMARK: /* test for (last) mark on messages */
5661: {
5662: mblk_t * scan = SHEAD_FIRSTMSG (sheadp);
5663:
5664: if ((ulong_t) arg != ANYMARK &&
5665: (ulong_t) arg != LASTMARK) {
5666:
5667: retval = EINVAL;
5668: break;
5669: }
5670:
5671: if (scan == NULL || (scan->b_flag & MSGMARK) == 0) {
5672:
5673: * rvalp = 0;
5674: break;
5675: }
5676:
5677: * rvalp = 1;
5678:
5679: if ((ulong_t) arg == LASTMARK)
5680: while ((scan = scan->b_next) != NULL)
5681: if ((scan->b_flag & MSGMARK) != 0) {
5682: * rvalp = 0;
5683: break;
5684: }
5685: }
5686: break;
5687:
5688: case I_SETCLTIME: /* set close timeout for stream */
5689: if (iocbuf.i_clock != 0)
5690: sheadp->sh_cltime = iocbuf.i_clock;
5691: else
5692: retval = EINVAL;
5693: break;
5694:
5695: case I_GETCLTIME: /* retrieve current close timeout */
5696: iocbuf.i_clock = sheadp->sh_cltime;
5697: break;
5698:
5699: case I_CANPUT: /* test if band is writeable */
5700: if ((uchar_t) (ulong_t) arg != (ulong_t) arg)
5701: retval = EINVAL;
5702: else
5703: * rvalp = bcanputnext (W (sheadp->sh_head),
5704: (uchar_t) (ulong_t) arg);
5705: break;
5706:
5707: default:
5708: ASSERT (info == & _transparent);
5709:
5710: retval = TRANSPARENT_IOCTL (sheadp, mode, cmd, arg, credp,
5711: rvalp);
5712: break;
5713: }
5714:
5715:
5716: /*
5717: * Perform any necessary unlocking operations and copy back any
5718: * results into the data area pointed to by "arg" (if this is a
5719: * STREAMS-specific ioctl ()).
5720: */
5721:
5722: switch (info->lock) {
5723:
5724: case IO_BASIC_LOCK:
5725: SHEAD_UNLOCK (sheadp, plbase);
5726: break;
5727:
5728: case IO_READFREEZE:
5729: (void) QUNFREEZE_TRACE (sheadp->sh_head, plbase);
5730: break;
5731:
5732: case IO_SLEEP_LOCK:
5733: SHEAD_SLEEP_UNLOCK (sheadp, info->cat);
5734: break;
5735:
5736: default:
5737: break;
5738: }
5739:
5740:
5741: /*
5742: * We only copy out results if there is no error. We have to
5743: * do this *after* unlocking, above; copyout () can block in
5744: * page fault resolution!
5745: */
5746:
5747: if (retval == 0 && info->out_len > 0 &&
5748: copyout (& iocbuf, arg, info->out_len) != 0)
5749: retval = EFAULT;
5750:
5751: return retval;
5752: }
5753:
5754:
5755: /*
5756: * Helper function to atomically read the stream head read options.
5757: */
5758:
5759: #if __USE_PROTO__
5760: __LOCAL__ short (SHEAD_READOPT) (shead_t * sheadp)
5761: #else
5762: __LOCAL__ short
5763: SHEAD_READOPT __ARGS ((sheadp))
5764: shead_t * sheadp;
5765: #endif
5766: {
5767: pl_t prev_pl;
5768: short opt;
5769:
5770: prev_pl = SHEAD_LOCK (sheadp);
5771:
5772: opt = sheadp->sh_readopt;
5773:
5774: SHEAD_UNLOCK (sheadp, prev_pl);
5775:
5776: return opt;
5777: }
5778:
5779:
5780: /*
5781: * Stream head user-level getmsg () processing.
5782: *
5783: * This is way too many parameters; this should be bundled into a block like
5784: * the "uio" structure is.
5785: */
5786:
5787: #if __USE_PROTO__
5788: int (STREAMS_GETPMSG) (shead_t * sheadp, struct strbuf * ctlbuf,
5789: struct strbuf * databuf, int * bandp, int * flagsp,
5790: int mode, int * rvalp)
5791: #else
5792: int
5793: STREAMS_GETPMSG __ARGS ((sheadp, ctlbuf, databuf, bandp, flagsp, mode, rvalp))
5794: shead_t * sheadp;
5795: int mode;
5796: struct strbuf * ctlbuf;
5797: struct strbuf * databuf;
5798: int * bandp;
5799: int * flagsp;
5800: int * rvalp;
5801: #endif
5802: {
5803: mblk_t * msg;
5804: mblk_t * scan;
5805: int retval;
5806:
5807: if ((mode & FREAD) == 0)
5808: return EBADF;
5809:
5810: mode &= ~ FWRITE;
5811:
5812:
5813: /*
5814: * As discussed in the general comment on read synchronization and in
5815: * the I_PEEK documentation, there are some warts when it comes to
5816: * read locking. Here we can solve things by dequeueing a message,
5817: * modifying at, and writing it back without worrying about any nasty
5818: * unintended effects.
5819: *
5820: * Because getmsg ()/getpmsg () always honours message boundaries,
5821: * there is no real value in single-threading this.
5822: */
5823:
5824: /*
5825: * Look at the stream head to see if a message is present. Note that
5826: * we freeze the read queue before acquiring the stream head basic
5827: * lock because that's our canonical ordering.
5828: */
5829:
5830: for (;;) {
5831: (void) QFREEZE_TRACE (sheadp->sh_head, "SHEAD_GETPMSG");
5832:
5833: (void) SHEAD_LOCK (sheadp);
5834:
5835: if ((retval = SHEAD_ERRHUP_LOCKED (sheadp, FREAD)) != 0) {
5836:
5837: QUNFREEZE_TRACE (sheadp->sh_head, plbase);
5838: return retval;
5839: }
5840:
5841:
5842: if ((msg = SHEAD_FIRSTMSG (sheadp)) != NULL) {
5843:
5844: switch (msg->b_datap->db_type) {
5845:
5846: case M_DATA:
5847: case M_PROTO:
5848:
5849: if (* flagsp == MSG_HIPRI ||
5850: (* flagsp == MSG_BAND &&
5851: msg->b_band < * bandp)) {
5852:
5853: sheadp->sh_head->q_lastband =
5854: msg->b_band;
5855: msg = NULL;
5856: break;
5857: }
5858:
5859: /* FALL THROUGH */
5860:
5861: case M_PCPROTO:
5862: rmvq (sheadp->sh_head, msg);
5863: break;
5864:
5865: default:
5866: retval = EBADMSG;
5867: break;
5868: }
5869: }
5870:
5871: QUNFREEZE_TRACE (sheadp->sh_head, plbase);
5872:
5873: if (retval != 0)
5874: return retval;
5875:
5876: if (msg != NULL)
5877: break;
5878:
5879: /*
5880: * We need to wait (unless O_NDELAY or O_NONBLOCK has been
5881: * specified). We don't wait any more if the stream has been
5882: * hung up.
5883: */
5884:
5885: if (SHEAD_HANGUP (sheadp)) {
5886: /*
5887: * Hangups are not an error for getpmsg ().
5888: */
5889:
5890: if (ctlbuf != NULL)
5891: ctlbuf->len = 0;
5892: if (databuf != NULL)
5893: databuf->len = 0;
5894:
5895: * rvalp = 0;
5896: return 0;
5897: }
5898:
5899: if ((retval = SHEAD_WAIT_NONBLOCK (sheadp, FREAD,
5900: SH_READ_WAIT,
5901: CHECK_SIGNALS)) != 0)
5902: return retval;
5903: }
5904:
5905:
5906: /*
5907: * After this point, "msg" is our responsibility and we either have to
5908: * free it or put it back if there is an error.
5909: */
5910:
5911: * bandp = msg->b_band;
5912: * flagsp = msg->b_datap->db_type == M_PCPROTO ? MSG_HIPRI : MSG_BAND;
5913:
5914: retval = (COPYOUT_BUF (ctlbuf, & msg, CONTROL_PART) != 0 ||
5915: COPYOUT_BUF (databuf, & msg,
5916: DATA_PART) != 0) ? EFAULT : 0;
5917:
5918: /*
5919: * Formulate a return mask indicating what components of the message
5920: * being transferred have not been fully consumed.
5921: */
5922:
5923: * rvalp = 0;
5924:
5925: for (scan = msg ; scan != NULL ; scan = scan->b_cont)
5926: * rvalp |= scan->b_datap->db_type == M_DATA ? MOREDATA
5927: : MORECTL;
5928:
5929: if (msg != NULL)
5930: putbq (sheadp->sh_head, msg);
5931:
5932: return retval;
5933: }
5934:
5935:
5936: /*
5937: * In order to keep the logic of SHEAD_READ () manageable, this section of
5938: * code has been factored into a separate function. Here we wait for data to
5939: * become available at the stream head for reading.
5940: *
5941: * We return 0 on success, or an error number on failure. The value of "mpp"
5942: * is only valid if 0 is returned.
5943: */
5944:
5945: #if __USE_PROTO__
5946: __LOCAL__ int (SHEAD_READ_DATA) (shead_t * sheadp, int mode, mblk_t ** mpp,
5947: int resid)
5948: #else
5949: __LOCAL__ int
5950: SHEAD_READ_DATA __ARGS ((sheadp, mode, mpp, resid))
5951: shead_t * sheadp;
5952: int mode;
5953: mblk_t ** mpp;
5954: int resid;
5955: #endif
5956: {
5957: int retval;
5958:
5959: for (;;) {
5960: (void) QFREEZE_TRACE (sheadp->sh_head, "SHEAD_READ");
5961:
5962: (void) SHEAD_LOCK (sheadp);
5963:
5964: if ((retval = SHEAD_ERRHUP_LOCKED (sheadp, FREAD)) != 0) {
5965:
5966: QUNFREEZE_TRACE (sheadp->sh_head, plbase);
5967: return retval;
5968: }
5969:
5970:
5971: if ((* mpp = SHEAD_FIRSTMSG (sheadp)) != NULL) {
5972:
5973: switch ((* mpp)->b_datap->db_type) {
5974:
5975: case M_PROTO:
5976: case M_PCPROTO:
5977: /*
5978: * These are valid depending on the read mode
5979: * of the stream.
5980: */
5981:
5982: if ((sheadp->sh_readopt & RPROTNORM) != 0) {
5983:
5984: retval = EBADMSG;
5985: break;
5986: }
5987:
5988: /* FALL THROUGH */
5989:
5990: case M_DATA:
5991: rmvq (sheadp->sh_head, * mpp);
5992: break;
5993:
5994: default:
5995: retval = EBADMSG;
5996: break;
5997: }
5998: }
5999:
6000: QUNFREEZE_TRACE (sheadp->sh_head, plbase);
6001:
6002: if (retval != 0 || * mpp != NULL) {
6003:
6004: SHEAD_UNLOCK (sheadp, plbase);
6005: return retval;
6006: }
6007:
6008:
6009: /*
6010: * Since we are going to sleep on a read (), this is the place
6011: * to generate M_READ messages if that is how this stream has
6012: * been configured.
6013: *
6014: * If we can't generate an M_READ message, schedule a bufcall.
6015: * If we can't do that, return EAGAIN???
6016: */
6017:
6018: if (SHEAD_READMSG (sheadp)) {
6019: mblk_t * msg;
6020:
6021: if ((msg = MSGB_ALLOC (sizeof (int), BPRI_LO,
6022: KM_NOSLEEP)) == NULL) {
6023: /*
6024: * Execute a short wait for buffer memory for
6025: * the M_READ, then retry the loop. Note that
6026: * SHEAD_READ_BUFCALL () unlocks the stream
6027: * head for us.
6028: */
6029:
6030: if ((retval = SHEAD_READ_BUFCALL (sheadp,
6031: mode)) != 0)
6032: return retval;
6033:
6034: continue;
6035: }
6036:
6037: msg->b_datap->db_type = M_READ;
6038: * (int *) msg->b_rptr = resid;
6039: msg->b_wptr += sizeof (int);
6040:
6041: putq (W (sheadp->sh_head), msg);
6042: }
6043:
6044: if ((retval = SHEAD_WAIT_NONBLOCK (sheadp, mode, SH_READ_WAIT,
6045: CHECK_SIGNALS)) != 0)
6046: return retval;
6047: }
6048:
6049: }
6050:
6051:
6052: /*
6053: * In order to keep the logic of SHEAD_READ () manageable, this section of
6054: * code has been factored into this routine, which manages the transfer of
6055: * message data to the user.
6056: *
6057: * We return EAGAIN to the user if more data needs to be read, 0 if the read
6058: * has successfully completed, or some other error number on failure.
6059: */
6060:
6061: #if __USE_PROTO__
6062: __LOCAL__ int (SHEAD_READ_MOVE) (shead_t * sheadp, uio_t * uiop,
6063: mblk_t * msg)
6064: #else
6065: __LOCAL__ int
6066: SHEAD_READ_MOVE __ARGS ((sheadp, uiop, msg))
6067: shead_t * sheadp;
6068: uio_t * uiop;
6069: mblk_t * msg;
6070: #endif
6071: {
6072: int readopt = SHEAD_READOPT (sheadp);
6073: mblk_t * scan;
6074:
6075: if ((readopt & RMODEMASK) == RNORM &&
6076: (msg->b_cont == NULL && msg->b_rptr == msg->b_wptr)) {
6077: /*
6078: * We have run into a zero-length message. Put it
6079: * back and terminate the read.
6080: */
6081:
6082: putbq (sheadp->sh_head, msg);
6083: return 0;
6084: }
6085:
6086: if ((readopt & RPROTDIS) != 0) {
6087:
6088: while (msg != NULL && msg->b_datap->db_type != M_DATA) {
6089: /*
6090: * Consume the control part of the message.
6091: */
6092:
6093: scan = msg->b_cont;
6094: freeb (msg);
6095: msg = scan;
6096: }
6097:
6098: if (msg == NULL)
6099: return EAGAIN;
6100: }
6101:
6102:
6103: /*
6104: * Actual data transfer time; copy each message segment to the user
6105: * with uiomove ().
6106: */
6107:
6108: do {
6109: size_t unit = msg->b_wptr - msg->b_rptr;
6110:
6111: if (unit > uiop->uio_resid)
6112: unit = uiop->uio_resid;
6113:
6114: if (unit > 0 &&
6115: uiomove (msg->b_rptr, unit, UIO_READ, uiop) != 0) {
6116: /*
6117: * Address fault time. But first, put back the data.
6118: */
6119:
6120: putbq (sheadp->sh_head, msg);
6121:
6122: return EFAULT;
6123: }
6124:
6125: msg->b_rptr += unit;
6126:
6127: if (msg->b_wptr != msg->b_rptr) {
6128: /*
6129: * Since we didn't finish this message block, we must
6130: * be finished with the read (). If we are in message-
6131: * discard mode we throw away the remaining data.
6132: */
6133:
6134: ASSERT (uiop->uio_resid == 0);
6135:
6136: if ((readopt & RMODEMASK) == RMSGD)
6137: freemsg (msg);
6138: else
6139: putbq (sheadp->sh_head, msg);
6140:
6141: return 0;
6142: }
6143:
6144: scan = msg->b_cont;
6145: freeb (msg);
6146: } while ((msg = scan) != NULL);
6147:
6148:
6149: /*
6150: * We have run out of message; what now? If in byte-stream mode, look
6151: * for more data, otherwise exit.
6152: */
6153:
6154: return (readopt & RMODEMASK) == RNORM ? EAGAIN : 0;
6155: }
6156:
6157:
6158: /*
6159: * Stream head user-level read processing.
6160: *
6161: * I apologise for the abysmal structure of this code; the gotos should be
6162: * replaced by proper loops and the major subsections factored into auxiliary
6163: * functions, but this code is the victim of time pressure and several
6164: * rewrites. By all means encourage the author to improve this in case he has
6165: * forgotten to come back and fix it.
6166: */
6167:
6168: #if __USE_PROTO__
6169: int (STREAMS_READ) (shead_t * sheadp, uio_t * uiop)
6170: #else
6171: int
6172: STREAMS_READ __ARGS ((sheadp, uiop))
6173: shead_t * sheadp;
6174: uio_t * uiop;
6175: #endif
6176: {
6177: mblk_t * msg;
6178: int retval;
6179: int mode;
6180: int readcount = uiop->uio_resid;
6181:
6182: if ((uiop->uio_fmode & FREAD) == 0)
6183: return EBADF;
6184:
6185: mode = uiop->uio_fmode & ~ FWRITE;
6186:
6187:
6188: /*
6189: * We (optionally) take out a lock on the stream head to single-thread
6190: * reads. This is important because in byte-stream mode we may want
6191: * to guarantee atomicity of reads. This is only relevant to byte-
6192: * stream mode because modes which honor message boundaries cannot
6193: * be protected against multiple readers anyway.
6194: */
6195:
6196: if ((retval = SHEAD_SLEEP_LOCK (sheadp, SH_READ_LOCK, 0,
6197: CHECK_SIGNALS)) != 0)
6198: return retval;
6199:
6200: do {
6201: if ((retval = SHEAD_READ_DATA (sheadp, mode, & msg,
6202: uiop->uio_resid)) != 0)
6203: break;
6204:
6205: /*
6206: * After this point, "msg" is our responsibility and we either
6207: * have to free it or put it back if there is an error.
6208: */
6209:
6210: } while ((retval = SHEAD_READ_MOVE (sheadp, uiop, msg)) == EAGAIN);
6211:
6212:
6213: /*
6214: * If a partial read has been done, we return a short read rather than
6215: * reporting an error immediately.
6216: */
6217:
6218: if (retval != 0 && readcount != uiop->uio_resid)
6219: retval = 0;
6220:
6221: SHEAD_SLEEP_UNLOCK (sheadp, SH_READ_LOCK);
6222: return retval;
6223: }
6224:
6225:
6226: /*
6227: * Helper function to atomically read the stream head write options.
6228: */
6229:
6230: #if __USE_PROTO__
6231: __LOCAL__ short (SHEAD_WRITEOPT) (shead_t * sheadp)
6232: #else
6233: __LOCAL__ short
6234: SHEAD_WRITEOPT __ARGS ((sheadp))
6235: shead_t * sheadp;
6236: #endif
6237: {
6238: pl_t prev_pl;
6239: short opt;
6240:
6241: prev_pl = SHEAD_LOCK (sheadp);
6242:
6243: opt = sheadp->sh_wropt;
6244:
6245: SHEAD_UNLOCK (sheadp, prev_pl);
6246:
6247: return opt;
6248: }
6249:
6250:
6251: /*
6252: * Stream head user level putpmsg () processing. As with getmsg (), there are
6253: * enough parameters being passed that this should be abstracted into a
6254: * structure like uio(D4DK).
6255: */
6256:
6257: #if __USE_PROTO__
6258: int (STREAMS_PUTPMSG) (shead_t * sheadp, struct strbuf * ctlbuf,
6259: struct strbuf * databuf, int band, int flags,
6260: int mode, int * rvalp)
6261: #else
6262: int
6263: STREAMS_PUTPMSG __ARGS ((sheadp, ctlbuf, databuf, band, flags, mode, rvalp))
6264: shead_t * sheadp;
6265: int mode;
6266: struct strbuf * ctlbuf;
6267: struct strbuf * databuf;
6268: int band;
6269: int flags;
6270: int * rvalp;
6271: #endif
6272: {
6273: mblk_t * msg;
6274: int retval;
6275:
6276: /*
6277: * Make a message (possibly high-priority). This can fail if the
6278: * requested message is too large for the advertised limits set by the
6279: * next thing downstream. SHEAD_MAKEMSG () also checks for error and
6280: * hangup conditions, FNDELAY/FNONBLOCK, and flow control.
6281: */
6282:
6283: msg = SHEAD_MAKEMSG (sheadp, mode, ctlbuf, databuf, flags, band,
6284: & retval);
6285:
6286: if (msg == NULL)
6287: return retval;
6288:
6289: /*
6290: * Note that we don't recheck for hangups even though we could have
6291: * waited a poentially long time in SHEAD_MAKEMSG (). The hangup
6292: * condition has plenty of slop in it with the time it takes write
6293: * messages to move down the queue anyway; drivers and modules have to
6294: * be able to cope.
6295: */
6296:
6297: putq (W (sheadp->sh_head), msg);
6298:
6299: * rvalp = 0;
6300: return 0;
6301: }
6302:
6303:
6304: /*
6305: * Stream head user-level write processing.
6306: *
6307: * I apologise for the abysmal structure of this code; the gotos should be
6308: * replaced by proper loops and the major subsections factored into auxiliary
6309: * functions, but this code is the victim of time pressure and several
6310: * rewrites. By all means encourage the author to improve this in case he has
6311: * forgotten to come back and fix it.
6312: */
6313:
6314: #if __USE_PROTO__
6315: int (STREAMS_WRITE) (shead_t * sheadp, uio_t * uiop)
6316: #else
6317: int
6318: STREAMS_WRITE __ARGS ((sheadp, uiop))
6319: shead_t * sheadp;
6320: uio_t * uiop;
6321: #endif
6322: {
6323: queue_t * q;
6324: short wropt = SHEAD_WRITEOPT (sheadp);
6325: mblk_t * datamsg;
6326: int datasize;
6327: int wroff;
6328: int retval;
6329: int mode;
6330: int writecount;
6331:
6332: if ((uiop->uio_fmode & FWRITE) == 0)
6333: return EBADF;
6334:
6335: mode = uiop->uio_fmode & ~ FREAD;
6336:
6337:
6338: /*
6339: * Deal with the zero-length-message special case.
6340: */
6341:
6342: if ((writecount = uiop->uio_resid) == 0 && (wropt & SNDZERO) == 0)
6343: return 0;
6344:
6345: /*
6346: * Unlike putmsg ()/putpmsg (), write () can potentially spread the
6347: * data it writes over multiple messages and take a considerable time
6348: * to do it, we allow for the possibility of locking the stream head
6349: * so that only one write () is in progress at any time.
6350: *
6351: * The primary purpose of this is to allow PIPE_BUF to be effectively
6352: * unlimited. This is an experimental idea, though.
6353: */
6354:
6355: if ((retval = SHEAD_SLEEP_LOCK (sheadp, SH_WRITE_LOCK, 0,
6356: CHECK_SIGNALS)) != 0)
6357: return retval;
6358:
6359: wroff = SHEAD_WRITEOFFSET (sheadp);
6360:
6361: q = TOP_QUEUE (sheadp);
6362:
6363: do {
6364:
6365: if ((datasize = uiop->uio_resid) + wroff > q->q_maxpsz) {
6366: /*
6367: * Special case (documented on the write (2) manual
6368: * page; if we can't fit within the max/min range and
6369: * the minimum is greater than 0, return ERANGE.
6370: */
6371:
6372: if (q->q_minpsz > 0) {
6373:
6374: retval = ERANGE;
6375: break;
6376: }
6377:
6378: datasize = q->q_maxpsz - wroff;
6379: } else if (datasize + wroff < q->q_minpsz) {
6380:
6381: retval = ERANGE;
6382: break;
6383: }
6384:
6385:
6386: /*
6387: * Let's see if the stream is flow controlled; if it is, we
6388: * either block or return EAGAIN depending on the
6389: * FNDELAY/FNONBLOCK setting.
6390: */
6391:
6392: if ((retval = SHEAD_WRITE_TEST (sheadp, mode, 0, 0)) != 0)
6393: break;
6394:
6395: if ((datamsg = MSGB_ALLOC (datasize + wroff, BPRI_LO,
6396: KM_SLEEP)) == NULL) {
6397: retval = ENOSR;
6398: break;
6399: }
6400:
6401: datamsg->b_wptr = datamsg->b_rptr = datamsg->b_rptr + wroff;
6402:
6403: if (datasize > 0 &&
6404: uiomove (datamsg->b_rptr, datasize, UIO_WRITE,
6405: uiop) != 0) {
6406:
6407: freemsg (datamsg);
6408:
6409: retval = EFAULT;
6410: break;
6411: }
6412:
6413: datamsg->b_wptr += datasize;
6414:
6415: /*
6416: * Now do the write, and see if there is more data.
6417: */
6418:
6419: putq (W (sheadp->sh_head), datamsg);
6420:
6421: } while (uiop->uio_resid > 0);
6422:
6423:
6424: /*
6425: * If there has been an error after some data was actually written
6426: * we return a short read rather than report the error immediately.
6427: */
6428:
6429: if (retval != 0 && uiop->uio_resid != writecount)
6430: retval = 0;
6431:
6432: SHEAD_SLEEP_UNLOCK (sheadp, SH_WRITE_LOCK);
6433: return retval;
6434: }
6435:
6436:
6437: /*
6438: * Stream head user-level open processing.
6439: */
6440:
6441: extern struct streamtab headinfo;
6442:
6443: #if __USE_PROTO__
6444: int (STREAMS_OPEN) (n_dev_t * devp, struct streamtab * stabp, int mode,
6445: cred_t * credp)
6446: #else
6447: int
6448: STREAMS_OPEN (devp, stabp, mode, credp)
6449: n_dev_t * devp;
6450: struct streamtab
6451: * stabp;
6452: int mode;
6453: cred_t * credp;
6454: #endif
6455: {
6456: shead_t * sheadp;
6457: queue_t * q;
6458: int retval;
6459: n_dev_t dev;
6460:
6461: ASSERT (devp != NULL);
6462: ASSERT (stabp != NULL);
6463: ASSERT (credp != NULL);
6464:
6465:
6466: dev = * devp;
6467:
6468: if ((sheadp = SHEAD_OPEN_LOCK (* devp, stabp, & retval)) == NULL)
6469: return retval;
6470:
6471: /*
6472: * If this is the first open of the stream, set up the stream head
6473: * entry points and the driver entry points.
6474: */
6475:
6476: q = W (sheadp->sh_head)->q_next;
6477:
6478: if (sheadp->sh_open_count == 0) {
6479:
6480: QUEUE_INIT (sheadp->sh_head, & headinfo, QI_NORMAL);
6481: qprocson (sheadp->sh_head);
6482:
6483: QUEUE_INIT (R (q), stabp, QI_NORMAL);
6484: }
6485:
6486:
6487: /*
6488: * Now we have a stream head (locked, no less), we can call the open
6489: * entry points of all the modules and the driver. In the special case
6490: * where the open count of the entry is 0, we allow the driver to
6491: * change the "dev_t" value to a previously unused number.
6492: */
6493:
6494: do {
6495: retval = (* R (q)->q_qinfo->qi_qopen)
6496: (R (q), & dev, mode,
6497: q->q_next == NULL ? 0 : MODOPEN, credp);
6498:
6499: if (dev != * devp && q->q_next != NULL) {
6500: /*
6501: * A module has changed the device number that we
6502: * passed a pointer to. This is not valid!
6503: */
6504:
6505: cmn_err (CE_WARN, "Module \"%s\" changed its device number",
6506: q->q_qinfo->qi_minfo->mi_idname);
6507: retval = ENXIO;
6508: }
6509:
6510: if (retval != 0)
6511: goto failure;
6512: } while ((q = q->q_next) != NULL);
6513:
6514:
6515: /*
6516: * The modules and driver have all OK'ed the open, so increment the
6517: * open count. Here we also check for the clone case.
6518: *
6519: * If we want to detect an error after this point, we should execute
6520: * a close.
6521: */
6522:
6523: sheadp->sh_open_count ++;
6524:
6525: if (dev != * devp) {
6526: /*
6527: * The driver has requested that the device number of the
6528: * queue be assigned differently than the initial device
6529: * number. This is only really valid if this is the first open
6530: * of the given queue.
6531: */
6532:
6533: if (sheadp->sh_open_count > 1) {
6534:
6535: cmn_err (CE_WARN, "Driver \"%s\" changed its device number after inital open",
6536: q->q_qinfo->qi_minfo->mi_idname);
6537:
6538: sheadp->sh_open_count --;
6539:
6540: retval = ENXIO;
6541: goto failure;
6542: }
6543:
6544:
6545: /*
6546: * Other open attempts may be waiting on the stream head for
6547: * the original device number; they need a wakeup.
6548: */
6549:
6550: if (SHEAD_RENAME (sheadp, dev) != 0) {
6551:
6552: cmn_err (CE_WARN, "Clone device number chosen by driver \"%s\"is in use",
6553: q->q_qinfo->qi_minfo->mi_idname);
6554:
6555: if (-- sheadp->sh_open_count == 0)
6556: SHEAD_DO_CLOSE (sheadp, mode, credp);
6557:
6558: retval = ENXIO;
6559: goto failure;
6560: }
6561:
6562: * devp = dev;
6563: }
6564:
6565: failure:
6566: /*
6567: * The module or driver has failed the open request. We unlock the
6568: * stream head, which may deallocate the stream head if the open count
6569: * is 0.
6570: */
6571:
6572: SHEAD_SLEEP_UNLOCK (sheadp, SH_OPENCLOSE);
6573: return retval;
6574: }
6575:
6576:
6577: /*
6578: * Stream head interface to generic polling.
6579: */
6580:
6581: #if __USE_PROTO__
6582: int (STREAMS_CHPOLL) (shead_t * sheadp, short events, int anyyet,
6583: short * reventsp, struct pollhead ** phpp)
6584: #else
6585: int
6586: STREAMS_CHPOLL __ARGS ((sheadp, events, anyyet, reventsp, phpp))
6587: shead_t * sheadp;
6588: short events;
6589: int anyyet;
6590: short * reventsp;
6591: struct pollhead
6592: ** phpp;
6593: #endif
6594: {
6595: short my_events;
6596:
6597: /*
6598: * The chpoll () entry point uses the POLL... constants rather than
6599: * the S_... constants that I_SETSIG uses. We convert to the S_...
6600: * form for our internal use... see <sys/poll.h>
6601: */
6602:
6603: my_events = (events & (__POLL_INPUT | __POLL_HIPRI | __POLL_OUTPUT |
6604: __POLL_RDNORM | __POLL_OUTPUT |
6605: __POLL_RDBAND | __POLL_WRBAND));
6606:
6607: if ((events & POLLERR) != 0)
6608: my_events = S_ERROR;
6609: if ((events & POLLHUP) != 0)
6610: my_events = S_HANGUP;
6611:
6612: if ((my_events = SHEAD_POLL_CHECK (sheadp, my_events)) == 0) {
6613:
6614: * reventsp = 0;
6615:
6616: if (anyyet == 0)
6617: * phpp = sheadp->sh_pollhead;
6618: } else
6619: * reventsp = my_events;
6620:
6621: return 0;
6622: }
6623:
6624:
6625: /*
6626: * Stream head user-level close processing.
6627: */
6628:
6629: #if __USE_PROTO__
6630: int (STREAMS_CLOSE) (shead_t * sheadp, int mode, cred_t * credp)
6631: #else
6632: int
6633: STREAMS_CLOSE __ARGS ((sheadp, mode, credp))
6634: shead_t * sheadp;
6635: int mode;
6636: cred_t * credp;
6637: #endif
6638: {
6639: int retval;
6640:
6641: if ((retval = SHEAD_SLEEP_LOCK (sheadp, SH_OPENCLOSE | SH_IOCTL_LOCK,
6642: 0, CHECK_SIGNALS)) != 0)
6643: return retval;
6644:
6645: if (-- sheadp->sh_open_count == 0)
6646: SHEAD_DO_CLOSE (sheadp, mode, credp);
6647:
6648: SHEAD_SLEEP_UNLOCK (sheadp, SH_OPENCLOSE | SH_IOCTL_LOCK);
6649:
6650: return 0;
6651: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.