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