|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1993 Christopher G. Demetriou ! 3: * Copyright (c) 1982, 1986 Regents of the University of California. ! 4: * All rights reserved. ! 5: * ! 6: * Redistribution and use in source and binary forms, with or without ! 7: * modification, are permitted provided that the following conditions ! 8: * are met: ! 9: * 1. Redistributions of source code must retain the above copyright ! 10: * notice, this list of conditions and the following disclaimer. ! 11: * 2. Redistributions in binary form must reproduce the above copyright ! 12: * notice, this list of conditions and the following disclaimer in the ! 13: * documentation and/or other materials provided with the distribution. ! 14: * 3. All advertising materials mentioning features or use of this software ! 15: * must display the following acknowledgement: ! 16: * This product includes software developed by the University of ! 17: * California, Berkeley and its contributors. ! 18: * 4. Neither the name of the University nor the names of its contributors ! 19: * may be used to endorse or promote products derived from this software ! 20: * without specific prior written permission. ! 21: * ! 22: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 25: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 26: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 32: * SUCH DAMAGE. ! 33: * ! 34: * from: @(#)subr_log.c 7.11 (Berkeley) 3/17/91 ! 35: * subr_acct.c,v 1.4 1993/06/30 13:43:03 mycroft Exp ! 36: */ ! 37: ! 38: /* ! 39: * acct buffer for accounting information ! 40: */ ! 41: ! 42: #include "param.h" ! 43: #include "systm.h" ! 44: #include "proc.h" ! 45: #include "vnode.h" ! 46: #include "ioctl.h" ! 47: #include "file.h" ! 48: #include "malloc.h" ! 49: #include "acct.h" ! 50: #include "acctbuf.h" ! 51: #include "select.h" ! 52: ! 53: #define ACCT_RDPRI (PZERO + 1) ! 54: ! 55: #define ACCT_ASYNC 0x04 ! 56: #define ACCT_RDWAIT 0x08 ! 57: ! 58: struct acctsoftc { ! 59: int sc_state; /* see above for possibilities */ ! 60: struct selinfo sc_selp; /* process waiting on select call */ ! 61: int sc_pgid; /* process/group for async I/O */ ! 62: } acctsoftc; ! 63: ! 64: int acct_open; /* also used in acct() */ ! 65: struct acctbuf *acctbufp; /* the accounting buffer pointer */ ! 66: ! 67: /*ARGSUSED*/ ! 68: int ! 69: #ifdef __STDC__ ! 70: acctopen(dev_t dev, int flags, int mode, struct proc *p) ! 71: /* gcc 1.x doesn't like non-ansi def for this */ ! 72: #else ! 73: acctopen() ! 74: dev_t dev; ! 75: int flags, mode; ! 76: struct proc *p; ! 77: #endif ! 78: { ! 79: if (acct_open) ! 80: return (EBUSY); ! 81: acct_open = 1; ! 82: acctsoftc.sc_pgid = p->p_pid; /* signal process only */ ! 83: ! 84: if (acctbufp == NULL) ! 85: acctbuf_init(); ! 86: #ifdef ACCT_DEBUG ! 87: acctbuf_checkbuf("acctopen"); ! 88: #endif ! 89: ! 90: return (0); ! 91: } ! 92: ! 93: /*ARGSUSED*/ ! 94: int ! 95: #ifdef __STDC__ ! 96: acctclose(dev_t dev, int flag) ! 97: /* gcc 1.x doesn't like non-ansi def for this */ ! 98: #else ! 99: acctclose() ! 100: dev_t dev; ! 101: int flag; ! 102: #endif ! 103: { ! 104: acct_open = 0; ! 105: acctsoftc.sc_state = 0; ! 106: bzero(&acctsoftc.sc_selp,sizeof(acctsoftc.sc_selp)); ! 107: ! 108: return 0; ! 109: } ! 110: ! 111: /*ARGSUSED*/ ! 112: int ! 113: #ifdef __STDC__ ! 114: acctread(dev_t dev, struct uio *uio, int flag) ! 115: /* gcc 1.x doesn't like non-ansi def for this */ ! 116: #else ! 117: acctread() ! 118: dev_t dev; ! 119: struct uio *uio; ! 120: int flag; ! 121: #endif ! 122: { ! 123: register struct acctbuf *abp = acctbufp; ! 124: register long l; ! 125: int error = 0; ! 126: ! 127: #ifdef ACCT_DEBUG ! 128: acctbuf_checkbuf("acctread 1"); ! 129: #endif ! 130: while (abp->ab_rind == abp->ab_wind) { ! 131: if (flag & IO_NDELAY) { ! 132: return (EWOULDBLOCK); ! 133: } ! 134: acctsoftc.sc_state |= ACCT_RDWAIT; ! 135: if (error = tsleep((caddr_t)abp, ACCT_RDPRI | PCATCH, ! 136: "acct", 0)) { ! 137: return (error); ! 138: } ! 139: } ! 140: acctsoftc.sc_state &= ~ACCT_RDWAIT; ! 141: ! 142: while (uio->uio_resid > 0) { ! 143: l = abp->ab_wind - abp->ab_rind; ! 144: if (l < 0) ! 145: l = ACCT_NBRECS - abp->ab_rind; ! 146: l = MIN(l, uio->uio_resid / sizeof(struct acct)); ! 147: if (l == 0) ! 148: break; ! 149: error = uiomove((caddr_t)&abp->recs[abp->ab_rind], ! 150: (int)(l * sizeof(struct acct)), uio); ! 151: if (error) ! 152: break; ! 153: abp->ab_rind += l; ! 154: if (abp->ab_rind < 0 || abp->ab_rind >= ACCT_NBRECS) ! 155: abp->ab_rind = 0; ! 156: } ! 157: #ifdef ACCT_DEBUG ! 158: acctbuf_checkbuf("acctread 2"); ! 159: #endif ! 160: return (error); ! 161: } ! 162: ! 163: /*ARGSUSED*/ ! 164: int ! 165: #ifdef __STDC__ ! 166: acctselect(dev_t dev, int rw, struct proc *p) ! 167: /* gcc 1.x doesn't like non-ansi def for this */ ! 168: #else ! 169: acctselect() ! 170: dev_t dev; ! 171: int rw; ! 172: struct proc *p; ! 173: #endif ! 174: { ! 175: switch (rw) { ! 176: ! 177: case FREAD: ! 178: #ifdef ACCT_DEBUG ! 179: acctbuf_checkbuf("acctselect"); ! 180: #endif ! 181: if (acctbufp->ab_rind != acctbufp->ab_wind) { ! 182: return (1); ! 183: } ! 184: selrecord(p, &acctsoftc.sc_selp); ! 185: break; ! 186: } ! 187: return (0); ! 188: } ! 189: ! 190: void ! 191: acctwakeup() ! 192: { ! 193: struct proc *p; ! 194: ! 195: if (!acct_open) ! 196: return; ! 197: selwakeup(&acctsoftc.sc_selp); ! 198: if (acctsoftc.sc_state & ACCT_ASYNC) { ! 199: if (acctsoftc.sc_pgid < 0) ! 200: gsignal(-acctsoftc.sc_pgid, SIGIO); ! 201: else if (p = pfind(acctsoftc.sc_pgid)) ! 202: psignal(p, SIGIO); ! 203: } ! 204: if (acctsoftc.sc_state & ACCT_RDWAIT) { ! 205: wakeup((caddr_t)acctbufp); ! 206: acctsoftc.sc_state &= ~ACCT_RDWAIT; ! 207: } ! 208: } ! 209: ! 210: /*ARGSUSED*/ ! 211: int ! 212: #ifdef __STDC__ ! 213: acctioctl(dev_t dev, int com, caddr_t data, int flag) ! 214: /* gcc 1.x doesn't like non-ansi def for this */ ! 215: #else ! 216: acctioctl() ! 217: dev_t dev; ! 218: int com; ! 219: caddr_t data; ! 220: int flag; ! 221: #endif ! 222: { ! 223: long l; ! 224: ! 225: switch (com) { ! 226: ! 227: /* return number of characters immediately available */ ! 228: case FIONREAD: ! 229: #ifdef ACCT_DEBUG ! 230: acctbuf_checkbuf("acctioctl"); ! 231: #endif ! 232: l = acctbufp->ab_wind - acctbufp->ab_rind; ! 233: if (l < 0) ! 234: l += ACCT_NBRECS; ! 235: *(off_t *)data = l * sizeof(struct acct); ! 236: break; ! 237: ! 238: case FIONBIO: ! 239: break; ! 240: ! 241: case FIOASYNC: ! 242: if (*(int *)data) ! 243: acctsoftc.sc_state |= ACCT_ASYNC; ! 244: else ! 245: acctsoftc.sc_state &= ~ACCT_ASYNC; ! 246: break; ! 247: ! 248: case TIOCSPGRP: ! 249: acctsoftc.sc_pgid = *(int *)data; ! 250: break; ! 251: ! 252: case TIOCGPGRP: ! 253: *(int *)data = acctsoftc.sc_pgid; ! 254: break; ! 255: ! 256: default: ! 257: return (-1); ! 258: } ! 259: return (0); ! 260: } ! 261: ! 262: void ! 263: acctbuf_init() ! 264: { ! 265: if (acctbufp != NULL) ! 266: panic("acctbuf reinit\n"); ! 267: ! 268: acctbufp = malloc(ACCT_BSIZE, M_DEVBUF, M_WAITOK); ! 269: if (acctbufp == NULL) ! 270: panic("acctbuf_init: couldn't allocate accounting buffer\n"); ! 271: ! 272: bzero(acctbufp, ACCT_BSIZE); ! 273: acctbufp->ab_magic = ACCT_MAGIC; ! 274: } ! 275: ! 276: #ifdef ACCT_DEBUG ! 277: void ! 278: acctbuf_checkbuf(char *from) ! 279: { ! 280: char *str; ! 281: int dopanic = 0; ! 282: ! 283: if (acctbufp == NULL) { ! 284: str = "accounting buffer pointer null"; ! 285: dopanic = 1; ! 286: } ! 287: if (acctbufp->ab_magic != ACCT_MAGIC) { ! 288: str = "accounting buffer magic bad"; ! 289: dopanic = 1; ! 290: } ! 291: if (acctbufp->ab_rind < 0 || acctbufp->ab_rind >= ACCT_NBRECS) { ! 292: str = "accounting buffer read index out of range"; ! 293: dopanic = 1; ! 294: } ! 295: if (acctbufp->ab_wind < 0 || acctbufp->ab_wind >= ACCT_NBRECS) { ! 296: str = "accounting buffer write index out of range"; ! 297: dopanic = 1; ! 298: } ! 299: if (dopanic) { ! 300: printf("acctbuf_checkbuf: from %s\n", from); ! 301: panic(str); ! 302: } ! 303: } ! 304: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.