1: #include "../h/rt.h"
2:
3: /*
4: * open(s1,s2) - open file s1 with specification s2.
5: */
6: Xopen(nargs, arg2, arg1, arg0)
7: int nargs;
8: struct descrip arg2, arg1, arg0;
9: {
10: register int slen, i;
11: register char *s;
12: int status;
13: char sbuf1[MAXSTRING], sbuf2[MAXSTRING], mode[3];
14: FILE *f;
15: extern struct b_file *alcfile();
16: extern char *alcstr();
17: extern FILE *fopen(), *popen();
18:
19: /*
20: * s1 must be a string and a C string copy of it is also needed.
21: * Make it a string if it isn't one; make a C string if s1 is
22: * a string.
23: */
24: switch (cvstr(&arg1, sbuf1)) {
25: case 1:
26: sneed(STRLEN(arg1));
27: STRLOC(arg1) = alcstr(STRLOC(arg1), STRLEN(arg1));
28: break;
29: case 2:
30: qtos(&arg1, sbuf1);
31: break;
32: default:
33: runerr(103, &arg1);
34: }
35: /*
36: * s2 defaults to "r".
37: */
38: defstr(&arg2, sbuf2, &letr);
39:
40: hneed(sizeof(struct b_file));
41: status = 0;
42:
43: /*
44: * Scan s2, setting appropriate bits in status. Produce a runerr
45: * if an unknown character is encountered.
46: */
47: s = STRLOC(arg2);
48: slen = STRLEN(arg2);
49: for (i = 0; i < slen; i++) {
50: switch (*s++) {
51: case 'a': case 'A':
52: status |= FS_WRITE|FS_APPEND;
53: continue;
54: case 'b': case 'B':
55: status |= FS_READ|FS_WRITE;
56: continue;
57: case 'c': case 'C':
58: status |= FS_CREATE|FS_WRITE;
59: continue;
60: case 'p': case 'P':
61: status |= FS_PIPE;
62: continue;
63: case 'r': case 'R':
64: status |= FS_READ;
65: continue;
66: case 'w': case 'W':
67: status |= FS_WRITE;
68: continue;
69: default:
70: runerr(209, &arg2);
71: }
72: }
73:
74: /*
75: * Construct a mode field for fopen/popen.
76: */
77: mode[0] = '\0';
78: mode[1] = '\0';
79: mode[2] = '\0';
80: if ((status & (FS_READ|FS_WRITE)) == 0) /* default: read only */
81: status |= FS_READ;
82: if (status & FS_CREATE)
83: mode[0] = 'w';
84: else if (status & FS_APPEND)
85: mode[0] = 'a';
86: else if (status & FS_READ)
87: mode[0] = 'r';
88: else
89: mode[0] = 'w';
90: if ((status & (FS_READ|FS_WRITE)) == (FS_READ|FS_WRITE))
91: mode[1] = '+';
92:
93: /*
94: * Open the file with fopen or popen.
95: */
96: if (status & FS_PIPE) {
97: if (status != (FS_READ|FS_PIPE) && status != (FS_WRITE|FS_PIPE))
98: runerr(209, &arg2);
99: f = popen(sbuf1, mode);
100: }
101: else
102: f = fopen(sbuf1, mode);
103: /*
104: * Fail if the file can't be opened.
105: */
106: if (f == NULL)
107: fail();
108: /*
109: * If the file isn't a terminal and a buffer is available, assign
110: * it to the file.
111: */
112: if (!isatty(fileno(f))) {
113: for (i = 0; i < numbufs; i++)
114: if (bufused[i] == NULL)
115: break;
116: if (i < numbufs) { /* Use buffer if any free. */
117: setbuf(f, bufs[i]);
118: bufused[i] = f;
119: }
120: else
121: setbuf(f, NULL);
122: }
123: else
124: setbuf(f, NULL);
125: /*
126: * Return the resulting file value.
127: */
128: arg0.type = D_FILE;
129: BLKLOC(arg0) = (union block *) alcfile(f, status, &arg1);
130: }
131:
132: Procblock(open,2)
Defined functions
Xopen
defined in line
6;
never used