|
|
1.1 ! root 1: /* ! 2: char id_tapeio[] = "@(#)tapeio.c 1.2"; ! 3: * ! 4: * tapeio - tape device specific I/O routines ! 5: * ! 6: * ierr = topen (tlu, name, labelled) ! 7: * ierr = tclose (tlu) ! 8: * nbytes = tread (tlu, buffer) ! 9: * nbytes = twrite (tlu, buffer) ! 10: * ierr = trewin (tlu) ! 11: * ierr = tskipf (tlu, nfiles, nrecs) ! 12: * ierr = tstate (tlu, fileno, recno, err, eof, eot, tcsr) ! 13: */ ! 14: ! 15: #include <ctype.h> ! 16: #include <sys/ioctl.h> ! 17: #ifndef MTIOCGET /* 4.1+ defines this in ... */ ! 18: #include <sys/types.h> ! 19: #include <sys/mtio.h> ! 20: #endif ! 21: #include "../libI77/f_errno.h" ! 22: ! 23: #define TU_NAMESIZE 22 ! 24: #define TU_MAXTAPES 4 ! 25: ! 26: struct tunits { ! 27: char tu_name[TU_NAMESIZE]; /* device name */ ! 28: int tu_fd; /* file descriptor */ ! 29: int tu_flags; /* state flags */ ! 30: int tu_file; /* current tape file number */ ! 31: int tu_rec; /* current record number in file */ ! 32: } tunits[TU_MAXTAPES]; ! 33: ! 34: #define TU_OPEN 0x1 ! 35: #define TU_EOF 0x2 ! 36: #define TU_ERR 0x4 ! 37: #define TU_READONLY 0x8 ! 38: #define TU_LABELLED 0x10 ! 39: #define TU_WRITING 0x20 ! 40: #define TU_EOT 0x40 ! 41: #define TU_RDATA 0x80 ! 42: ! 43: #ifdef MTWEOF /* this implies 4.1+ ... */ ! 44: struct mtget mtget; /* controller status */ ! 45: #endif ! 46: ! 47: /* ! 48: * Open a tape unit for I/O ! 49: * ! 50: * calling format: ! 51: * integer topen, tlu ! 52: * character*(*) devnam ! 53: * logical labled ! 54: * ierror = topen(tlu, devnam, labled) ! 55: * where: ! 56: * ierror will be 0 for successful open; an error number otherwise. ! 57: * devnam is a character string ! 58: * labled should be .true. if the tape is labelled. ! 59: */ ! 60: ! 61: long ! 62: topen_(tlu, name, labelled, len) ! 63: long *tlu; ! 64: char *name; ! 65: long *labelled; ! 66: long len; ! 67: { ! 68: struct tunits *tu; ! 69: ! 70: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 71: errno = F_ERUNIT; ! 72: return(-1L); ! 73: } ! 74: ! 75: tu = &tunits[*tlu]; ! 76: if (tu->tu_flags & TU_OPEN) ! 77: tclose_(tlu); ! 78: ! 79: if (len >= TU_NAMESIZE) { ! 80: errno = F_ERARG; ! 81: return(-1L); ! 82: } ! 83: ! 84: g_char(name, len, tu->tu_name); ! 85: ! 86: if ((tu->tu_fd = open(tu->tu_name, 2)) < 0) { ! 87: if ((tu->tu_fd = open(tu->tu_name, 0)) < 0) ! 88: return(-1L); ! 89: tu->tu_flags |= TU_READONLY; ! 90: } ! 91: tu->tu_flags |= TU_OPEN; ! 92: tu->tu_file = tu->tu_rec = 0; ! 93: if (*labelled) ! 94: tu->tu_flags |= TU_LABELLED; ! 95: return(0L); ! 96: } ! 97: ! 98: /* ! 99: * Close a tape unit previously opened by topen_() ! 100: * ! 101: * calling sequence: ! 102: * integer tlu, tclose ! 103: * ierrno = tclose(tlu) ! 104: * where: ! 105: * tlu is a previously topened tape logical unit. ! 106: */ ! 107: ! 108: long ! 109: tclose_(tlu) ! 110: long *tlu; ! 111: { ! 112: struct tunits *tu; ! 113: ! 114: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 115: errno = F_ERUNIT; ! 116: return(-1L); ! 117: } ! 118: ! 119: tu = &tunits[*tlu]; ! 120: if (!(tu->tu_flags & TU_OPEN)) ! 121: return(0L); ! 122: ! 123: tu->tu_flags = 0; ! 124: if (close(tu->tu_fd) < 0) ! 125: return(-1L); ! 126: return(0L); ! 127: } ! 128: ! 129: /* ! 130: * Read from a tape logical unit ! 131: * ! 132: * calling sequence: ! 133: * integer tread, tlu ! 134: * character*(*) buffer ! 135: * ierr = tread(tlu, buffer) ! 136: */ ! 137: ! 138: long ! 139: tread_(tlu, buffer, len) ! 140: long *tlu; ! 141: char *buffer; ! 142: long len; ! 143: { ! 144: struct tunits *tu; ! 145: int nbytes; ! 146: ! 147: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 148: errno = F_ERUNIT; ! 149: return(-1L); ! 150: } ! 151: ! 152: tu = &tunits[*tlu]; ! 153: if (!(tu->tu_flags & TU_OPEN)) { ! 154: errno = F_ERNOPEN; ! 155: return(-1L); ! 156: } ! 157: if (tu->tu_flags & TU_WRITING) { ! 158: errno = F_ERILLOP; ! 159: return(-1L); ! 160: } ! 161: if (tu->tu_flags & (TU_EOF|TU_EOT)) ! 162: return(0L); ! 163: ! 164: if ((nbytes = read(tu->tu_fd, buffer, (int)len)) > 0) ! 165: tu->tu_flags |= TU_RDATA; ! 166: ! 167: if (nbytes == 0 && len != 0) { ! 168: tu->tu_flags |= TU_EOF; ! 169: if (tu->tu_rec == 0) ! 170: tu->tu_flags |= TU_EOT; ! 171: } ! 172: if (nbytes < 0) ! 173: tu->tu_flags |= TU_ERR; ! 174: else ! 175: tu->tu_rec++; ! 176: ! 177: return((long)nbytes); ! 178: } ! 179: ! 180: /* ! 181: * Write to a tape logical unit ! 182: * ! 183: * calling sequence: ! 184: * integer twrite, tlu ! 185: * character*(*) buffer ! 186: * ierr = twrite(tlu, buffer) ! 187: */ ! 188: ! 189: long ! 190: twrite_(tlu, buffer, len) ! 191: long *tlu; ! 192: char *buffer; ! 193: long len; ! 194: { ! 195: struct tunits *tu; ! 196: int nbytes; ! 197: long nf; ! 198: long zero = 0L; ! 199: ! 200: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 201: errno = F_ERUNIT; ! 202: return(-1L); ! 203: } ! 204: ! 205: tu = &tunits[*tlu]; ! 206: if (!(tu->tu_flags & TU_OPEN)) { ! 207: errno = F_ERNOPEN; ! 208: return(-1L); ! 209: } ! 210: if (tu->tu_flags & TU_READONLY) { ! 211: errno = F_ERILLOP; ! 212: return(-1L); ! 213: } ! 214: ! 215: if (tu->tu_flags & TU_EOT) { /* must backspace over last EOF */ ! 216: nf = (long)tu->tu_file; /* should be number to skip */ ! 217: trewin_(tlu); /* KLUDGE!! */ ! 218: tskipf_(tlu, &nf, &zero); ! 219: } ! 220: ! 221: nbytes = write(tu->tu_fd, buffer, (int)len); ! 222: if (nbytes <= 0) ! 223: tu->tu_flags |= TU_ERR; ! 224: tu->tu_rec++; ! 225: tu->tu_flags |= TU_WRITING; ! 226: tu->tu_flags &= ~(TU_EOF|TU_EOT|TU_RDATA); ! 227: return((long)nbytes); ! 228: } ! 229: ! 230: /* ! 231: * rewind a tape device ! 232: */ ! 233: ! 234: long ! 235: trewin_(tlu) ! 236: long *tlu; ! 237: { ! 238: struct tunits *tu; ! 239: char namebuf[TU_NAMESIZE]; ! 240: register char *p, *q; ! 241: int munit; ! 242: int rfd; ! 243: long labelled; ! 244: long one = 1L; ! 245: long zero = 0L; ! 246: int save_errno; ! 247: ! 248: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 249: errno = F_ERUNIT; ! 250: return(-1L); ! 251: } ! 252: ! 253: tu = &tunits[*tlu]; ! 254: if (!(tu->tu_flags & TU_OPEN)) { ! 255: errno = F_ERNOPEN; ! 256: return(-1L); ! 257: } ! 258: labelled = (tu->tu_flags & TU_LABELLED); ! 259: tclose_(tlu); ! 260: ! 261: for (p = tu->tu_name, q = namebuf; *p; p++) { ! 262: if (*p == 'n') /* norewind name */ ! 263: continue; ! 264: if (isdigit(*p)) { /* might be norewind minor dev */ ! 265: munit = 0; ! 266: while (isdigit(*p)) ! 267: munit = (10 * munit) + (*p++ - '0'); ! 268: *q++ = (munit & 03) + '0'; ! 269: while (*p) ! 270: *q++ = *p++; ! 271: break; ! 272: } ! 273: *q++ = *p; ! 274: } ! 275: *q = '\0'; ! 276: /* debug printf("rewinding [%s]\n", namebuf); /* */ ! 277: ! 278: if ((rfd = open(namebuf, 0)) < 0) ! 279: save_errno = errno; ! 280: else { ! 281: save_errno = 0; ! 282: close(rfd); ! 283: } ! 284: ! 285: topen_(tlu, tu->tu_name, &labelled, (long)strlen(tu->tu_name)); ! 286: if (labelled) { ! 287: tskipf_(tlu, &one, &zero); ! 288: tu->tu_file = 0; ! 289: } ! 290: if (save_errno) { ! 291: errno = save_errno; ! 292: return(-1L); ! 293: } ! 294: return(0L); ! 295: } ! 296: ! 297: /* ! 298: * Skip forward files ! 299: * ! 300: * NOTE: This is a kludge, to be fixed after 4.1a ! 301: */ ! 302: ! 303: long ! 304: tskipf_(tlu, nfiles, nrecs) ! 305: long *tlu; ! 306: long *nfiles; ! 307: long *nrecs; ! 308: { ! 309: struct tunits *tu; ! 310: char dummybuf[20]; ! 311: int nf; ! 312: int nr; ! 313: int nb; ! 314: int empty; ! 315: ! 316: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 317: errno = F_ERUNIT; ! 318: return(-1L); ! 319: } ! 320: ! 321: tu = &tunits[*tlu]; ! 322: if (!(tu->tu_flags & TU_OPEN)) { ! 323: errno = F_ERNOPEN; ! 324: return(-1L); ! 325: } ! 326: if (tu->tu_flags & TU_WRITING) { ! 327: errno = F_ERILLOP; ! 328: return(-1L); ! 329: } ! 330: ! 331: nf = (int)*nfiles; ! 332: while (nf > 0) { ! 333: if (tu->tu_flags & TU_EOT) { ! 334: errno = F_ERILLOP; ! 335: return(-1L); ! 336: } ! 337: if (tu->tu_flags & TU_EOF) ! 338: tu->tu_flags &= ~TU_EOF; ! 339: else { ! 340: empty = ((tu->tu_flags & TU_RDATA) == 0); ! 341: while ((nb = read(tu->tu_fd, dummybuf, sizeof dummybuf)) > 0) ! 342: empty = 0; ! 343: ! 344: if (nb < 0) { ! 345: tu->tu_flags |= TU_ERR; ! 346: return(-1L); ! 347: } ! 348: if (empty) ! 349: tu->tu_flags |= TU_EOT; ! 350: } ! 351: nf--; ! 352: tu->tu_rec = 0; ! 353: tu->tu_flags &= ~TU_RDATA; ! 354: if (tu->tu_flags & TU_EOT) ! 355: return(-1L); ! 356: else ! 357: tu->tu_file++; ! 358: } ! 359: ! 360: nr = (int)*nrecs; ! 361: while (nr > 0) { ! 362: if (tu->tu_flags & (TU_EOT|TU_EOF)) { ! 363: errno = F_ERILLOP; ! 364: return(-1L); ! 365: } ! 366: ! 367: empty = ((nb = read(tu->tu_fd, dummybuf, sizeof dummybuf)) <= 0); ! 368: if (nb < 0) { ! 369: tu->tu_flags |= TU_ERR; ! 370: return(-1L); ! 371: } ! 372: if (empty) { ! 373: tu->tu_flags |= TU_EOF; ! 374: if (!(tu->tu_flags & TU_RDATA)) ! 375: tu->tu_flags |= TU_EOT; ! 376: } else ! 377: tu->tu_flags |= TU_RDATA; ! 378: nr--; ! 379: tu->tu_rec++; ! 380: } ! 381: return(0L); ! 382: } ! 383: ! 384: /* ! 385: * Return status of tape channel ! 386: */ ! 387: ! 388: long ! 389: tstate_(tlu, fileno, recno, err, eof, eot, tcsr) ! 390: long *tlu, *fileno, *recno, *err, *eof, *eot, *tcsr; ! 391: { ! 392: struct tunits *tu; ! 393: int csr; ! 394: ! 395: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 396: errno = F_ERUNIT; ! 397: return(-1L); ! 398: } ! 399: ! 400: tu = &tunits[*tlu]; ! 401: if (!(tu->tu_flags & TU_OPEN)) { ! 402: errno = F_ERNOPEN; ! 403: return(-1L); ! 404: } ! 405: ! 406: *fileno = (long)tu->tu_file; ! 407: *recno = (long)tu->tu_rec; ! 408: *err = (long)((tu->tu_flags & TU_ERR) != 0); ! 409: *eof = (long)((tu->tu_flags & TU_EOF) != 0); ! 410: *eot = (long)((tu->tu_flags & TU_EOT) != 0); ! 411: #ifdef MTWEOF /* implies 4.1+ system */ ! 412: ioctl(tu->tu_fd, MTIOCGET, &mtget); ! 413: *tcsr = (long)mtget.mt_dsreg & 0xffff; ! 414: #else ! 415: ioctl(tu->tu_fd, MTIOCGET, &csr); ! 416: *tcsr = (long)csr; ! 417: #endif ! 418: return(0L); ! 419: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.