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 /* 32 * This module switches the read and write flush bits for each 33 * M_FLUSH control message it receives. It's intended usage is to 34 * properly flush a STREAMS-based pipe. 35 */ 36 #include <sys/types.h> 37 #include <sys/param.h> 38 #include <sys/errno.h> 39 #include <sys/stream.h> 40 #include <sys/stropts.h> 41 42 #include <sys/conf.h> 43 #include <sys/modctl.h> 44 45 /*ARGSUSED*/ 46 static int 47 pipeopen(queue_t *rqp, dev_t *devp, int flag, int sflag, cred_t *crp) 48 { 49 qprocson(rqp); 50 return (0); 51 } 52 53 /*ARGSUSED*/ 54 static int 55 pipeclose(queue_t *q, int cflag, cred_t *crp) 56 { 57 qprocsoff(q); 58 return (0); 59 } 60 61 /* 62 * Use same put procedure for write and read queues. 63 * If mp is an M_FLUSH message, switch the FLUSHW to FLUSHR and 64 * the FLUSHR to FLUSHW and send the message on. If mp is not an 65 * M_FLUSH message, send it on with out processing. 66 */ 67 static int 68 pipeput(queue_t *qp, mblk_t *mp) 69 { 70 switch (mp->b_datap->db_type) { 71 case M_FLUSH: 72 if (!(*mp->b_rptr & FLUSHR && *mp->b_rptr & FLUSHW)) { 73 if (*mp->b_rptr & FLUSHW) { 74 *mp->b_rptr |= FLUSHR; 75 *mp->b_rptr &= ~FLUSHW; 76 } else { 77 *mp->b_rptr |= FLUSHW; 78 *mp->b_rptr &= ~FLUSHR; 79 } 80 } 81 break; 82 83 default: 84 break; 85 } 86 putnext(qp, mp); 87 return (0); 88 } 89 90 static struct module_info pipe_info = { 91 1003, "pipemod", 0, INFPSZ, STRHIGH, STRLOW 92 }; 93 94 static struct qinit piperinit = { 95 pipeput, NULL, pipeopen, pipeclose, NULL, &pipe_info, NULL 96 }; 97 98 static struct qinit pipewinit = { 99 pipeput, NULL, NULL, NULL, NULL, &pipe_info, NULL 100 }; 101 102 static struct streamtab pipeinfo = { &piperinit, &pipewinit, NULL, NULL }; 103 104 static struct fmodsw fsw = { 105 "pipemod", 106 &pipeinfo, 107 D_NEW | D_MP 108 }; 109 110 static struct modlstrmod modlstrmod = { 111 &mod_strmodops, "pipe flushing module", &fsw 112 }; 113 114 static struct modlinkage modlinkage = { 115 MODREV_1, { &modlstrmod, NULL } 116 }; 117 118 int 119 _init(void) 120 { 121 return (mod_install(&modlinkage)); 122 } 123 124 int 125 _fini(void) 126 { 127 return (mod_remove(&modlinkage)); 128 } 129 130 int 131 _info(struct modinfo *modinfop) 132 { 133 return (mod_info(&modlinkage, modinfop)); 134 }