added depend label
[unix-history] / usr / src / sys / stand.att / sys.c
CommitLineData
da7c5cc6 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
42967f7c 6 * @(#)sys.c 7.4 (Berkeley) %G%
da7c5cc6 7 */
a5a27f5c 8
f6b35dd2
MK
9#include "param.h"
10#include "inode.h"
11#include "fs.h"
12#include "dir.h"
13#include "reboot.h"
a5a27f5c
BJ
14#include "saio.h"
15
16ino_t dlook();
17
70b4ffec
KM
18struct dirstuff {
19 int loc;
20 struct iob *io;
21};
22
a5a27f5c 23static
0839bdeb 24openi(n, io)
70b4ffec 25 register struct iob *io;
a5a27f5c
BJ
26{
27 register struct dinode *dp;
9c0778a9 28 int cc;
a5a27f5c
BJ
29
30 io->i_offset = 0;
70b4ffec
KM
31 io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
32 io->i_cc = io->i_fs.fs_bsize;
a5a27f5c 33 io->i_ma = io->i_buf;
9c0778a9 34 cc = devread(io);
a5a27f5c 35 dp = (struct dinode *)io->i_buf;
70b4ffec 36 io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic;
9c0778a9 37 return (cc);
a5a27f5c
BJ
38}
39
40static
41find(path, file)
70b4ffec
KM
42 register char *path;
43 struct iob *file;
a5a27f5c
BJ
44{
45 register char *q;
f6b35dd2 46 char *dir;
a5a27f5c
BJ
47 char c;
48 int n;
49
50 if (path==NULL || *path=='\0') {
51 printf("null path\n");
0839bdeb 52 return (0);
a5a27f5c
BJ
53 }
54
9c0778a9
SL
55 if (openi((ino_t) ROOTINO, file) < 0) {
56 printf("can't read root inode\n");
57 return (0);
58 }
f6b35dd2 59 dir = path;
a5a27f5c
BJ
60 while (*path) {
61 while (*path == '/')
62 path++;
63 q = path;
64 while(*q != '/' && *q != '\0')
65 q++;
66 c = *q;
67 *q = '\0';
c015e76f 68 if (q == path) path = "." ; /* "/" means "/." */
a5a27f5c 69
f6b35dd2 70 if ((n = dlook(path, file, dir)) != 0) {
9c0778a9 71 if (c == '\0')
a5a27f5c 72 break;
9c0778a9
SL
73 if (openi(n, file) < 0)
74 return (0);
a5a27f5c
BJ
75 *q = c;
76 path = q;
77 continue;
78 } else {
c015e76f 79 printf("%s: not found\n", path);
0839bdeb 80 return (0);
a5a27f5c
BJ
81 }
82 }
0839bdeb 83 return (n);
a5a27f5c
BJ
84}
85
86static daddr_t
87sbmap(io, bn)
70b4ffec
KM
88 register struct iob *io;
89 daddr_t bn;
a5a27f5c 90{
a5a27f5c 91 register struct inode *ip;
70b4ffec 92 int i, j, sh;
a5a27f5c 93 daddr_t nb, *bap;
a5a27f5c
BJ
94
95 ip = &io->i_ino;
70b4ffec 96 if (bn < 0) {
a5a27f5c 97 printf("bn negative\n");
0839bdeb 98 return ((daddr_t)0);
a5a27f5c
BJ
99 }
100
101 /*
70b4ffec 102 * blocks 0..NDADDR are direct blocks
a5a27f5c 103 */
70b4ffec
KM
104 if(bn < NDADDR) {
105 nb = ip->i_db[bn];
0839bdeb 106 return (nb);
a5a27f5c
BJ
107 }
108
109 /*
70b4ffec
KM
110 * addresses NIADDR have single and double indirect blocks.
111 * the first step is to determine how many levels of indirection.
a5a27f5c 112 */
70b4ffec
KM
113 sh = 1;
114 bn -= NDADDR;
115 for (j = NIADDR; j > 0; j--) {
116 sh *= NINDIR(&io->i_fs);
117 if (bn < sh)
a5a27f5c 118 break;
70b4ffec 119 bn -= sh;
a5a27f5c 120 }
70b4ffec
KM
121 if (j == 0) {
122 printf("bn ovf %D\n", bn);
123 return ((daddr_t)0);
a5a27f5c
BJ
124 }
125
126 /*
70b4ffec 127 * fetch the first indirect block address from the inode
a5a27f5c 128 */
70b4ffec
KM
129 nb = ip->i_ib[NIADDR - j];
130 if (nb == 0) {
a5a27f5c 131 printf("bn void %D\n",bn);
0839bdeb 132 return ((daddr_t)0);
a5a27f5c
BJ
133 }
134
135 /*
136 * fetch through the indirect blocks
137 */
70b4ffec 138 for (; j <= NIADDR; j++) {
a5a27f5c 139 if (blknos[j] != nb) {
70b4ffec 140 io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
a5a27f5c 141 io->i_ma = b[j];
70b4ffec 142 io->i_cc = io->i_fs.fs_bsize;
9c0778a9
SL
143 if (devread(io) != io->i_fs.fs_bsize) {
144 if (io->i_error)
145 errno = io->i_error;
146 printf("bn %D: read error\n", io->i_bn);
147 return ((daddr_t)0);
148 }
a5a27f5c
BJ
149 blknos[j] = nb;
150 }
151 bap = (daddr_t *)b[j];
70b4ffec
KM
152 sh /= NINDIR(&io->i_fs);
153 i = (bn / sh) % NINDIR(&io->i_fs);
a5a27f5c
BJ
154 nb = bap[i];
155 if(nb == 0) {
156 printf("bn void %D\n",bn);
0839bdeb 157 return ((daddr_t)0);
a5a27f5c
BJ
158 }
159 }
0839bdeb 160 return (nb);
a5a27f5c
BJ
161}
162
163static ino_t
f6b35dd2 164dlook(s, io, dir)
70b4ffec
KM
165 char *s;
166 register struct iob *io;
f6b35dd2 167 char *dir;
a5a27f5c
BJ
168{
169 register struct direct *dp;
170 register struct inode *ip;
70b4ffec
KM
171 struct dirstuff dirp;
172 int len;
a5a27f5c 173
70b4ffec 174 if (s == NULL || *s == '\0')
0839bdeb 175 return (0);
a5a27f5c 176 ip = &io->i_ino;
70b4ffec 177 if ((ip->i_mode&IFMT) != IFDIR) {
a5a27f5c 178 printf("not a directory\n");
f6b35dd2 179 printf("%s: not a directory\n", dir);
0839bdeb 180 return (0);
a5a27f5c 181 }
70b4ffec 182 if (ip->i_size == 0) {
f6b35dd2 183 printf("%s: zero length directory\n", dir);
0839bdeb 184 return (0);
a5a27f5c 185 }
70b4ffec
KM
186 len = strlen(s);
187 dirp.loc = 0;
188 dirp.io = io;
189 for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
190 if(dp->d_ino == 0)
191 continue;
192 if (dp->d_namlen == len && !strcmp(s, dp->d_name))
0839bdeb 193 return (dp->d_ino);
a5a27f5c 194 }
0839bdeb 195 return (0);
a5a27f5c
BJ
196}
197
70b4ffec
KM
198/*
199 * get next entry in a directory.
200 */
201struct direct *
202readdir(dirp)
203 register struct dirstuff *dirp;
a5a27f5c 204{
70b4ffec
KM
205 register struct direct *dp;
206 register struct iob *io;
207 daddr_t lbn, d;
208 int off;
a5a27f5c 209
70b4ffec
KM
210 io = dirp->io;
211 for(;;) {
212 if (dirp->loc >= io->i_ino.i_size)
9c0778a9 213 return (NULL);
70b4ffec
KM
214 off = blkoff(&io->i_fs, dirp->loc);
215 if (off == 0) {
216 lbn = lblkno(&io->i_fs, dirp->loc);
217 d = sbmap(io, lbn);
218 if(d == 0)
219 return NULL;
220 io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
221 io->i_ma = io->i_buf;
222 io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn);
9c0778a9
SL
223 if (devread(io) < 0) {
224 errno = io->i_error;
c015e76f
MK
225 printf("bn %D: directory read error\n",
226 io->i_bn);
9c0778a9
SL
227 return (NULL);
228 }
70b4ffec
KM
229 }
230 dp = (struct direct *)(io->i_buf + off);
231 dirp->loc += dp->d_reclen;
232 if (dp->d_ino == 0)
233 continue;
234 return (dp);
a5a27f5c 235 }
a5a27f5c
BJ
236}
237
238lseek(fdesc, addr, ptr)
0839bdeb
SL
239 int fdesc, ptr;
240 off_t addr;
a5a27f5c
BJ
241{
242 register struct iob *io;
243
31fec9db 244#ifndef SMALL
a5a27f5c
BJ
245 if (ptr != 0) {
246 printf("Seek not from beginning of file\n");
0839bdeb
SL
247 errno = EOFFSET;
248 return (-1);
a5a27f5c 249 }
31fec9db 250#endif SMALL
a5a27f5c 251 fdesc -= 3;
70b4ffec 252 if (fdesc < 0 || fdesc >= NFILES ||
0839bdeb
SL
253 ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
254 errno = EBADF;
255 return (-1);
256 }
a5a27f5c 257 io->i_offset = addr;
70b4ffec 258 io->i_bn = addr / DEV_BSIZE;
a5a27f5c 259 io->i_cc = 0;
0839bdeb 260 return (0);
a5a27f5c
BJ
261}
262
263getc(fdesc)
0839bdeb 264 int fdesc;
a5a27f5c
BJ
265{
266 register struct iob *io;
70b4ffec 267 register struct fs *fs;
a5a27f5c 268 register char *p;
70b4ffec 269 int c, lbn, off, size, diff;
a5a27f5c
BJ
270
271
272 if (fdesc >= 0 && fdesc <= 2)
0839bdeb 273 return (getchar());
a5a27f5c 274 fdesc -= 3;
70b4ffec 275 if (fdesc < 0 || fdesc >= NFILES ||
0839bdeb
SL
276 ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
277 errno = EBADF;
278 return (-1);
279 }
a5a27f5c
BJ
280 p = io->i_ma;
281 if (io->i_cc <= 0) {
70b4ffec
KM
282 if ((io->i_flgs & F_FILE) != 0) {
283 diff = io->i_ino.i_size - io->i_offset;
284 if (diff <= 0)
285 return (-1);
286 fs = &io->i_fs;
287 lbn = lblkno(fs, io->i_offset);
288 io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
289 off = blkoff(fs, io->i_offset);
290 size = blksize(fs, &io->i_ino, lbn);
291 } else {
292 io->i_bn = io->i_offset / DEV_BSIZE;
293 off = 0;
294 size = DEV_BSIZE;
295 }
a5a27f5c 296 io->i_ma = io->i_buf;
70b4ffec 297 io->i_cc = size;
9c0778a9
SL
298 if (devread(io) < 0) {
299 errno = io->i_error;
300 return (-1);
301 }
70b4ffec
KM
302 if ((io->i_flgs & F_FILE) != 0) {
303 if (io->i_offset - off + size >= io->i_ino.i_size)
304 io->i_cc = diff + off;
a5a27f5c 305 io->i_cc -= off;
70b4ffec 306 }
a5a27f5c
BJ
307 p = &io->i_buf[off];
308 }
309 io->i_cc--;
310 io->i_offset++;
311 c = (unsigned)*p++;
312 io->i_ma = p;
0839bdeb 313 return (c);
a5a27f5c 314}
70b4ffec 315
0839bdeb 316int errno;
a5a27f5c
BJ
317
318read(fdesc, buf, count)
0839bdeb
SL
319 int fdesc, count;
320 char *buf;
a5a27f5c 321{
c015e76f 322 register i, size;
a5a27f5c 323 register struct iob *file;
c015e76f
MK
324 register struct fs *fs;
325 int lbn, off;
a5a27f5c 326
0839bdeb 327 errno = 0;
a5a27f5c
BJ
328 if (fdesc >= 0 & fdesc <= 2) {
329 i = count;
330 do {
331 *buf = getchar();
332 } while (--i && *buf++ != '\n');
0839bdeb 333 return (count - i);
a5a27f5c
BJ
334 }
335 fdesc -= 3;
70b4ffec 336 if (fdesc < 0 || fdesc >= NFILES ||
0839bdeb
SL
337 ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
338 errno = EBADF;
339 return (-1);
340 }
341 if ((file->i_flgs&F_READ) == 0) {
342 errno = EBADF;
343 return (-1);
344 }
31fec9db 345#ifndef SMALL
70b4ffec 346 if ((file->i_flgs & F_FILE) == 0) {
a5a27f5c
BJ
347 file->i_cc = count;
348 file->i_ma = buf;
b5d17f4d 349 file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
a5a27f5c 350 i = devread(file);
0839bdeb
SL
351 if (i < 0)
352 errno = file->i_error;
80c81fbf
MK
353 else
354 file->i_offset += i;
0839bdeb 355 return (i);
a5a27f5c 356 }
31fec9db 357#endif SMALL
c015e76f
MK
358 if (file->i_offset+count > file->i_ino.i_size)
359 count = file->i_ino.i_size - file->i_offset;
360 if ((i = count) <= 0)
361 return (0);
362 /*
363 * While reading full blocks, do I/O into user buffer.
364 * Anything else uses getc().
365 */
366 fs = &file->i_fs;
367 while (i) {
368 off = blkoff(fs, file->i_offset);
369 lbn = lblkno(fs, file->i_offset);
370 size = blksize(fs, &file->i_ino, lbn);
371 if (off == 0 && size <= i) {
372 file->i_bn = fsbtodb(fs, sbmap(file, lbn)) +
373 file->i_boff;
374 file->i_cc = size;
375 file->i_ma = buf;
376 if (devread(file) < 0) {
377 errno = file->i_error;
378 return (-1);
379 }
380 file->i_offset += size;
381 file->i_cc = 0;
382 buf += size;
383 i -= size;
384 } else {
385 size -= off;
386 if (size > i)
387 size = i;
388 i -= size;
389 do {
390 *buf++ = getc(fdesc+3);
391 } while (--size);
392 }
393 }
394 return (count);
a5a27f5c
BJ
395}
396
31fec9db 397#ifndef SMALL
a5a27f5c 398write(fdesc, buf, count)
0839bdeb
SL
399 int fdesc, count;
400 char *buf;
a5a27f5c
BJ
401{
402 register i;
403 register struct iob *file;
404
0839bdeb 405 errno = 0;
a5a27f5c
BJ
406 if (fdesc >= 0 && fdesc <= 2) {
407 i = count;
408 while (i--)
409 putchar(*buf++);
0839bdeb 410 return (count);
a5a27f5c
BJ
411 }
412 fdesc -= 3;
70b4ffec 413 if (fdesc < 0 || fdesc >= NFILES ||
0839bdeb
SL
414 ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
415 errno = EBADF;
416 return (-1);
417 }
418 if ((file->i_flgs&F_WRITE) == 0) {
419 errno = EBADF;
420 return (-1);
421 }
a5a27f5c
BJ
422 file->i_cc = count;
423 file->i_ma = buf;
b5d17f4d 424 file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
a5a27f5c 425 i = devwrite(file);
b5d17f4d 426 file->i_offset += count;
0839bdeb
SL
427 if (i < 0)
428 errno = file->i_error;
429 return (i);
a5a27f5c 430}
31fec9db 431#endif SMALL
a5a27f5c 432
10899d3a 433int openfirst = 1;
80c81fbf
MK
434unsigned opendev; /* last device opened */
435extern unsigned bootdev;
10899d3a 436
a5a27f5c 437open(str, how)
70b4ffec 438 char *str;
0839bdeb 439 int how;
a5a27f5c
BJ
440{
441 register char *cp;
80c81fbf 442 register int i;
a5a27f5c 443 register struct iob *file;
0839bdeb
SL
444 int fdesc;
445 long atol();
a5a27f5c 446
10899d3a 447 if (openfirst) {
a5a27f5c
BJ
448 for (i = 0; i < NFILES; i++)
449 iob[i].i_flgs = 0;
10899d3a 450 openfirst = 0;
a5a27f5c
BJ
451 }
452
453 for (fdesc = 0; fdesc < NFILES; fdesc++)
454 if (iob[fdesc].i_flgs == 0)
455 goto gotfile;
456 _stop("No more file slots");
457gotfile:
458 (file = &iob[fdesc])->i_flgs |= F_ALLOC;
459
42967f7c 460#ifndef SMALL
80c81fbf
MK
461 for (cp = str; *cp && *cp != '/' && *cp != ':' && *cp != '('; cp++)
462 ;
463 if (*cp == '(') {
464 if ((file->i_ino.i_dev = getdev(str, cp - str)) == -1)
465 goto bad;
466 cp++;
467 if ((file->i_unit = getunit(cp)) == -1)
468 goto bad;
469 for (; *cp != ','; cp++)
470 if (*cp == NULL) {
471 errno = EOFFSET;
472 goto badspec;
473 }
f6b35dd2 474 file->i_boff = atol(++cp);
80c81fbf
MK
475 for (;;) {
476 if (*cp == ')')
477 break;
478 if (*cp++)
479 continue;
480 goto badspec;
481 }
f6b35dd2 482 cp++;
80c81fbf 483 } else if (*cp != ':') {
42967f7c 484#endif
c015e76f 485 /* default bootstrap unit and device */
80c81fbf
MK
486 file->i_ino.i_dev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
487 file->i_unit = ((bootdev >> B_UNITSHIFT) & B_UNITMASK) +
488 (8 * ((bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK));
489 file->i_boff = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
c015e76f 490 cp = str;
42967f7c 491#ifndef SMALL
c015e76f
MK
492 } else {
493# define isdigit(n) ((n>='0') && (n<='9'))
80c81fbf
MK
494 if (cp == str)
495 goto badspec;
c015e76f
MK
496 /*
497 * syntax for possible device name:
498 * <alpha-string><digit-string><letter>:
499 */
500 for (cp = str; *cp != ':' && !isdigit(*cp); cp++)
501 ;
80c81fbf
MK
502 if ((file->i_ino.i_dev = getdev(str, cp - str)) == -1)
503 goto bad;
504 if ((file->i_unit = getunit(cp)) == -1)
505 goto bad;
506 while (isdigit(*cp))
507 cp++;
508 file->i_boff = 0;
509 if (*cp >= 'a' && *cp <= 'h')
510 file->i_boff = *cp++ - 'a';
c015e76f 511 if (*cp++ != ':') {
c015e76f 512 errno = EOFFSET;
80c81fbf 513 goto badspec;
c015e76f 514 }
c015e76f 515 }
42967f7c 516#endif
80c81fbf
MK
517 opendev = file->i_ino.i_dev << B_TYPESHIFT;
518 opendev |= ((file->i_unit % 8) << B_UNITSHIFT);
519 opendev |= ((file->i_unit / 8) << B_ADAPTORSHIFT);
520 opendev |= file->i_boff << B_PARTITIONSHIFT;
f6b35dd2 521 opendev |= B_DEVMAGIC;
80c81fbf
MK
522 if (errno = devopen(file))
523 goto bad;
c015e76f
MK
524 if (cp != str && *cp == '\0') {
525 file->i_flgs |= how+1;
526 file->i_cc = 0;
527 file->i_offset = 0;
528 return (fdesc+3);
529 }
70b4ffec
KM
530 file->i_ma = (char *)(&file->i_fs);
531 file->i_cc = SBSIZE;
f6b35dd2 532 file->i_bn = SBOFF / DEV_BSIZE + file->i_boff;
70b4ffec 533 file->i_offset = 0;
9c0778a9
SL
534 if (devread(file) < 0) {
535 errno = file->i_error;
536 printf("super block read error\n");
80c81fbf 537 goto bad;
9c0778a9 538 }
a5a27f5c 539 if ((i = find(cp, file)) == 0) {
0839bdeb 540 errno = ESRCH;
80c81fbf 541 goto bad;
a5a27f5c 542 }
31fec9db 543#ifndef SMALL
a5a27f5c
BJ
544 if (how != 0) {
545 printf("Can't write files yet.. Sorry\n");
0839bdeb 546 errno = EIO;
80c81fbf 547 goto bad;
a5a27f5c 548 }
31fec9db 549#endif SMALL
9c0778a9
SL
550 if (openi(i, file) < 0) {
551 errno = file->i_error;
80c81fbf 552 goto bad;
9c0778a9 553 }
a5a27f5c
BJ
554 file->i_offset = 0;
555 file->i_cc = 0;
556 file->i_flgs |= F_FILE | (how+1);
0839bdeb 557 return (fdesc+3);
80c81fbf
MK
558
559badspec:
560 printf("malformed device specification\n");
561bad:
562 file->i_flgs = 0;
563 return (-1);
564}
565
42967f7c 566#ifndef SMALL
80c81fbf
MK
567static
568getdev(str, len)
569 char *str;
570 int len;
571{
572 register struct devsw *dp;
573
574 for (dp = devsw; dp->dv_name; dp++) {
575 if (!strncmp(str, dp->dv_name, len))
576 return (dp - devsw);
577 }
578 printf("Unknown device\n");
579 errno = ENXIO;
580 return (-1);
581}
582
583static
584getunit(cp)
585 register char *cp;
586{
587 register int i = 0;
588
589 while (*cp >= '0' && *cp <= '9')
590 i = i * 10 + *cp++ - '0';
591 if ((unsigned) i > 255) {
592 printf("minor device number out of range (0-255)\n");
593 errno = EUNIT;
594 i = -1;
595 }
596 return (i);
a5a27f5c 597}
42967f7c 598#endif
a5a27f5c
BJ
599
600close(fdesc)
0839bdeb 601 int fdesc;
a5a27f5c
BJ
602{
603 struct iob *file;
604
605 fdesc -= 3;
70b4ffec 606 if (fdesc < 0 || fdesc >= NFILES ||
0839bdeb
SL
607 ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
608 errno = EBADF;
609 return (-1);
610 }
a5a27f5c
BJ
611 if ((file->i_flgs&F_FILE) == 0)
612 devclose(file);
613 file->i_flgs = 0;
0839bdeb
SL
614 return (0);
615}
616
31fec9db 617#ifndef SMALL
0839bdeb
SL
618ioctl(fdesc, cmd, arg)
619 int fdesc, cmd;
620 char *arg;
621{
622 register struct iob *file;
623 int error = 0;
624
9a46f589 625 fdesc -= 3;
0839bdeb
SL
626 if (fdesc < 0 || fdesc >= NFILES ||
627 ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
628 errno = EBADF;
629 return (-1);
630 }
631 switch (cmd) {
632
633 case SAIOHDR:
634 file->i_flgs |= F_HDR;
635 break;
636
637 case SAIOCHECK:
638 file->i_flgs |= F_CHECK;
639 break;
640
641 case SAIOHCHECK:
642 file->i_flgs |= F_HCHECK;
643 break;
644
9a46f589
HS
645 case SAIONOBAD:
646 file->i_flgs |= F_NBSF;
647 break;
648
649 case SAIODOBAD:
650 file->i_flgs &= ~F_NBSF;
651 break;
652
0839bdeb
SL
653 default:
654 error = devioctl(file, cmd, arg);
655 break;
656 }
657 if (error < 0)
658 errno = file->i_error;
659 return (error);
a5a27f5c 660}
31fec9db 661#endif SMALL
a5a27f5c
BJ
662
663exit()
664{
665 _stop("Exit called");
666}
667
668_stop(s)
0839bdeb 669 char *s;
a5a27f5c 670{
0b87420c
MT
671 int i;
672
673 for (i = 0; i < NFILES; i++)
674 if (iob[i].i_flgs != 0)
675 close(i);
a5a27f5c
BJ
676 printf("%s\n", s);
677 _rtt();
678}