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