|
|
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.