1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1997, by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* 34 * This module switches the read and write flush bits for each 35 * M_FLUSH control message it receives. It's intended usage is to 36 * properly flush a STREAMS-based pipe. 37 */ 38 #include <sys/types.h> 39 #include <sys/param.h> 40 #include <sys/errno.h> 41 #include <sys/stream.h> 42 #include <sys/stropts.h> 43 44 #include <sys/conf.h> 45 #include <sys/modctl.h> 46 47 /*ARGSUSED*/ 48 static int 49 pipeopen(queue_t *rqp, dev_t *devp, int flag, int sflag, cred_t *crp) 50 { 51 qprocson(rqp); 52 return (0); 53 } 54 55 /*ARGSUSED*/ 56 static int 57 pipeclose(queue_t *q, int cflag, cred_t *crp) 58 { 59 qprocsoff(q); 60 return (0); 61 } 62 63 /* 64 * Use same put procedure for write and read queues. 65 * If mp is an M_FLUSH message, switch the FLUSHW to FLUSHR and 66 * the FLUSHR to FLUSHW and send the message on. If mp is not an 67 * M_FLUSH message, send it on with out processing. 68 */ 69 static int 70 pipeput(queue_t *qp, mblk_t *mp) 71 { 72 switch (mp->b_datap->db_type) { 73 case M_FLUSH: 74 if (!(*mp->b_rptr & FLUSHR && *mp->b_rptr & FLUSHW)) { 75 if (*mp->b_rptr & FLUSHW) { 76 *mp->b_rptr |= FLUSHR; 77 *mp->b_rptr &= ~FLUSHW; 78 } else { 79 *mp->b_rptr |= FLUSHW; 80 *mp->b_rptr &= ~FLUSHR; 81 } 82 } 83 break; 84 85 default: 86 break; 87 } 88 putnext(qp, mp); 89 return (0); 90 } 91 92 static struct module_info pipe_info = { 93 1003, "pipemod", 0, INFPSZ, STRHIGH, STRLOW 94 }; 95 96 static struct qinit piperinit = { 97 pipeput, NULL, pipeopen, pipeclose, NULL, &pipe_info, NULL 98 }; 99 100 static struct qinit pipewinit = { 101 pipeput, NULL, NULL, NULL, NULL, &pipe_info, NULL 102 }; 103 104 static struct streamtab pipeinfo = { &piperinit, &pipewinit, NULL, NULL }; 105 106 static struct fmodsw fsw = { 107 "pipemod", 108 &pipeinfo, 109 D_NEW | D_MP 110 }; 111 112 static struct modlstrmod modlstrmod = { 113 &mod_strmodops, "pipe flushing module", &fsw 114 }; 115 116 static struct modlinkage modlinkage = { 117 MODREV_1, &modlstrmod, NULL 118 }; 119 120 int 121 _init(void) 122 { 123 return (mod_install(&modlinkage)); 124 } 125 126 int 127 _fini(void) 128 { 129 return (mod_remove(&modlinkage)); 130 } 131 132 int 133 _info(struct modinfo *modinfop) 134 { 135 return (mod_info(&modlinkage, modinfop)); 136 }