UNIX OPERATING SYSTEM SOURCE CODE LEVEL SIX

3 downloads 55609 Views 230KB Size Report
System source code, such as might be used on a typical ..... 1509 CLOCK1 0177546 8618 ERROR. 040 ... Sep 1 09:32 1988 UNIX Operating System Source Code Cross Reference Listing Page 1 ..... itrunc 4112 5825 7353 7414 i_mtime 5615.
THIS VERSION WAS PRODUCED BY REVERTING THE SEVENTH EDITION KERNEL SOURCE CODE AND A PROGRAM WRITTEN TO GENERATE THE INDEX AND CROSS REFERENCE BY BRIAN S. WALDEN WH 3A-327 AUGUST 1988

UNIX OPERATING SYSTEM SOURCE CODE LEVEL SIX This booklet has been produced for studets at the University of New South Wales taking courses 6.602B and 6.657G. It containes a specially edited selection of the UNIX Operating System source code, such as might be used on a typical PDP11/40 computer installation. The UNIX Software System was written by K. Thompson and D. Ritchie of Bell Telephone Laboratories, Murray Hill, NJ. It has been made available to the University of New South Wales under a licence from the Western Electric Company.

J. Lions Department of Computer Science The University of New South Wales. June, 1977

Sep

1 09:31 1988

6746 6956 0734 1012 7040 4856 6585 4836 5229 5055 6415 4754 4773 4869 4809 8274 3538 3560 3575 8234 0676 3725 5846 6643 6672 5038 1244 1252 0696 4094 6542 5781 2447 5096 0890 1319 1327 6069 1650 3020 3219 2268 6847 8252 3322 7000 6014 0815 0814 0844 0845 4921 0930 5336 6619 7167

access alloc aretu: backup: badblock bawrite bcopy bdwrite bflush binit bmap bread breada brelse bwrite canon chdir chmod chown cinit clearseg: clock close closef closei clrbuf copyin: copyout: copyseg: core cpass creat deverror devstart display: dpadd: dpcmp: dup estabur exec exit expand falloc flushtty fork free fstat fubyte: fuibyte: fuiword: fuword: getblk getc: geterror getf getfs

UNIX Operating System Procedures Sorted Alphabetically Page 1

3472 6181 3480 3413 3452 4136 3420 8165 7067 1284 7134 7276 6922 4899 0895 5018 6364 4982 7344 3991 7414 7374 3630 8055 8023 8062 8078 8090 8066 8070 1393 5909 8879 8863 8976 8850 8986 8967 8870 1401 1410 1550 7455 2528 5156 5182 6326 2556 6339 5952 9016 9042 7518 1826 3493 6566

getgid getmdev getpid getswit getuid grow gtime gtty ialloc idle: ifree iget iinit incore incupc: iodone iomove iowait iput issig itrunc iupdat kill klclose klopen klread klrint klsgtty klwrite klxint ldiv: link lpcanon lpclose lpint lpopen lpoutput lpstart lpwrite lrem: lshift: main maknode malloc mapalloc mapfree max mfree min mknod mmread mmwrite namei newproc nice nodev

2855 4999 1771 6577 2864 5765 5804 6702 6791 2416 6517 8669 8763 8648 8748 8739 8682 8719 8710 8701 5259 7723 7862 2433 7882 2340 2369 4204 3667 4043 3963 4164 0967 2386 5731 5711 6221 7758 0740 3205 5123 5420 5451 5476 5440 5389 5483 0889 0725 3354 7679 1940 5861 3460 2156 2134

nosys notavil nseg nulldev nullsys open open1 openi owner panic passc pcclose pcleader pcopen pcoutput pcpint pcread pcrint pcstart pcwrite physio pipe plock prdev prele printf printn procxmt profil psig psignal ptrace putc: putchar rdwr read readi readp retu: rexit rhstart rkaddr rkintr rkread rkstart rkstrategy rkwrite savfp: savu: sbreak schar sched seek setgid setpri setrun

3439 8201 3949 2066 3595 6086 1293 1297 1302 1303 1308 1313 3614 5979 6028 6045 3428 4016 8183 0827 0826 0860 6144 1739 6811 0861 5196 2178 3486 3845 3656 2693 2841 8535 8486 8505 8550 8333 8373 8577 7689 6824 3510 7201 3270 2113 7477 8217 5720 6276 7805 4433 4490 4398 4368

setuid sgtty signal sleep smdate smount spl0: spl1: spl4: spl5: spl6: spl7: ssig sslep stat stat1 stime stop stty subyte: suibyte: suiword: sumount sureg suser suword: swap swtch sync timeout times trap trap1 ttread ttrstrt ttstart ttwrite ttyinput ttyoutput ttystty uchar ufalloc unlink update wait wakeup wdir wflushtty write writei writep xalloc xccdec xfree xswap

Sep

1 09:31 1988

File param.h File systm.h File seg.h File proc.h File user.h File low.s File m40.s 0676 _clearseg: 0696 _copyseg: 0725 _savu: 0734 _aretu: 0740 _retu: 0814 _fuibyte: 0815 _fubyte: 0826 _suibyte: 0827 _subyte: 0844 _fuiword: 0845 _fuword: 0860 _suiword: 0861 _suword: 0889 _savfp: 0890 _display: 0895 _incupc: 0930 _getc: 0967 _putc: 1012 _backup: 1244 _copyin: 1252 _copyout: 1284 _idle: 1293 _spl0: 1297 _spl1: 1302 _spl4: 1303 _spl5: 1308 _spl6: 1313 _spl7: 1319 _dpadd: 1327 _dpcmp: 1393 _ldiv: 1401 _lrem: 1410 _lshift: File main.c 1550 main 1650 estabur 1739 sureg 1771 nseg File slp.c 1826 newproc 1940 sched 2066 sleep 2113 wakeup 2134 setrun 2156 setpri 2178 swtch 2268 expand

UNIX Operating System Files and Procedures Page 1

File prf.c 2340 printf 2369 printn 2386 putchar 2416 panic 2433 prdev 2447 deverror File malloc.c 2528 malloc 2556 mfree File reg.h File trap.c 2693 trap 2841 trap1 2855 nosys 2864 nullsys File sysent.c File sys1.c 3020 exec 3205 rexit 3219 exit 3270 wait 3322 fork 3354 sbreak File sys4.c 3413 getswit 3420 gtime 3428 stime 3439 setuid 3452 getuid 3460 setgid 3472 getgid 3480 getpid 3486 sync 3493 nice 3510 unlink 3538 chdir 3560 chmod 3575 chown 3595 smdate 3614 ssig 3630 kill 3656 times 3667 profil File clock.c 3725 clock 3845 timeout File sig.c 3949 signal 3963 psignal 3991 issig 4016 stop 4043 psig 4094 core

4136 grow 4164 ptrace 4204 procxmt File text.h File text.c 4368 xswap 4398 xfree 4433 xalloc 4490 xccdec File buf.h File conf.h File conf.c File bio.c 4754 bread 4773 breada 4809 bwrite 4836 bdwrite 4856 bawrite 4869 brelse 4899 incore 4921 getblk 4982 iowait 4999 notavil 5018 iodone 5038 clrbuf 5055 binit 5096 devstart 5123 rhstart 5156 mapalloc 5182 mapfree 5196 swap 5229 bflush 5259 physio 5336 geterror File rk.c 5389 rkstrategy 5420 rkaddr 5440 rkstart 5451 rkintr 5476 rkread 5483 rkwrite File file.h File filsys.h File ino.h File inode.h File sys2.c 5711 read 5720 write 5731 rdwr 5765 open 5781 creat 5804 open1 5846 close

5861 seek 5909 link 5952 mknod 5979 sslep File sys3.c 6014 fstat 6028 stat 6045 stat1 6069 dup 6086 smount 6144 sumount 6181 getmdev File rdwri.c 6221 readi 6276 writei 6326 max 6339 min 6364 iomove File subr.c 6415 bmap 6517 passc 6542 cpass 6566 nodev 6577 nulldev 6585 bcopy File fio.c 6619 getf 6643 closef 6672 closei 6702 openi 6746 access 6791 owner 6811 suser 6824 ufalloc 6847 falloc File alloc.c 6922 iinit 6956 alloc 7000 free 7040 badblock 7067 ialloc 7134 ifree 7167 getfs 7201 update File iget.c 7276 iget 7344 iput 7374 iupdat 7414 itrunc 7455 maknode 7477 wdir File nami.c 7518 namei

7679 schar 7689 uchar File pipe.c 7723 pipe 7758 readp 7805 writep 7862 plock 7882 prele File tty.h File kl.c 8023 klopen 8055 klclose 8062 klread 8066 klwrite 8070 klxint 8078 klrint 8090 klsgtty File tty.c 8165 gtty 8183 stty 8201 sgtty 8217 wflushtty 8234 cinit 8252 flushtty 8274 canon 8333 ttyinput 8373 ttyoutput 8486 ttrstrt 8505 ttstart 8535 ttread 8550 ttwrite 8577 ttystty File pc.c 8648 pcopen 8669 pcclose 8682 pcread 8701 pcwrite 8710 pcstart 8719 pcrint 8739 pcpint 8748 pcoutput 8763 pcleader File lp.c 8850 lpopen 8863 lpclose 8870 lpwrite 8879 lpcanon 8967 lpstart 8976 lpint 8986 lpoutput File mem.c 9016 mmread 9042 mmwrite

Sep

1 09:31 1988

5372 7993 7992 8617 4584 4576 4586 4574 4575 4579 4577 4573 4583 4581 4572 0140 8840 7990 7955 7954 7958 7956 1509 1510 8609 0141 7957 7976 7970 5374 0107 8010 7980 8616 8815 5369 5371 8013 0473 0479 0477 0475 2658 0481 0476 7969 0318 0482 0466 0492

ARDY ASLEEP BUSY BUSY B_ASYNC B_BUSY B_DELWRI B_DONE B_ERROR B_MAP B_PHYS B_READ B_RELOC B_WANTED B_WRITE CANBSIZ CAP CARR_ON CEOT CERASE CINTR CKILL CLOCK1 CLOCK2 CLOSED CMAPSIZ CQUIT CRDELAY CRMOD CTLRDY DIRSIZ DLBASE DONE DONE DONE DRESET DRY DSRDY E2BIG EACCES EAGAIN EBADF EBIT EBUSY ECHILD ECHO ED EEXIST EFAULT EFBIG

UNIX Operating System Defined Symbols Page 1

0100 0100 040 04000 0400 010 01000 02 04 040 020 01 0200 0100 0 256 01 020 004 ’#’ 0177 ’@’ 0177546 0172540 0 100 034 030000 020 0200 14 0175610 0200 0200 0200 014 0200 02 7 13 11 9 1 16 10 010 010 17 106 27

0470 0487 0471 0486 8842 8820 0489 0496 0488 0484 0468 0474 0478 0493 0480 0485 0490 0472 8612 0467 0497 0495 8618 0494 0469 0491 7973 0483 3018 8847 5519 5517 5518 5095 5368 7966 0147 5681 5620 5687 5092 5370 7981 8615 8814 5631 5698 5624 5691 5623

EINTR EINVAL EIO EISDIR EJECT EJLINE EMFILE EMLINK ENFILE ENODEV ENOENT ENOEXEC ENOMEM ENOSPC ENOTBLK ENOTDIR ENOTTY ENXIO EOF EPERM EPIPE EROFS ERROR ESPIPE ESRCH ETXTBSY EVENP EXDEV EXPRI FORM FPIPE FREAD FWRITE GO GO HUPCL HZ IACC IALLOC IALLOC IENABLE IENABLE IENABLE IENABLE IENABLE IEXEC IEXEC IFBLK IFBLK IFCHR

4 22 5 21 02 60 24 31 23 19 2 8 12 28 15 20 25 6 3 1 32 30 0100000 29 3 26 0200 18 -1 014 04 01 02 01 01 01 60 04 0100000 0100000 0100 0100 0100 0100 0100 0100 0100 060000 060000 020000

5690 5622 5689 5621 5688 5625 5692 5679 5682 8844 3914 5629 5696 5627 5694 7987 5626 5693 5628 5695 5684 5680 5683 5630 5697 0165 8008 8009 7968 8812 8819 8818 8817 8821 0135 0130 0143 0146 8012 0134 0132 0131 8011 7974 0133 0105 0139 0144 5364

IFCHR IFDIR IFDIR IFMT IFMT ILARG ILARG ILOCK IMOUNT IND IPCPRI IREAD IREAD ISGID ISGID ISOPEN ISUID ISUID ISVTX ISVTX ITEXT IUPD IWANT IWRITE IWRITE KL KLADDR KLBASE LCASE LPADDR LPHWAT LPLWAT LPPRI MAXCOL MAXMEM NBUF NCALL NCLIST NDL11 NEXEC NFILE NINODE NKL11 NLDELAY NMOUNT NODEV NOFILE NPROC NRK

020000 040000 040000 060000 060000 010000 010000 01 010 010 (-1) 0400 0400 02000 02000 04 04000 04000 01000 01000 040 02 020 0200 0200 0177560 0177560 0176500 04 0177514 100 50 10 80 (64*32) 15 20 100 0 3 100 100 1 001400 5 (-1) 15 50 4

5365 0113 0145 0104 7972 8843 8607 8624 8620 8623 8622 8621 0155 7715 0157 0156 0164 0159 0154 0160 0158 2605 2606 2607 2608 2609 2610 2611 2612 7971 5094 8014 8614 8611 5367 5121 5120 5363 0315 0106 2613 0317 3707 2660 0385 0123 0120 0121 0114

NRKBLK NSIG NTEXT NULL ODDP OPEN PCADDR PCIHWAT PCIPRI PCOHWAT PCOLWAT PCOPRI PINOD PIPSIZ PPIPE PRIBIO PS PSLEP PSWP PUSER PWAIT R0 R1 R2 R3 R4 R5 R6 R7 RAW RCOM RDRENB RDRENB READING RESET RHRCOM RHWCOM RKADDR RO ROOTINO RPS RW SCHMAG SETD SIDL SIGBUS SIGEMT SIGFPT SIGHUP

4872 20 40 0 0100 04 0177550 250 30 100 50 40 -90 4096 1 -50 0177776 90 -100 100 40 (0) (-2) (-9) (-8) (-7) (-6) (-3) (1) 040 04 01 01 2 0 070 060 0177400 02 1 (2) 06 10 0170011 4 10 7 8 1

0117 0115 0119 0122 0126 0116 0124 0125 0118 0138 0391 0393 0142 0384 0137 0382 7988 0387 0394 0392 0395 0166 0383 0396 2661 0386 7975 2615 7984 7961 7951 7962 7952 7963 0311 0308 0306 0304 2659 3706 2662 0103 7977 8610 5093 5373 0316 7985 7967

SIGINS SIGINT SIGIOT SIGKIL SIGPIPE SIGQIT SIGSEG SIGSYS SIGTRC SINCR SLOAD SLOCK SMAPSIZ SRUN SSIZE SSLEEP SSTART SSTOP SSWAP SSYS STRC SW SWAIT SWTED SYS SZOMB TBDELAY TBIT TIMEOUT TTHIWAT TTIPRI TTLOWAT TTOPRI TTYHOG UBMAP UDSA UISA UISD UMODE UMODE USER USIZE VTDELAY WAITING WCOM WLO WO WOPEN XTABS

4 2 6 9 13 3 11 12 5 20 01 04 100 3 20 1 010 6 010 02 020 0177570 2 040 0104400 5 006000 020 01 50 10 30 20 256 0170200 0177660 0177640 0177600 0170000 0170000 020 16 040000 1 02 020000 04 02 02

Sep

1 09:32 1988

a1

a2

aa abae abn abp

ac access

addr

adev adx afp aip

alloc an ap

ARDY aretu arg ASLEEP atp

av av_back av_forw

1828 2271 2293 1828 1915 2290 2556 5123 7040 5156 5260 5341 8333 3041 5817 7658 8024 8044 8082 8508 8522 4773 4899 2344 2361 7040 6221 6277 6751 6435 6497 6364 1652 1678 1694 1708 1718 3022 3154 3164 5372 0724 3845 7993 8217 8253 8282 8486 8512 8550 8578 8577 4526 5009 4525 4960

UNIX Operating System Source Code Cross Reference Listing Page 1

1894 1904 1915 2276 2278 2292 1896 2271 2292 2563 5125 7046 5157 5268 5389 8340 3552 6746

1902 1913 2282 2283

5171 5336 5390 8373 4109 7563

5259 5337 5396 8382 5815 7604

8039 8051 8083 8513

8041 8052 8084 8515

8043 8079 8086 8518

5134

4778 4785 4795 4905 4906 2346 2355 2357 7045 6222 6229 6276 6284 6746 6747 6448 6956 6370 1665 1679 1696 1712 1719 3052 3155

0734 3871 8224 8218 8257 8333 8490 8535 8551 8581 8578 4884 5063 4888 5008

6468 6480

1669 1685 1699 1715 1721 3054 3156

1675 1691 1701 1717 1722 3058 3159

2106 2242 8562 8221 8274 8334 8505 8536 8555

8252 8275 8339 8506 8540 8577

8582 4889 5008 4891 4953 5009 5063

5235 5470 backp 4872 4890 backup 1009 2812 bad 3042 3093 3193 5284 6629 6766 badblock 6970 badtrap 1465 bap 6419 6479 6499 base 5264 5291 5308 bawrite 4845 bcopy 3238 6976 bdevsw 4617 4785 4906 5212 6722 bdp 5060 bdwrite 4836 6485 bflg 1049 1204 bflush 5229 bfreelist 4567 4884 4954 5063 5071 bigger 3375 binit 1614 blkno 4754 4781 4921 5209 bmap 6248 bn 6225 6256 6298 6417 6451 6464 7046 9029 9055 bno 6958

5236 5407 5412 4884 4888 4889 1012 1015 1047 3055 3103 3548 5293 6715 6777 7008 1468 6437 6484 6506 5269 5305

3060 3107 3553 5325 6721

4856 6124 7019 4622 4795 4934 6113 6926 5076 6311 6500 1060 1238 7230 4878 4891 4955 5068 5235 3386 5055 4758 4799 4938

6310 6585 7220 4656 4819 5060 6166

6298 6239 6258 6304 6423 6455 6478 7047 9032 9059 6967

6415 6248 6280 6305 6431 6456 6496 9018 9033 9065 6968

3065 3119 5274 6625 6726

7040 6439 6473 6491 6497 5273 5278 5306 5307

6931 7636 4763 4843 5076 6689

5077 6443 6449 6501 1094 1108

4879 4932 4960 5069

4880 4953 5062 5070

4773 4780 4899 4908 4974 5196 7626 6253 6294 6415 6447 6463 7043 9024 9044 9066 6970

bp

6973 7016 2447 2534 2538 2559 2567 2571 2578 2584 3049 3282 4810 4842 4869 4907 4937 4943 4961 4967 4971 4975 4999 5019 5044 5067 5071 5097 5132 5173 5186 5237 5241 5296 5305 5310 5316 5322 5342 5397 5403 5412 5427 5453 5470 6052 6258 6304 6310 6371 6442 6450 6473 6490 6924 6959

6981 7025 2448 2535 2540 2564 2568 2572 2580 2585 3153 3290 4815 4856 4870 4908 4938 4948 4962 4968 4972 4982 5000 5023 5057 5068 5072 5105 5160 5178 5231 5238 5263 5297 5307 5311 5318 5323 5343 5398 5404 5413 5442 5457 5471 6062 6260 6305 6311 6419 6443 6468 6481 6491 6927 6973

7000 7008 2452 2536 2541 2565 2569 2576 2581 3022 3195 3298 4836 4857 4875 4909 4941 4949 4963 4969 4973 4983 5005 5038 5065 5069 5073 5123 5171 5182 5235 5239 5268 5299 5308 5313 5319 5339 5392 5399 5407 5420 5444 5460 6048 6224 6261 6306 6364 6435 6448 6470 6485 6501 6931 6974

2532 2537 2542 2566 2570 2577 2583 3040 3272 4809 4837 4861 4902 4923 4942 4960 4966 4970 4974 4987 5018 5039 5066 5070 5096 5124 5172 5183 5236 5240 5295 5300 5309 5315 5321 5341 5396 5402 5410 5421 5447 5467 6051 6256 6279 6308 6365 6437 6449 6472 6487 6503 6932 6977

bp1 br4 br5 br6 br7

bread

breada brelse

bss buf

buffers BUSY bwrite byte b_addr

6981 7016 7082 7112 7221 7400 7440 7602 7636 7664 8300 8315 8322 8278 0526 0541 0544 0534 0512 0516 0547 3282 6116 6488 7319 7625 4773 3195 4848 6062 6261 6503 7324 7602 1237 4520 4526 4557 4756 4837 4870 4983 5019 5097 5157 5260 5387 5423 4720 7992 3239 5241 1220 3049 4529 5136

6982 7017 7083 7205 7379 7417 7524 7623 7655 8277 8301 8316 8323 8319 0527

0535 0513 0517 0548 4754 6258 6927 7386 6256 3298 4869 6118 6308 6932 7332 7624 1463 4523 4535 4558 4775 4839 4872 4985 5021 5101 5160 5263 5390 5442 5067 8617 4809 7021

6984 7021 7097 7216 7386 7426 7590 7624 7656 8291 8310 8319

7002 7069 7098 7220 7387 7427 7601 7625 7662 8298 8312 8320

8322 0530 0531

0514 0518 0549 4799 6305 6973 7426

0515 0538

4791 5028 6129 6481 6977 7436 7656

4822 5073 6172 6487 7112 7440

4524 4555 4567 4810 4857 4902 5000 5057 5124 5183 5337 5392 5453

4525 4556 4721 4812 4859 4923 5002 5065 5128 5231 5339 5421 6365

6051 6472 7097 7431

8691 4863 4963 7221 7400

3153 3238 3290 5044 5067 5107 5210 5305 5307

Sep

1 09:32 1988

B_ASYNC b_back

b_blkno

B_BUSY

B_DELWRI b_dev

B_DONE

b_error B_ERROR b_error B_ERROR b_error B_ERROR b_flags

b_forw

B_MAP B_PHYS B_READ

B_RELOC

6052 6437 6935 7174 7387 7636 4584 4887 4524 4970 5070 2454 4974 5428 6484 4576 5010 5202 5299 4586 4961 2453 4883 5066 5399 4574 4817 5214 4532 4575 5311 5342 5343 5403 4522 4783 4817 4878 4941 4962 5024 5072 5186 5295 5318 5403 4523 4967 4972 5071 4579 4577 2034 4783 5140 4583

UNIX Operating System Source Code Cross Reference Listing Page 2

6124 6473 6974 7212 7427

6125 6491 7017 7220 7432

6371 6931 7098 7328 7433

4793 4962 4556 4971 5080 4531 5209 6442 6498 4887 5072 5206 5321 4817 5237 4527 4908 5207 5429 4759 4847 5315

4820 5027 4967 5062

4862 5239 4968 5068

4908 4938 5309 5402 6450 6470 4941 4966 5165 5169 5219 5295 4823 4847 4819 4938 5238 5431 4782 4989

4843 4973 5300 4790 5026

4817 4882 5220

5467 4759 4790 4847 4879 4942 4966 5026 5111 5200 5296 5321 5467 4555 4968 5062 5079 5024 5206 2042 4793 5479 4966

7323 4761 4793 4862 4882 4954 4989 5027 5140 5237 5299 5342 7323 4907 4969 5069 5172 5299 4573 4817 6260

4782 4816 4876 4887 4961 5010 5030 5172 5239 5315 5397 4937 4971 5070 5186 5397 4761 5111

b_resid B_WANTED

4533 4581 4887 5166 5219 b_wcount 4528 4818 5310 B_WRITE 4572 6386 b_xmem 4530 5173 c1 8881 8887 8929 c2 8881 8902 call 0555 0567 0752 call1 0762 callo 0260 callout 0265 3768 callp 2696 2762 CANBSIZ 0140 canon 8274 canonb 0202 8320 CAP 8840 CARR_ON 7990 8556 cblock 8140 8237 cc 8635 8830 ccc 8835 8937 8950 ccp 8236 8246 cdevsw 4635 6287 8238 cdp 8238 CEOT 7955 CERASE 7954 cf 8636 cfree 8146 cfreelist 0928 0979 8241 chan 2066 2118 chdir 2924

5322 4876 4942 5187 5296 4762 5108

4878 4954 5203 5318 4784 5137

4879 5030 5216 5321 4794 5208

chmod chown cinit CINTR CKILL cl clearseg

5486 6306 6373

clist

5110 5178 8883 8911 8930 8890 8906 0558 0570 0776 0771 3727 3748 3773 2754 2765 0202 8543 8291

clock CLOCK1 CLOCK2 cloop close CLOSED closef closei clrbuf CMAPSIZ colp

5134 5211 8885 8915 8959 8894 8909 0561 0574 2669

5139 5308 8886 8928 8898 0564 0577 2771

3847 3750 3767 3853 2755 2761 2771 8316 8300 8316

8884 8046 8285 8541 8141 8146 8149 8731 8981 8910 8941 8954 8239 8247 4641 6685 8245 8245 8306 8048 8831 8239 0954 0986 8242 2076 3538

8743 8988 8918 8942 8955 8240

8754 8935 8946 8962 8244

com

cont copsu copyin copyout copyseg core coreaddr coremap

count cp

4669 6234 6716 8213

8240 0955 0977 0988 8149 2089 2113 cp1 cp2

2927 2928 1613 7958 7956 8637 0675 3395 7908 8634 0569 1509 1510 7542 2918 8609 3230 6656 5038 0141 8378 8404 8436 8454 5102 5115 5142 7106 1245 1243 1243 0695 3380 4076 5196 0203 2278 4383 2668 5208 3025 3153 3187 4024 6052 6372 6390 6931 6937 7417 7431 7572 7645 8241 7480 7480

3560 3575 8234 8344 8049 8832 0676 4155 7928 8643 0570 1601 1603 7667 5846 8653 5854 6672 6982 0203 8400 8423 8442 8458 5109 5129 5143 7110 1253 1244 1252 0696 3392 4094 5210 1568 2282 4497 2762 6585 3049 3161 4018 4026 6059 6374 6394 6933 6938 7427 7438 7573 7646 8242 7483 7484

cpass cputype 8345

1566 3134 7929 7930 8644 3725

8675 6643

CQUIT CRDELAY creat cret CRMOD csv CTLRDY ctype

curpri c_arg c_cc

8401 8429 8443 8459 5112 5138

8402 8435 8448 8475 5114 5141

1264 6374 1630 6376 1915 2292 4152

c_cf c_cl c_func

c_next c_time

data dev

5211 1896 1982 2293 3241 2765 6592 3061 3162 4021 4028 6367 6376 6924 6935 6939 7428 7523 7576 8237 7485 7485

5196 3072 3186 4022 6048 6371 6377 6928 6936 6940 7429 7570 7577 8240

devblk

6388 8874 0208 1655 5162 7957 7976 2920 1429 7970 1419 5374 8379 8441 8468 0222 0263 3871 7910 8543 7911 7912 0264 3770 3865 8141 0262 3769 3859 1457 2433 2702 4758 4780 4799 4921 4938 5259 5483 6685 6716 6970 7000 7040 7078 7134 7178 7314 8030 8042 8063 8072 8093 8863 9042 5096

6542 8558 8705 9057 1459 1461 1571 1746 1756 5133 8344 5781 1430 8047 1420 5462 8424 8445 8469 2141 3770

8342 8412

8426 8452 8472 2165 3776

8440 8453 2224 3866

8074 8223 8349 8544 8560

3748 3774 3870 8241 3751 3775 3864

3751 3769 3855 3861

2436 2718 4763 4781 4901 4927 4973 5300 5486 6689 6722 6973 7004 7048 7097 7138 7276 7319 8033 8055 8066 8078 8648 9016 9047 5106

2693 3725 4776 4788 4905 4931 5229 5476 6676 6706 6956 6981 7008 7067 7104 7167 7286 8023 8039 8057 8067 8081 8669 9021 9064 5123

3753 3767 3855 3856 3869 2700 4754 4778 4789 4908 4934 5238 5479 6679 6709 6961 6988 7016 7072 7120 7173 7296 8026 8040 8062 8070 8090 8850 9031 5135

Sep

1 09:32 1988

deverror devloc devstart devtab DIRSIZ

display DLBASE dn

DONE dp

dpadd

dpcmp DRESET DRY ds DSRDY dump dup d_actf d_active d_actl d_close

2447 5096 5125 5096 4551 5058 0107 3526 7576 7638 0888 8010 6226 6250 6281 6305 7980 8714 1652 1680 1700 1718 4843 4907 4935 4971 5078 5104 5115 5136 7431 7521 7551 7604 7626 7663 1318 3295 5895 1326 5990 5369 5371 3023 3138 8013 0521 1355 2953 4557 5457 4553 5458 4558 4619 6689

UNIX Operating System Source Code Cross Reference Listing Page 3

5460 5098 5131 5447 4840 5386 0429 7484 7589 7645 0890 8043 6243 6252 6300

0433 3524 7486 7572 7608 7637

8518 8815 1666 1684 1707 1720 4844 4924 4937 4972 5079 5106 5127 5137 7432 7531 7559 7606 7658 7664 1319 3296 5986 1327 6243

8616 8971 1668 1690 1711 1722 4903 4932 4969 5058 5080 5107 5131 5143 7433 7533 7563 7609 7660 7665 3292 5756 6382 5988 6312

5104 5123

4903 4924

3740 6245 6247 6256 6258 6302 6304 8691 1674 1695 1716 4840 4906 4934 4970 5077 5100 5108 5135 7418 7436 7534 7589 7625 7662 7670 3293 5890 9051 5989

3117 3118 3131 3149 8051 0523 1352 1353 6069 5409 5410 5444 5470 5414 5446 5455 5412 5413 4637 6166 6685

d_errcnt d_major

4554 2436 4795 4927 6192 6710 d_minor 2436 5429 8039 8063 8093 9064 d_open 4618 6716 d_read 4638 d_sgtty 4640 d_strategy4620 4819 d_tab 4621 5077 d_write 4639 E2BIG 0473 EACCES 0479 EAGAIN 0477 EBADF 0475 EBIT 2658 EBUSY 0481 ECHILD 0476 ECHO 7969 ED 0318 edata 0611 EEXIST 0482 EFAULT 0466 6551 EFBIG 0492 EINTR 0470 EINVAL 0487 EIO 0471 8854 EISDIR 0486 EJECT 8842 EJLINE 8820 eloop 7592 else 1659 2579 3792 4823 5113 5748 6107 6304 6392 6522 8308 8662 EMFILE 0489

5463 4606 4819 4934 6234 6926 4605 5431 8040 8067 9021

5469 4763 4843 6113 6287 8213 4883 8026 8042 8072 9031

4636 6722 6234 8213 4763 5212 4843

5076 6113 6926 8245

eo

4785 4795

EOF ep

6287 3064 6778 3330 5740 2753 6135 3317 8047 1711 0651 5930 5326 7695 6424 2773 3620 4193 5819 8857 8927 7643 1909 2764 3815 4846 5141 5750 6251 6308 6471 6549 8444 8677 6833

4785 4906 6166 6680 5399 8030 8057 8081 9047

4906 4934

EMLINK end ENFILE ENODEV ENOENT ENOEXEC ENOMEM ENOSPC ENOTBLK ENOTDIR ENOTTY ENXIO

EPERM EPIPE EROFS err error

6630 2776 6163

ERROR esc

8361

5960 6378 6524

6157 5344 8751

ESPIPE ESRCH estabur

ETXTBSY EVENP EXDEV exec execnt

8923 8927

exit

7647 2087 3098 4445 4933 5411 5754 6257 6310 6486 7394 8471 8729

expand 2575 3100 4792 5029 5432 5879 6301 6375 6502 7608 8523 8886

EXPRI extern

falloc fetch ff file

0496 0611 0488 0484 0468 0474 0478 0493 0480 0485 0490 0472 8654 7524 7641 8612 7418 7435 0467 0497 0495 0855 1658 4219 4248 8618 8750 8891 8908 0494 0469 1629 3152 4460 0491 7973 0483 2923 0210 3196 3209 4278 1628 3383 4473 3018 1552 4097 5912 6184 5827 1051 1222 4368 5507 6854

5918 0632 6863 6569 7538 3102 1728 6989 6190 3547 8210 6193

filsys flag

0654 7311 7612

7121 7560 6727 8027

7588 7607 7608 7642 8689 8728 7432 7433 7434 6816 7827 6755 0872 1661 4226 4260 8691

0880 1663 4234 4281 8722

flushtty fmt fork FORM found found1 found2 fp

1656 1727 4241 8727

8895 8899 8903 5870 3652 4177 1650 3118 3138 3371 4120 4146 3106 6759 5937 3020 3037 3038 3039 3197 3198 3219 4032 4080 2268 3129 3132 3387 4148 4459 3038 3026 4925 5955 6794 6847 1173

3513 5768 6031 8650 7731 1180

3541 5784 6091 7737 1184

FPIPE FREAD

4382 5513 5807 6849 8204

free from

5561 4813 6364 7537 8648 8833 8863 8927 8227 2340 2914 8847 8928 3329 6156 1994 1983 5198 5204 5216 5733 5746 5752 5807 5836 5854 5869 5895 6018 6073 6621 6643 6854 6858 6961 6967 6975 6983 7005 7010 7015 7022 7042 7072 7077 7107 7117 7139 7758 7809 5519 7746 5517 5814 7000 6585

7042 4816 6373 7603 8652 8850 8866 8936 8252 2341 3322 8859 8930 3333 6160 2021 2031 5200 5206 5217 5736 5748 5754 5827 5848 5864 5889 5901 6019 6074 6626 6644 6855 6859 6962 6970 6976 6987 7006 7011 7018 7023 7045 7073 7084 7108 7118 7141 7759 8204 5746 7748 5713 5829 7435 6586

4820 6386 7657 8669 8853 8884

4823 7518 8023 8671 8857 8923

8346 8350 2348 2353 8865 8921 4176 4180

5202 5214 5219 5737 5749 5755 5829 5850 5866 5890 5902 6021 6078 6627 6648 6856 6860 6963 6971 6978 7002 7007 7012 7019 7025 7047 7074 7094 7113 7136 7143 7763 8206 5869

5203 5215 5220 5739 5751 5756 5830 5851 5867 5894 6016 6071 6079 6628 6849 6857 6959 6965 6972 6979 7004 7008 7014 7020 7026 7069 7076 7096 7116 7138 7144 7805 8208 6649

5747 5753 7748 7438 7442 6590

Sep

1 09:32 1988

fstat fubyte fuibyte fuiword

fun func fuword

FWRITE

f_count

f_flag

f_inode

f_offset

getblk

getc

geterror getf getfs getgid getmdev getpid getswit getuid gid GO grow gtime gtty gword hbcom

2940 0807 6550 0809 9034 0813 2734 4220 3845 7518 7574 0811 2763 8189 5518 5816 7746 1878 6655 7739 5509 5869 7748 5511 5894 6656 7810 5512 5889 6858 7774 3040 4789 6928 0926 8264 8673 4824 5736 6073 6754 7138 2959 6093 2932 2950 2936 3462 3467 5095 5461 2813 2925 2944 0818 5096

UNIX Operating System Source Code Cross Reference Listing Page 4

6014 0815 3058 4225 7693 0814 1564 4218 0844 1602 1604 2754 2756 2766 3870 7519 7579 0845 3052 8190 5722 5829

7532 8510 0847 4227

7536 8515 2758 8188

5793 5795 5832 6656

5510 5836 6079 6657 6855 6857

hibyte httab HUPCL HZ IACC IALLOC ialloc IALLOC ialloc IALLOC icode idle IENABLE

IEXEC

5739 5746 5829 6649 6656 7746

IFBLK

5754 5895 7747 8208 5751 5890 6859 7796 3237 4921 6981 0930 8292 8688 4992 5850 6619 6961 7167 3472 6151 3480 3413 3452 3464

IFCHR

5755 5830 6021 6650 7749 7764

IFDIR 5752 5901 7772 7798 4758 6123 7016 8258 8520 8714 5323 5866 8206 7004 7383

5756 5902 7773 4781 6304 7216 8259 8544 8971 5336 6018

IFMT

ifree iget iinit ILARG ILOCK

7072

6181

3465 3466

IMOUNT incore incupc IND info ino

5109 5138 5368 4056 4136 3420 8165 0830 0848 0851 5109

inode

0180 8585 4728 7966 0147 5681 7391 5620 7067 7463 7728 7752 1516 1283 5092 7981 8659 8814 3041 6764 5624 6242 6719 5623 6286 7421 3522 5818 3041 5621 6189 6297 8209 7134 1616 7276 1615 5625 7425 1617 7224 7316 7888 5682 4780 0894 8844 8142 7070 7100 7143 7315 5605 6161 6282 7105

3456 3476 3582 8593 4844 3797 3800 6232 6285 7382 7462 7751 5687 7459

1630 1284 5109 8051 8663 8858 3552 6765 5691 6297 7421 5690 6314 8209 3546 5921 3522 5688 6233 6682 7355 1618 7534 6922 5692 7445 1619 7225 7351

2220 5138 8052 8692

2423 5370 8615 8732

5631 5698 7563 6100 6189 6314 6688 6100 6233 6684 6713 5622 7559 3546 5818 6242 6711

5689 4110 5921 6286 7559

3519 7078 7664 6427 6444 5679 5926 7287 7303 7868 7872

6130 4788 0895 8857

6168 7292 4899 3791 8936

7077 7105 7276 7319 5659 6222 6416 7203

7078 7107 7286 7328 5675 6227 6793 7223

7095 7134 7297 6147 6277 7104 7278

inta integ

IO iodone iomove iowait ip

7285 3921 0175 3416 4892 8266 0641 5018 6260 4764 3024 3090 3171 3177 3185 3194 3522 3540 3549 3562 3570 3581 4096 4106 4118 4405 4433 4464 5771 5787 5795 5911 5921 5941 5958 5969 6034 6046 6053 6098 6131 6162 6170 6187 6194 6233 6248 6259 6286 6300 6315 6416 6440 6451 6467 6651

7345 4235 2070 3852 5006

7521 4254 2095 3872 5011

8205 2391 4885 8262

5404 6306 4800 3034 3105 3173 3182 3189 3512 3529 3543 3552 3564 3571 3582 4101 4109 4124 4406 4434 4470 5774 5790 5804 5914 5926 5942 5959 5972 6036 6050 6055 6100 6137 6167 6172 6189 6227 6234 6250 6282 6287 6302 6316 6422 6442 6452 6470 6652

5471 6364 4821 3035 3130 3174 3183 3190 3519 3530 3544 3555 3566 3577 3583 4102 4110 4126 4410 4446 5767 5783 5791 5805 5915 5935 5945 5966 6030 6037 6051 6089 6121 6147 6168 6183 6191 6229 6242 6252 6284 6297 6312 6318 6427 6444 6456 6646 6653

4982 3041 3142 3176 3184 3191 3520 3534 3546 3556 3569 3579 3584 4105 4112 4399 4411 4454 5770 5786 5793 5811 5917 5940 5954 5967 6033 6045 6052 6097 6130 6161 6169 6186 6192 6232 6243 6255 6285 6298 6314 6415 6439 6447 6466 6650 6672

ip1

ip2 ipc

IPCPRI iput

6673 6708 6758 6774 6799 6974 7017 7078 7085 7203 7217 7223 7227 7294 7307 7324 7415 7426 7457 7463 7467 7482 7733 7750 7764 7776 7787 7799 7817 7836 7848 7852 7882 8208 7280 7387 7395 7279 7378 3939 4184 4190 4195 4213 4227 4242 4264 4282 3914 3194 3549 4126 5936 6137 6802 7490

6678 6749 6764 6793 6801 6975 7018 7079 7091 7212 7218 7224 7281 7295 7309 7328 7420 7430 7459 7464 7468 7725 7741 7751 7768 7777 7789 7807 7825 7837 7849 7862 7883 8209 7328 7390 7397 7329 7388 4181 4185 4191 4209 4218 4232 4247 4266

6702 6751 6769 6796 6802 6976 7019 7081 7098 7213 7219 7225 7284 7296 7319 7332 7423 7442 7460 7465 7477 7728 7747 7752 7772 7778 7790 7810 7826 7838 7850 7863 7887 8213 7331 7392 7398 7330 7389 4182 4186 4192 4211 4220 4235 4249 4268

4182 3232 3554 4411 5945 6169 7091 7663

4190 3533 3571 5839 5972 6194 7325 7670

6703 6754 6771 6798 6959 7002 7069 7082 7101 7214 7220 7226 7293 7306 7323 7414 7424 7443 7462 7466 7478 7729 7749 7761 7775 7786 7797 7815 7835 7845 7851 7867 8205 7378 7393 7331 7390 4183 4189 4194 4212 4225 4240 4254 4273

3534 3584 5931 6037 6691 7344 7733

Sep

1 09:32 1988

ip_addr

ip_data

ip_lock ip_req IREAD ISGID ISOPEN issig ISUID ISVTX ITEXT itrunc IUPD

iupdat IWANT IWRITE

i_addr

i_atime i_count

i_dev

i_flag

7741 3937 4225 4242 3938 4227 4264 3935 4209 3936 4211 5629 7789 3176 7987 2073 3991 3171 3568 5790 3105 6758 4112 3530 5942 6467 7462 6050 5683 7890 4109 6651 7776 5613 6192 6302 6447 6470 6710 7423 5614 1883 6100 7317 7787 3519 6053 6422 7314 7426 7442 7662 1617 3570 5661 6168

UNIX Operating System Source Code Cross Reference Listing Page 5

4185 4227 4247 4184 4235 4266 4181

4218 4232 4249 4191 4242 4268 4183

4220 4240 4254 4220 4249 4273 4194

4186 4212 5696 7850 5627 8045 2085

4189 4192 4282 5815 6651 7851 5694 8046 2821 3826

i_gid i_lastr i_mode

5626 5693 4406 5628 5695 4410 4471 5684 5825 3570 6285 7382 7609 7226 7288

7353 3583 6318 7396 7751 7357 7869

7414 5680 6452 7448

5630 6753 7777 5672 6234 6439 6451 6679 7082 7430

5697 7604 7836 5969 6252 6440 6456 6680 7330 8213

5817 7658

i_size1

6191 6287 6442 6466 6709 7389

i_uid

7374 7889

3105 6681 7350 7825 5663 6162 6754 7355 7431 7459

4472 5662 7302 7306 7362 7750 5935 6250 7104 7383 7435 7534

6051 6300 7286 7386 7438 7625

1619 3583 5926 6232

3105 4410 5942 6285

3530 4471 6130 6318

i_mtime i_nlink i_number

i_size0

j jflg jmp jsr k ka6

kill KISA0 KISA6 KISD0 KL kl11 KLADDR KLBASE klclose klin

6452 7225 7303 7382 7462 7869 7890 3177 6771 5673 3041 3546 4406 5921 6242 6427 6711 7082 7421 7559 7789 8209 5615 3529 5941 5664 7105 7360 5611 6312 5612 6312 7772 3173 5668 7070 1018 0522 0558 0570 7070 0322 1589 9065 2949 0619 1368 0620 0165 2399 8015 8067 8008 8009 4671 0558

6467 7287 7316 7391 7609 7872 3582 7466 6255 3171 3566 5607 6100 6286 6444 6764 7329 7425 7752 7836

6758 7288 7351 7396 7751 7888

7224 7292 7359 7448 7868 7889

5610 5669 6259 3176 3569 5666 6189 6297 6651 6774 7354 7445 7776 7850

7318 3522 4110 5818 6233 6314 6682 7081 7388 7463 7777 7851

klopen klou klrbuf klrcsr klread klregs klrint klsgtty kltbuf kltcsr klwrite klxint kwlp l large lbn lbolt LCASE ldiv

5608 7352 6051 7286 7385 5670 6315 5671 6316 7775 3174 6769 7099 1193

5667 7464 6052 7315 7482 5894 7446 5895 7447 7835 3581 6798 7101 1239

0561 0574 7103 1459 1599

0564 0577 7104 1460 2716

5917 6162 7355 7534 6243 6243 7589 7845 5609 7465

link lks lobyte

loop

0567 lp11 7105 1560 9032

3630 1460 LPADDR 2393 2406 8030 8072 8039 8041 8055

2397 2398 8057 8063 8081 8093 8041 8043

lpbuf lpcanon lpclose LPHWAT lpint LPLWAT

4671 0561 8018 8017 4671 8016 0557 4671 8020 8019 4671 0560 0570 2354 6445 6225 6259 0212 4925 7968 8399 1392 5434 7589 2921 0226 1604 0180 3464 8584 1951 2048 2362 3315 4945 5242 7283 7791 8290 8837 8884 8924 8931 8941 8952 8960 8982 8812 8972 8825 8859 8909 4675 8819 0573 8818

8023

lpopen lpou lpoutput

8083 8051 8084 8062

LPPRI lpsr lpstart lpwrite lrem

0558 8078 8090 8086 8052 8066 0561 8070

lshift main maj

6462 6239 6280 3797 8650 8047 1393 6051 7626 5909 1601 1607 3443 3465 8592 1957 2195 3245 4020 4957 7075 7290 7812 8305 8853 8910 8925 8935 8942 8954 8962 8988 8853

6248 6255 3800 3808 8660 8309 8353

maknode malloc map

2373 4143 7319 7386

mapalloc mapfree maplock

1602 1603 3734 3444 3455 3475 3581

maptab max MAXCOL MAXMEM maxmem MAXMEM maxmem mcc

1969 2221 3260 4030 4964 7092 7298 7839

2025 2347 3276 4930 5233 7119 7765 7854

8857 8918 8926 8936 8946 8955 8971 8989 8858

8866 8923 8927 8937 8950 8957 8981 8990 8971

8972 8865 8875 8879 8863 8988 0574 8976 8981

mfree

min mknod mlc mmread mmwrite mode mount

mp

4675 0574 8929 8986 8817 8824 8967 4675 1400 6052 1409 6294 0611 6676 6706 6720 4105 1896 3234 2515 2559 5156 5025 5155 5169 8117 6326 8821 0135 0224 1582 1582 8834 8952 1568 2293 4383 1582 6339 2926 8836 8931 4682 4682 5731 6746 0272 6148 7169 7281 2528 2557 6103 6116 6148 6170

8850 8951 8956 8959 8989 8853 8980 8870 1401 7328 1410 9024 0669 6680 6710 6722 5790 1982 4375 2529

8858 8971 8992 2375 7387 5309 9055 1550 6685 6714

5433 6239

6689 6716

5966 7455 2282 2528 4457 2532 2557

5398 5182 5165 5166 5167 5187 5188 5189 8309 8311 8443 8954 1567 1576 1662 8924 8955 1583 2556 4408 6241 7846 5952 8924 9016 9042 5735 6752 0277 6154 7172 7293 2529 2564 6104 6118 6154 6171

8925 8957 2044 3241 4497 6247

8950 8960 2278 3283 6296

8926 8927

5804 7455 6090 6933 7204 7294 2534 2565 6105 6124 6155 7204

5812 7463 6103 6934 7210 2556 6090 6109 6129 6167 7210

Sep

1 09:32 1988

mpid MTC m_addr

m_bufp

m_dev m_inodp m_size

n1 n2 na namei

nb

nblkdev nbp NBUF nc NCALL nchrdev NCLIST nd

NDL11 newproc newsize NEXEC NFILE nice NINODE NKL11 NLDELAY

7211 0216 1849 1373 2518 2564 2576 0275 6125 6933 7212 0274 6934 0276 2517 2542 2568 2578 7170 7170 3022 3156 3034 5770 5958 6796 5265 5306 6450 6472 6498 4631 6720 6420 6490 0130 3022 3071 0143 4647 0146 1650 1683 1692 8012 1627 2268 2282 0134 0132 2946 0131 7223 8011 8043 7974

UNIX Operating System Source Code Cross Reference Listing Page 6

7212 7216 1841 1842 1843 1867 2536 2565 2577 6104 6155 7173

2537 2567 2580 6123 6170 7174

2541 2571 2581 6124 6171 7211

6105 7173 6121 2534 2564 2569 2583 7175 7176 3050 3158 3515 5786 6033 7518 5278 6419 6451 6479 6499 4927

6122 7216 6167 2535 2565 2572 2584 7177 7177 3053

6155 7296 7295 2538 2566 2576

5283 6447 6457 6488 6507 5084

5292 6448 6466 6497

6480 6497 4535 3051 3073 0265 6714 8146 1657 1687

6484 6498 4720 3062 3154

6488 6500 5064 3063 3157

NODEV nodev

NODEV nodev NODEV nofault

NOFILE 3154

nospace nosys

3543 4101 5914 5928 6097 6186

notavail notavil NPROC

6192

8247 8240 1660 1662 1689 1690

8015 8026 1826 3334 2275 2277 2278 3037 5513 3493 5675 7285 8015

NMOUNT

3196 6854 6161 7103 8026 8042

nps NRK NRKBLK ns

nseg NSIG nswap nt NTEXT NULL

0133 7172 0105 4659 4663 4675 4680 4686 4690 5238 6566 6928 0757 0871 0909 1225 1267 1466 0139 6624 6966 2855 2951 2962 2966 2970 2974 4948 4999 0144 1991 2206 3327 4023 2693 5364 5365 1650 1703 1711 1657 0113 3619 0232 1650 1667 0145 0104 1852 1979 2198 3229 3516 3579 4401 4442

0277 7210 3040 4660 4664 4677 4681 4687 4691 6123 7230 0766 0872 0910 1228 1273 0438 6828 6969 2939 2952 2963 2967 2971 2975 4960 0376 2006 3246 3639 4172 3725

6103 6154 7294 4661 4665 4678 4682 4688

0854 0876 0918 1232 1277

4662 4673 4679 4684 4689

0855 0881 1224 1259 1465

1876 3227 6986 2941 2957 2964 2968 2972

2945 2961 2965 2969 2973

5240 1846 2120 3250 3810

1960 2203 3277 3953

nulldev nullsys o1 o2 ODDP ok on

open OPEN open1 openi os out

5402 1657 1660 1662 1704 1706 1710 1660 0447 3968 1583 1657 1671 4314 1752 1877 1982 2218 3235 3520 4102 4402 4443

1771 3366 3183 3225 4698 1660 1673 4441 1833 1879 2032 2283 3284 3544 4106 4407 4451

1662 1674 1847 1902 2184 3035 3328 3564 4376 4440 4457

out1 owner p1

p2

4495 5787 5851 5929 6034 6104 6171 6448 6482 6796 6853 7080 7284 7326 7601 7665 7732 4658 2864 2447 2447 7972 4256 6225 6280 9018 9056 2917 8843 5774 5832 4368 4383 2735 3331 3749 4474 5919 5944 6106 7539 7581 7669 6119 3564 1942 2015 3326 3769 3775 3853 3859 3870 3324 3727 3753

4935 5791 5853 5959 6074 6108 6187 6468 6497 6797 6864 7122 7306 7460 7610 7666 7738 4682 2912 2454 2454

5737 5827 5867 5967 6098 6111 6435 6469 6627 6803 6990 7173 7309 7461 7623 7671 7740 4684 2942

5771 5835 5915 6019 6102 6155 6436 6480 6631 6829 7079 7211 7312 7590 7655 7729 8206 6577

4259 6240 6295 9025 9067 5765 8853 5793 6702 4373

4261 6241 6260 6296 6306 9034 9044

2779 3346 3760 5823 5922 5961 6112 7549 7605 8690 6136 3579 1963 2032 3335 3770 3776 3855 3860 3871 3327 3750 3773

2814 3523 3787 5828 5934 5971 6115 7561 7613 8696

pad panic

panicstr partab passc pc pc11

PCADDR

8857 5795 5804 4374 4380

6791 1977 2041 3727 3771 3777 3856 3863

2820 3532 4449 5838 5938 6101 6134 7564 7659

2010 3324 3768 3774 3847 3857 3869

3328 3344 3751 3752 3774 3775

pcclose PCIHWAT pcin PCIPRI pcleader PCOHWAT PCOLWAT pcopen PCOPRI pcou pcout pcoutput pcpbuf pcpcsr pcpint pcrbuf pcrcsr pcread pcrint pcstart pcstate

pcwrite physio PINOD pipe PIPSIZ

3776 3861 3865 5575 1605 2719 4381 4936 2328 7947 6394 9038 2693 2757 8641 8658 8689 8724 8731 8754 8607 8691 8722 8750 4673 8624 0564 8693 8620 8664 8623 8622 4673 8621 0567 8644 8754 8706 8630 8629 0566 8628 8627 8692 4673 0563 8710 8642 8675 8726 4673 5259 0155 7289 2954 7715

3778 3847 3860 3862 3863 3864 3866 3867 1853 3236 4451 6930 2419 8424 6517

2051 3521 4458 7184

2734 2766 8645 8673 8693 8726 8734 8755 8659 8692 8727

2754 2767 8653 8675 8714 8728 8743 8756 8663 8714 8730

8669 8731 8643 8730 8660 8678 8754 8743 8648 8755 8714 8755 8748 8715 8663 0567 8730 8659 8722 8682 0564 8742 8653 8689 8728 8701 5479 6963

2416 4377 4928 7300

8522 8544 8695 2756 3725 8657 8688 8721 8730 8744 8674 8715 8732

8673 8688 8731 8734 8693 8763

8743 8744 8756 8769 8714 8750 8739 8674 8691 8727 8732 8719 8758 8657 8658 8721 8724

5486 7007 7074

7723 7835 7846

Sep

1 09:32 1988

plock pp

PPIPE prdev prele

pri PRIBIO printf

printn proc

procxmt profil PS

ps PS

ps

PS

7768 2158 2167 3518 3728 3810 3814 3818 4025 0157 2433 7120 3518 7227 7799 7849 2066 0156 5297 1576 1580 2454 6862 2355 0358 1591 1830 1960 2119 2185 3222 3273 3632 3810 4018 4028 2956 0164 0691 0726 0748 0783 0791 0798 0870 0934 0970 1005 1294 1305 2070 2693 2776 3791 3852 5006

UNIX Operating System Source Code Cross Reference Listing Page 7

7815 2160 3512 3519 3794 3811 3815 4018 7790 2453 7178 3556 7358 7817 7882 2072 4943 5316 1577 2340 2716 7310 2369 0376 1592 1846 1991 2136 2193 3246 3277 3639 3951 4023 4204 3667 0668 0697 0731 0756 0787 0852 0877 0935 0973 1285 1298 1309 2095 2699 3725 3798 3872 5011

7862 2161 3515 3528 3795 3812 3816 4023

psig 2162 3516 3533 3796 3813 3817 4024

7838 7870 6988 7048 5826 6131 7363 7786 7826 7837 2078 2091 4955 4990

psignal PSLEP PSWP ptrace PUSER putc

putchar PWAIT pword p_addr

1578 1579 2421 2436 2717 2718 2374 1589 1593 1942 2006 2180 2206 3248 3324 3644 3953 4166

1590 1829 1943 2115 2182 2207 3250 3327 3728 3994 4172

0677 0700 0735 0773 0790

0679 0720 0741 0777

0853 0882 0958 0974 1286 1299 1310

0869 0932 0964 0999 1288 1304 1314

2717 3759 3824 4885 8262

2753 3788 4892 8266

p_cpu p_flag

p_nice p_pid

p_ppid

p_pri p_sig

p_size

p_stat

2074 3827 2793 3963 0159 0154 5204 2938 0160 3974 0926 8358 8756 2351 2401 0158 0840 0371 1904 2045 2290 3242 4149 4467 0366 3814 0361 1961 2046 2241 3289 3998 4379 4479 0367 0369 3251 3304 3642 4175 0370 3252 4024 0362 2167 0363 3626 4000 0372 1978 2275 4149 0360 1903 2008 2208

2086 4043 2818 7828 5994 1955 5215 4164 2162

2105 2822

0967 8414 8990 2359 2402 3314 0865 1589 1913 2193 2294 3282 4380

8323 8355 8478 8730

2161 3815 1592 1992 2143 2286 3302 4028 4385 5312 1865 1849 3278 3335 4022 4183 1868 3259 4175 2078 2209 3287 3971 4049 1590 2042 3241 4374 1591 1908 2077 3243

3795 3816 1862 2007 2208 3170 3303 4169 4466 5317 2162 1867 3281 3344 4024 4209 3247 3278

3649 3955 p_textp 1968 5167 p_time 3817 3973 p_ttyp

2375 2386 2403 2405

p_uid p_wchan q

0868 1743 2042 2228 3134 3376 4383

2091 2211 3305 3972 4050 1893 2044 4119 4375 1847 1961 2090 3253

1894 2044 2276 3241 3388 4384

qc ql r

3796 1907 2023 2240 3224 3309 4187 4468 3502 3247 3285 3482 4174 3251 3286 2141 3817 3625 3997 4273 1895 2274 4148 1861 1993 2140 3280

R0 r0 R0

r0 R0

R1 r1 R1 r1 R1 R2 R3 R4 R5 R6

3284 3973 4173 0374 1979 4402 0365 2009 3813 0368 3954 0364 3646 0373 2139 3221 3228 3242 3259 3644 5393 5393 0185 1574 1750 5175 7736 8413 9027 9035 9062 9069 2605 2693 3208 3344 3443 3475 3623 3725 4079 5758 5866 6830 8206 2606 2693 3297 3725 7744 2607 2608 2609 2610 2611 4059

3301 3328 3811 3974 3975 4026 1752 2032 4448 1869 2011 4386 1864 8031 1863

1866 4378 4469 1962 2047

1879 4401

R7 rablkno rablock rabp

1964 3812

3288 3644 8032 3174 3446

RAW rbp

2076 2089 2122 3225 3229 3243 3632

3226 3240 3247 3638

3227 3241 3251 3640

1561 1599 1755 5177 7740 8934 9029 9036 9063

1563 1600 1760 5306 7745 8951 9030 9059 9065

1573 1745 2401 7726 8342 9026 9032 9060 9068

2679 2701 3281 3416 3455 3476 3637 3825 4184 5831 5986 7736

rbr rc 2777 3304 3423 3456 3482

4191 5850 6018 7744

3335 3432 3464 3497

5736 5853 6073 7745

RCOM rdflg RDRENB rdwr read readi READING readp regloc

2679 3305 3424 3433

2679 2679 2679 2679 2679 3155 4055

RESET retry retu returm rexit rf

rfp

2612 4058 4773 0235 6456 4775 4793 7971 8386 2450 4756 4761 4765 4782 4798 4815 4819 4839 4847 4862 4876 4887 4891 4990 5008 5023 5027 5101 5110 5134 5140 2316 2388 2400 5094 5196 8014 8659 5713 2915 3090 6221 8611 5748 0237 1148 5367 1840 0724 2294 7468 2913 6621 7725 7748 6646

2679 4061 4788 6253 6504 4789 4794 8297

3188 3347

2452 4758 4762 4775 4783 4800 4816 4821 4842 4848 4863 4877 4888 4985 4992 5009 5024 5028 5105 5111 5136

2453 4759 4763 4779 4784 4801 4817 4822 4843 4859 4872 4882 4889 4987 5002 5010 5025 5030 5107 5128 5137

4789 6256 6454 6506 4790 4791 4795 8344 8356 2454 4760 4764 4781 4785 4812 4818 4824 4845 4861 4875 4883 4890 4989 5005 5021 5026 5031 5108 5132 5139

2390 2395 2399 5112 5206 8051 8692 5722 5711 3142 7797 8724 7758 1011 2677 5461 1844 0740

8084 8614 8732 5731 4464 5754 8726 1025 1038 3186 4258 1850 2193 2228

3205 6623 6624 6626 7731 7732 7739 7749 6648 6649 6650

Sep

1 09:32 1988

6655 5121 5123 5120 1831 1864 1876 1894 5808 5818 5832 6679 6691 6710 RKADDR 5363 rkaddr 5420 RKADDR 5447 rkaddr 5447 RKADDR 5459 rkba 5381 rkcs 5379 rkda 5382 rkds 5377 rker 5378 rkintr 0576 rkio 0577 rkread 4684 rkstart 5415 rkstrategy4658 rktab 4658 5412 5446 5463 rkwc 5380 rkwrite 4684 RO 0315 rootdev 0228 6926 rootdir 0206 ROOTINO 0106 rp 1741 1751 1761 1960 1964 1980 1993 2009 2023 2034 2041 2046 2076 2090 2139 2182

RHRCOM rhstart RHWCOM rip

UNIX Operating System Source Code Cross Reference Listing Page 8

6656 6657 5141 5142 1859 1865 1877 1903 5811 5825 5839 6680 6705 6711

1860 1866 1892 1908 5815 5826 6675 6681 6708

1863 1868 1893 1917 5817 5830 6678 6682 6709

5460 5461 5462 5459 5461 5462 5447 5460 5460 0577 5451 5476 5440 5389 5386 5413 5455 5469 5483 1668 1616 6927 1616 1616 1745 1755 1762 1961 1977 1981 2006 2010 2024 2036 2042 2047 2077 2091 2140 2197

5464 5479 5409 5414 5457 5470

1674 1618 6934 1617 1618 1748 1758 1763 1962 1978 1991 2007 2011 2032 2037 2044 2068 2078 2136 2141 2205

5472 5486 5410 5444 5458

rpp

RPS 4695 7728 7533 7297 1750 1760 1943 1963 1979 1992 2008 2015 2033 2039 2045 2071 2089 2138 2143 2206

rrkbuf rsr rtp

runin

runout

runrun RW rw

2207 2211 2240 3971 3975 4049 4374 4380 4386 4444 4467 4471 4496 7350 7354 7359 7378 7385 7391 7421 7430 7442 7448 7772 7798 7865 7870 7888 1830 1849 1863 1867 1878 1890 1906 2613 4262 5387 2315 8377 8392 8412 8440 8478 0218 2081 3822 0219 2144 4389 0220 2166 0317 1711 5259 6689

2208 2219 2241 3972 3976 4050 4375 4383 4437 4451 4468 4472 4497 7351 7355 7360 7381 7386 7396 7423 7431 7445 7761 7773 7807 7867 7872 7889 1846 1852 1864 1868 1879 1891 1907 2679

2209 2223 3966 3973 4046 4370 4378 4384 4440 4465 4469 4493 7347 7352 7357 7362 7382 7388 7417 7425 7435 7446 7763 7774 7809 7868 7885 7890 1847 1861 1865 1869 1880 1895 1913 4057

2210 2228 3970 3974 4048 4372 4379 4385 4443 4466 4470 4495 7349 7353 7358 7363 7383 7389 7420 7426 7438 7447 7764 7796 7810 7869 7887 7891 1848 1862 1866 1877 1881 1904 4060

5479 5486 8381 8393 8413 8452

8386 8399 8414 8463

8390 8403 8423 8468

savfp savu

sbreak schar sched SCHMAG seek sep

SETD setgid setpri setreg setrun setuid sgtty si SIDL sig SIGBUS SIGEMT SIGFPT SIGHUP SIGINS SIGINT SIGIOT SIGKIL signal SIGPIPE SIGQIT SIGSEG SIGSYS SIGTRC SINCR size

1954 1955 2080 2082 3820 3821 sleep 1967 1968 2143 2145 4387 4388 0770 0788 2142 2196 3807 1684 1690 1707 5299 6672 6685 6702 6716 6722

SLOAD

0888 0724 2189 4476 2929 1552 1637 3707 2931 1650 1714 3118 2660 2958 2156 1089 1196 2123 3976 2935 8171 4139 4148 0385 3949 3972 0123 0120 0121 0114 0117 4067 0115 0119 0122 3949 0126 0116 0124 0125 0118 0138 2528 2556 2577 2586 1955 3314 4955 5215 6963 7790 8287 8755 0391 1992

0889 0725 2281 4477 3354 4097 1940 3814 5861 1654 3023 3151 2734 3460 2823 1099

2698 1889 1905 2284 2846

2134 4188 3439 8191 4143 4152 1903 3955

3254 3310

4101 7679 3815 1677 1698 3094 3100

SLOCK

sloop slp0 slp6 SMAPSIZ smount smp

sp 3818 3828 1117 1120

8201 4144 4146 4154 4156

spl0

spl1 spl4

3963 3968 spl5

2722 4072 2748 4070 2793 2797 4071

spl6

2734 2736 4053 spl7 8345 2744 3619 8345 7828 4066 2815 2781 2740 4143 2535 2566 2578

4069 3971

sps

SRUN 8345 4073 4074 4053 4068 2537 2538 2567 2576 2579 2584

ssig SSIZE SSLEEP sslep ssr

SSR0 1968 4182 4990 5297 7007 7838 8563 8989 1592 2007

2066 4190 5167 5316 7074 7870 8660

3038 4943 5204 5994 7289 8225 8693

1862 1961 2023 2046

SSR2 SSTART SSTOP SSWAP SSYS start

2143 0393 4385 5317 1953 2022 1990 0142 2933 6090 6111 6124 6128 2693 4137 1292 2092 4959 5245 8228 8697 9070 1292 1292 8757 1292 8222 1292 2088 4988 5213 1292 9028 4873 5006 8266 0384 1961 2960 0137 0382 2947 0759 1021 1150 0613 0765 0760 7988 0387 4026 0394 2286 0392 0521 0614

2208 4385 1992 2007 4379 4466 4468 5312 2004 2014

0204 6086 6102 6108 6109 6121 6122 6123 6125 6126 6127 2811 4141 1293 4944 4991 5320 8289 8759

3725 4143 1976 4947 5170 5416 8565 8993

1297 1302 8991 1303 8263 1308 4886 5007 5234 1313 9061 4885 5011

3803 8672 8686

1591 2008 3614 3118 2008 5979 0760 1023 1171 0647 1354

1861 1908 2140 2208

8514 1993 4173 1907 4479 1592 0522

3766 8283 1958 4940 5164 5294 3854

4136 2079 4956 5218 5996 8676 9037

5408 8559 2075 4952 5201 5314 5983

4892 5003 8256 8262

3131 3150 2090 1013 1028 1465 0759

1016 1050 1467 0761

3253 3301 2240 2241 1992 2007 0611 0612

Sep

1 09:32 1988

stat stat1 static stime stop str strat STRC stty subyte suibyte suiword sumount sureg suser

suword

SW SWAIT swap swapdev swaper swapmap swbuf swplo swtch

SWTED sync SYS sysent SZOMB s_flock

s_fmod s_free s_fsize s_ilock

2930 6021 2180 2937 3999 2433 5259 0395 3998 2943 0807 0809 0813 2934 1724 3431 3522 6800 0811 3159 4058 6059 0166 0383 2034 5196 0229 5207 2035 0204 3283 4721 5209 0231 0770 2178 4480 0396 4187 2948 2661 2667 2755 0386 5570 6963 7006 7023 5572 7084 5567 7019 5564 5571 7074 7139

UNIX Operating System Source Code Cross Reference Listing Page 9

6028 6036 6045 3428 4016 2436 5261 3170 4028 8183 0827 0826 0860 6144 1739 3444 3579 6811 0861 3164 4247 8175 2391 1993 2042 3237 5212 2043 1583 4375 5200 5210 1583 0791 2287

s_inode s_isize s_nfree

5313 3224 3309 4169

s_ninode

s_ronly 3161 6523 9067 4240 4242 2229 2295 3465 3500 5921 5957 0864 3661 4249 8176 3416 2077 4380

3156 4057 6055 8177 3975 4467

3282 4696 2050 2044 4408 5207 5211 4697 2084 3256

3234 4457 5208 5212 2093 4027

s_time t00 t01 t02 t03 t04 t05 t06 t07 t10 t11 t12 t13 t14 t15 t16 t17 TBDELAY TBIT text tim time

3302 3303 3309 3486 2759 2670 2761 3243 6127 6972 7007 7214 6983 7144 6967 7025 7047 6126 7094 7213

2696 2910 3280 6936 6978 7015

2754

6962 6979 7022

7005 7026 7213 7217 6976 7012

timeout TIMEOUT timeout TIMEOUT times tm tmtab to tout

tp 6937 7073 7116 7117

5569 5563 5565 6975 7014 7175 5568 7108 7143 5573 7214 5574 7219 1056 1056 1056 1056 1056 1056 1056 1056 1062 1057 1057 1057 1057 1057 1057 1057 7975 2615 1240 4441 3845 0213 3433 3806 5989 7218 7392 3845 7984 8524 8525 2955 7374 4727 6585 0214 5989 5994 3949 8032 8046 8056 8071

7077 7047 6965 6987 7018 7179 7076 7113 7176 6128 7383 6939

7107 7096 6967 7010 7020

7143 6971 7011 7025

7077 7107 7118 7141 7180 6754 6938 6940 7218

1059 1079 1085 1101 1102 1103 1104 1105 1106 1093 1110 1111 1112 1113 1114 1107 1140 1188 4060 4306 4314 4436 3851 3423 3801 5984 6050 7219 7393

3424 3802 5985 6939 7226

3432 3804 5988 6940 7357

8491 8518

3656 7376 4844 6586 3434 5990

6591 3804 3805 5991 5992

3954 8033 8047 8057 8072

8025 8044 8048 8058 8073

7397 7398

8030 8045 8049 8059 8074

8075 8087 8220 8225 8258 8264 8284 8294 8309 8341 8350 8359 8374 8491 8513 8520 8540 8553 8561 8568 8584 8591 trap 0555 0762 trap1 2771 trf 5804 ts 3023 4437 4459 5275 tst 0604 TTHIWAT 7961 TTIPRI 7951 TTLOWAT 7962 TTOPRI 7952 ttrbuf 8157 ttrcsr 8156 ttread 8063 ttrstrt 8486 ttstart 8073 8561 tttbuf 8159 tttcsr 8158 ttwrite 8067 tty 7926 8071 8220 8279 8377 8536 TTYHOG 7963 ttyinput 8087 ttyoutput 8362 8413 ttystty 8094 t_addr 7932

8080 8092 8221 8227 8259 8265 8285 8297 8321 8345 8355 8362 8381 8492 8514 8524 8541 8555 8562 8580 8585 8592 0752 2693 2841 5813 3116 4455 4460 5277 0605 8560 8287 8074 8225

8535 8524 8363 8568 8522 8518 8550 8015 8080 8253 8334 8488 8538 8349 8333 8373 8566 8577 8044

8081 8093 8223 8255 8260 8279 8287 8299 8337 8346 8357 8363 8488 8509 8515 8525 8543 8556 8563 8581 8586 8593 0754

8082 8094 8224 8257 8261 8282 8292 8304 8339 8349 8358 8373 8490 8512 8518 8538 8544 8560 8566 8583 8589 8594 0755

t_canq t_char t_col t_delct t_dev t_erase t_flags

t_kill t_outq

t_rawq

t_speeds t_state 5824 3118 4456 4467 5283

3148 4457 5266 5291

8563

8492 8505

8025 8092 8255 8337 8506 8551

8056 8218 8275 8374 8509 8553

8392 8403

8082 8513

u

7929 8544 7940 7935 7934 8359 7942 7936 8592 7931 8336 8353 8390 8452 8594 7937 8593 7930 8225 8478 7928 8292 8358 7941 7938 8224 8518 8562 0459 0744 1618 1678 1716 1721 1752 1883 1917 2242 2701 2766 2774 2812 2846 3056 3087 3092 3099 3106 3134 3148 3152 3173 3187 3224 3238 3291

8258 8321 8543

8393 8423 8265 8284 8294 8033 8048 8299 8584 8047 8341 8356 8399 8463

8297 8342 8361 8412 8468

8309 8344 8386 8440 8586

8049 8304 8585 8074 8259 8520 8260 8349

8075 8261 8560 8264 8355

8223 8414 8563 8287 8357

8583 8045 8285 8525

8591 8046 8059 8491 8514 8541 8556

0646 1440 1619 1694 1717 1728 1754 1889 2071 2273 2734 2770 2775 2818 2848 3064 3088 3095 3101 3116 3139 3149 3155 3174 3188 3225 3240 3292

0659 1441 1665 1699 1719 1743 1859 1891 2106 2281 2752 2772 2777 2823 2857 3085 3089 3096 3102 3117 3140 3150 3170 3177 3189 3227 3278 3293

0662 1593 1666 1715 1720 1744 1876 1905 2189 2284 2763 2773 2793 2845 3052 3086 3091 3097 3105 3127 3141 3151 3172 3183 3208 3232 3281 3294

Sep

1 09:32 1988

3295 3305 3330 3338 3344 3366 3373 3389 3432 3445 3456 3467 3497 3525 3554 3569 3620 3626 3649 3662 3673 3793 3996 4051 4057 4061 4100 4114 4119 4127 4148 4168 4177 4191 4254 4273 4448 4463 4478 5275 5306 5317 5344 5744 5756 5788 5831 5853 5875 5927 5936 5966 6021 6094 6117 6157

3296 3314 3335 3339 3347 3369 3376 3416 3433 3446 3464 3475 3502 3526 3555 3581 3623 3637 3652 3670 3789 3794 4003 4052 4058 4075 4103 4115 4121 4141 4149 4169 4184 4193 4255 4401 4455 4465 4479 5276 5309 5322 5736 5745 5758 5790 5833 5866 5876 5930 5937 5969 6036 6096 6128 6163

UNIX Operating System Source Code Cross Reference Listing Page 10

3297 3317 3336 3340 3364 3370 3378 3423 3443 3447 3465 3476 3519 3527 3567 3582 3624 3638 3660 3671 3790 3825 4021 4054 4059 4079 4111 4116 4122 4143 4150 4174 4185 4209 4258 4402 4461 4476 5269 5291 5310 5326 5740 5751 5773 5819 5835 5870 5880 5933 5960 5986 6073 6113 6135 6190

3304 3326 3337 3341 3365 3371 3388 3424 3444 3455 3466 3482 3524 3547 3568 3618 3625 3646 3661 3672 3791 3828 4048 4055 4060 4099 4113 4117 4123 4146 4156 4175 4186 4235 4262 4439 4462 4477 5273 5292 5312 5343 5743 5752 5774 5822 5850 5873 5918 5935 5964 6018 6078 6114 6152 6193

u0 u1 u2 u3 u4 u5 u6 u7 ub UBMAP uchar

UDSA

6230 6244 6295 6313 6372 6381 6521 6527 6531 6550 6556 6630 6763 6798 6830 6929 7459 7483 7488 7538 7571 7585 7600 7622 7639 7646 7695 7745 7811 7844 8027 8174 8190 8654 9025 9050 9057 1067 1067 1067 1067 1067 1067 1067 1067 6045 6060 0311 5177 3026 3541 5784 5928 6033 6186 0308

6239 6262 6296 6315 6374 6382 6522 6528 6546 6551 6557 6727 6769 6814 6833 6989 7465 7484 7489 7548 7572 7586 7606 7626 7640 7664 7736 7795 7818 7845 8031 8187 8206 8751 9038 9051

6240 6290 6307 6316 6376 6383 6523 6529 6548 6554 6569 6755 6771 6816 6856 7121 7466 7486 7490 7560 7576 7587 7608 7636 7642 7682 7740 7796 7827 7846 8032 8188 8210 8854 9048 9055

6241 6294 6309 6319 6378 6424 6524 6530 6549 6555 6626 6759 6778 6829 6863 7311 7482 7487 7531 7570 7580 7589 7612 7638 7645 7693 7744 7798 7828 7847 8172 8189 8590 9024 9049 9056

1096 1189 1190 1191 1087 1071 1075 1097 1069 1192 6055 6056 6059

ufalloc uid UISA

UISA0 UISA1 UISD

UISD0 UISD1 UMODE unlink up

update updlock user USER

USIZE

u_ar0

1573 1574 5175 3034 3543 5786 5955 6091 6794 5306

3513 5768 5912 5958 6097 6796

3515 5770 5914 6031 6184 7689

u_arg

6076 3441 3446 0306 1750 9029 9062 0678 0701 0699 0304 1760 9036 0681 0705 0704 2659 3824 2922 1741 1752 1761 1892 8174 8185 8190 2420 0234 7229 0413 2662 2739 2796 0103 1560 1682 3370 4459 0452 3187 3297 3344 3424 3455 3476 3637 4058 4079 4262 5850 6018 7744 0440 3052 3096 3105

6824 3443 3447 1563 1763 9032 9065 0680 0719 0702 1561 1763 9060 0682 0717 0706 2699 3510 1744 1753 1829 2156 8175 8187

6852 3444 3445 1599 5306 9035 9068 0690 0718 1600 9027 9063 0689

1745 9026 9059 0698

1755 9030 9069 0703

u_base

0716 3706 3788

1747 1754 1860 2160 8176 8188

1751 1757 1879 8168 8177 8189

u_cdir u_count

3489 6150 7201 1559 7207 7209

2700 2743 2810 0636 1590 3129 4116 4467 2701 3188 3304 3347 3432 3456 3482 3825 4059 4184 5736 5853 6073 7745 2763 3056 3097 3116

2721 2733 2747 2751

u_cstime u_cutime

0646 1628 3131 4119 4473 2812 3208 3305 3416 3433 3464 3497 4055 4060 4191 5758 5866 6830 8206 2766 3085 3099 3117

0662 1662 3133 4233 3155 3281 3335 3423 3443 3475 3623 4057 4061 4258 5831 5986 7736 2770 3095 3101 3140

u_dbuf u_dent

u_dirp u_dsize u_error

3141 3568 3618 3662 3673 4174 4455 5756 5790 5880 6021 6128 8189 0425 4115 5743 6381 6549 9050 0428 3232 0426 4116 5291 5756 6262 6383 6554 7639 7847 0451 3294 0450 3339 0429 7576 0434 7482 7640 0430 6096 0442 3371 0419 2774 3064 3317 3652 4127 5343 5819 5918 5960 6117 6163 6307

3208 3569 3624 3670 4075 4185 4461 5758 5873 5927 6036 8174 8190 3085 4121 6372 6522 6550

3297 3581 3649 3671 4079 4186 5743 5773 5875 5966 6096 8187 8590 3139 4463 6374 6523 6557

3364 3582 3661 3672 4168 4439 5744 5774 5876 5969 6113 8188

1618 3554 3086 4122 5310 5758 6290 6527 7486 7811 9048 3291 3336 3294 3340 7484 7645 3519 7483 7646 2770 7682 3149 3373 1728 2775 3092 3330 4052 4177 5344 5822 5930 5964 6135 6190 6319

1619 3555 3141 4461 5322 6230 6296 6531 7589 7818 9049 3292 3337 3295

1883 7531 3526 5273 5744 6241 6319 6546 7600 7846

7570 7646 3525 7488 7664 4100 7693 3152 4146 2752 2777 3102 3547 4099 4193 5740 5833 5933 6094 6152 6193 6378

7572

3525 5269 6376 6530 7488

3293 3296

3527 7636 5927 3369 5291 2773 2857 3106 3620 4103 5326 5788 5870 5937 6114 6157 6262 6424

Sep

1 09:32 1988

u_fsav u_gid u_ino u_intflg u_name u_offset

u_ofile

u_pdir u_procp

6524 6727 6816 6989 7548 7612 8172 8854 0416 0421 6771 0432 7640 0454 0433 0427 3524 5309 6240 6309 6382 6556 7622 7642 7844 9025 0438 5853 6856 0435 7489 0424 1859 2273 3134 3240 3376 3502 3794

UNIX Operating System Source Code Cross Reference Listing Page 11

6551 6755 6833 7121 7560 7695 8210 9038 3189 3177 7466 3519 7664 2772 7483 3087 4113 5751 6244 6313 6528 7585 7626 7795 7845 9051 1876 6078 7740 5935 7490 1593 1891 2793 3170 3278 3388 3625 3828

6569 6759 6863 7311 7571 7827 8654 9057 4255 3466

6630 6778 6929 7538 7580 8027 8751

u_prof

3476

u_qsav u_rgid u_rsav

3527 7482

u_ruid

2845 7646 3088 4114 5752 6294 6315 6529 7586 7636 7796 7846 9055 3227 6626

u_segflg

5936 7606 1743 1917 2818 3174 3314 3446 3626 3996

2848 3140 4462 6239 6295 6316 6555 7608 7638 7798 9024 9056 5835 6829

u_sep u_signal

u_ssav u_ssize

u_stime u_tsize

7459 u_uid 1752 2071 2823 3224 3326 3482 3638 4021

u_uisa

u_uisd

4048 4169 4401 4478 7828 0453 3672 0445 0423 0415 4476 0422 4111 0418 4123 6548 0444 3371 0447 3623 4054 0446 4477 0443 3371 4141 4156 0449 0441 3371 0420 3456 6763 7465 0436 1699 1744 0437

4119 4175 4402 4479 8031 3127 3673 2106 3465 1889

4148 4209 4448 5312 8032 3670 3790 2846 3467 2189

4149 4273 4465 5317 3671 3791 3475 2281

3444 3447 3455 3089 5745 7487 3151 4146 2734 3624

3091 6372 7587 3152 5276 3183 4003

4117 6521 3365 5306 3225 4051

1905 2242 2284 3150 3376 4143 5292 3293 3148 4146 3172 3567 6769

3152 3370 3378 3389 4146 4150 3338 3152 5275 3173 3646 6798

3793 3366 3445 4111 6814

1665 1678 1694 1715 1716 1717 1666 1719 1720

1721 0448 3789 v 8090 8170 8580 8585 8592 vp 8168 8176 VTDELAY 7977 wait 2919 WAITING 8610 wakeup 2082 3248 3808 4213 5031 6652 7117 8075 8734 WCOM 5093 wdir 5940 wf 7725 7747 wflushtty 8058 WLO 5373 WO 0316 WOPEN 7985 write 2916 writei 3528 6276 writep 5749 x1 2340 x2 2340 x3 2340 x4 2340 u_utime

1754 3296 3341 3660 8091 8201 8582 8586 8593 8170 8177 8463 3270 8657 2113 3249 3822 4389 5188 6653 7778 8260 8744 5114 7467 7737

8094 8202 8583 8590 8594 8171

8658 2145 3434 4025 4877 5217 6979 7852 8261 8982

8167 8213 8584 8591 8175

8721 3197 3805 4195 4880 5319 7023 7891 8357

x5 x6 x7 x8 x9 xa xalloc xb xbr xc xccdec xfree xp

xsr xswap

7477 7738 7746

8217 8589

XTABS x_caddr x_ccount

1762 x_count 5720 4118 4124 5755 7489 7848 7805 2346

x_daddr x_iptr x_size z

2340 2340 2340 2340 2340 2340 3130 2340 2318 2340 4378 3128 4399 4405 4436 4446 4452 4457 4483 5911 2317 2406 1906 4478 7967 1753 1881 4313 4495 1880 4452 2034 4467 4311 4446 1981 4408 8407

4433 2399 4403 3233 4401 4407 4441 4447 4453 4467 4490 5928 2393

4490 4398 4403 4408 4442 4448 4454 4469 4491 5929 2397

4404 4409 4444 4451 4456 4475 4495 5931 2398

2024 2285 4368 8047 2036 1980 4453 4496 4312

8390 4309 4497 2033 2039 4475 4483 4404 4447

4308 4409 4457 4405 4407 4442 4454 2034 2037 4310 4456 4497 8885

1 Initialization Process Initialization

Sep

1 09:28 1988

0100 0101 0102 0103 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149

/* fundamental constants: do not change */

#define #define #define #define #define

unix/param.h Page 1

USIZE 16 /* size of user block (*64) */ NULL 0 NODEV (-1) ROOTINO 1 /* i number of all roots */ DIRSIZ 14 /* max characters per directory */

/* signals: do not change */

#define #define #define #define #define #define #define #define #define #define #define #define #define #define

NSIG SIGHUP SIGINT SIGQIT SIGINS SIGTRC SIGIOT SIGEMT SIGFPT SIGKIL SIGBUS SIGSEG SIGSYS SIGPIPE

20 1 2 3 4 5 6 7 8 9 10 11 12 13

/* /* /* /* /* /* /* /* /* /* /* /* /*

hangup */ interrupt (rubout) */ quit (FS) */ illegal instruction */ trace or breakpoint */ iot */ emt */ floating point exception */ kill */ bus error */ segmentation violation */ sys */ end of pipe */

/* tunable variables */ #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define

NBUF 15 /* size of buffer cache */ NINODE 100 /* number of in core inodes */ NFILE 100 /* number of in core file structures */ NMOUNT 5 /* number of mountable file systems */ NEXEC 3 /* number of simultaneous exec’s */ MAXMEM (64*32) /* max core per process; first number is kw */ SSIZE 20 /* initial stack size (*64 bytes) */ SINCR 20 /* increment of stack (*64 bytes) */ NOFILE 15 /* max open files per process */ CANBSIZ 256 /* max size of typewriter line */ CMAPSIZ 100 /* size of core allocation area */ SMAPSIZ 100 /* size of swap allocation area */ NCALL 20 /* max simultaneous time callouts */ NPROC 50 /* max number of processes */ NTEXT 40 /* max number of pure texts */ NCLIST 100 /* max total clist size */ HZ 60 /* Ticks/second of the clock */

Sep

0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0181 0182 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199

1 09:28 1988

unix/param.h Page 2

/* priorities: do not alter much */

#define #define #define #define #define #define #define

PSWP PINOD PRIBIO PPIPE PWAIT PSLEP PUSER

-100 -90 -50 1 40 90 100

/* Certain processor registers */ #define PS 0177776 #define KL 0177560 #define SW 0177570 /* -------------------------

*/

/* structures to access integers : */

/* single integer */ struct {

int

/* in bytes struct {

integ;

};

*/

char lobyte;

char hibyte;

};

/* as a sequence */ struct {

int

r[];

};

/* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 01

Sheet 01

Sep

1 09:28 1988

unix/systm.h Page 1

0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 0231 0232 0233 0234 0235 0236 0237 0238 0239 0240 0241 0242 0243 0244 0245 0246 0247 0248 0249

/* various global variables */ char canonb[CANBSIZ]; int coremap[CMAPSIZ]; int swapmap[SMAPSIZ];

Sep

/* buffer for erase and kill */ /* space for core allocation */ /* space for swap allocation */

int

*rootdir;

/* pointer to inode of root directory */

int

cputype;

/* type of cpu =40, 45, or 70 */

int

execnt;

/* number of processes in exec */

int int int

lbolt; time[2]; tout[2];

/* time of day in 60th not in time */ /* time in sec from 1970 */ /* time of day of next sleep */

int

mpid; /* generic for unique process id’s */

char runin; char runout; char runrun;

/* scheduling flag */ /* scheduling flag */ /* scheduling flag */

char curpri;

/* more scheduling */

int

maxmem;

/* actual max memory per process */

int

*lks; /* pointer to clock device */

int int

rootdev; swapdev;

/* dev of root see conf.c */ /* dev of swap see conf.c */

int int

swplo; nswap;

/* block number of swap space */ /* size of swap space */

int int

updlock; rablock;

/* lock for sync */ /* block to be read ahead */

char regloc[];

/* locs. of saved user registers (see trap.c) */

/* -------------------------

*/

0250 0251 0252 0253 0254 0255 0256 0257 0258 0259 0260 0261 0262 0263 0264 0265 0266 0267 0268 0269 0270 0271 0272 0273 0274 0275 0276 0277 0278 0279 0280 0281 0282 0283 0284 0285 0286 0287 0288 0289 0290 0291 0292 0293 0294 0295 0296 0297 0298 0299

1 09:28 1988

unix/systm.h Page 2

/* ------------------------/* * * * * *

*/

The callout structure is for a routine arranging to be called by the the clock interrupt (see clock.c), with a specified argument, within a specified amount of time. It is used, for example, to time tab delays on teletypes. */

struct callo { int c_time; /* incremental time */ int c_arg; /* argument to routine */ int (*c_func)(); /* routine */ } callout[NCALL]; /* ------------------------*/ /* Mount structure: used to locate * the super block of a mounted file. */ struct mount { int m_dev; /* device mounted */ int *m_bufp; /* pointer to superblock */ int *m_inodp; /* pointer to mounted on inode */ } mount[NMOUNT]; /* ------------------------*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 02

Sheet 02

Sep

0300 0301 0302 0303 0304 0305 0306 0307 0308 0309 0310 0311 0312 0313 0314 0315 0316 0317 0318 0319 0320 0321 0322 0323 0324 0325 0326 0327 0328 0329 0330 0331 0332 0333 0334 0335 0336 0337 0338 0339 0340 0341 0342 0343 0344 0345 0346 0347 0348 0349

1 09:28 1988

unix/seg.h Page 1

/* kt-11 addresses and bits */

#define UISD #define UISA #define UDSA

0177600 /* first user I-space descriptor register */ 0177640 /* first user I-space address register */ 0177660 /* first user D-space address register */

#define UBMAP 0170200 /* access to 11/70 unibus map */

#define #define #define #define

RO WO RW ED

02 04 06 010

/* access abilities */

/* expand segment downwards */

/* ------------------------int

*ka6;

*/

/* 11/40 KISA6; 11/45 KDSA6 */

Sep

1 09:28 1988

unix/proc.h Page 1

0350 0351 0352 0353 0354 0355 0356 0357 0358 0359 0360 0361 0362 0363 0364 0365 0366 0367 0368 0369 0370 0371 0372 0373 0374 0375 0376 0377 0378 0379 0380 0381 0382 0383 0384 0385 0386 0387 0388 0389 0390 0391 0392 0393 0394 0395 0396 0397 0398 0399

/* * One structure allocated per active * process. It contains all data needed * about the process while the * process may be swapped out. * Other per process data (user.h) * is swapped with the process. */ struct proc { char p_stat; char p_flag; char p_pri; /* priority, negative is high */ char p_sig; /* signal number sent to this process */ char p_uid; /* user id, used to direct tty signals */ char p_time; /* resident time for scheduling */ char p_cpu; /* cpu usage for scheduling */ char p_nice; /* nice for scheduling */ int p_ttyp; /* controlling tty */ int p_pid; /* unique process id */ int p_ppid; /* process id of parent */ int p_addr; /* address of swappable image */ int p_size; /* size of swappable image (*64 bytes) */ int p_wchan;/* event process is awaiting */ int *p_textp;/* pointer to text structure */ } proc[NPROC]; /* -------------------------

*/

/* stat codes */ /* #define #define #define #define #define #define

null SSLEEP SWAIT SRUN SIDL SZOMB SSTOP

0 1 2 3 4 5 6

/* /* /* /* /* /*

not assigned */ sleeping on high priority */ sleeping on low priority */ running */ process being created */ process being terminated */ process being traced */

/* flag codes */ #define #define #define #define #define #define

SLOAD SSYS SLOCK SSWAP STRC SWTED

01 02 04 010 020 040

/* /* /* /* /* /*

in core */ scheduling process */ process cannot be swapped */ process is being swapped out */ process is being traced */ another tracing flag */

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 03

Sheet 03

Sep

1 09:28 1988

unix/user.h Page 1

Sep

1 09:28 1988

unix/user.h Page 2

0400 /* 0401 * The user structure. 0402 * One allocated per process. 0403 * Contains all per process data 0404 * that doesn’t need to be referenced 0405 * while the process is swapped. 0406 * The user block is USIZE*64 bytes 0407 * long; resides at virtual kernel 0408 * loc 140000; contains the system 0409 * stack per user; is cross referenced 0410 * with the proc structure for the 0411 * same process. 0412 */ 0413 struct user 0414 { 0415 int u_rsav[2]; /* save r5,r6 when exchanging stacks */ 0416 int u_fsav[25]; /* save fp registers */ 0417 /* rsav and fsav must be first in structure */ 0418 char u_segflg; /* flag for IO; user or kernel space */ 0419 char u_error; /* return error code */ 0420 char u_uid; /* effective user id */ 0421 char u_gid; /* effective group id */ 0422 char u_ruid; /* real user id */ 0423 char u_rgid; /* real group id */ 0424 int u_procp; /* pointer to proc structure */ 0425 char *u_base; /* base address for IO */ 0426 char *u_count; /* bytes remaining for IO */ 0427 char *u_offset[2]; /* offset in file for IO */ 0428 int *u_cdir; /* pointer to inode for current directory */ 0429 char u_dbuf[DIRSIZ]; /* current pathname component */ 0430 char *u_dirp; /* current pointer to inode */ 0431 struct { /* current directory entry */ 0432 int u_ino; 0433 char u_name[DIRSIZ]; 0434 } u_dent; 0435 int *u_pdir; /* inode of parent directory of dirp */ 0436 int u_uisa[16]; /* prototype segmentation addresses */ 0437 int u_uisd[16]; /* prototype segmentation descriptors */ 0438 int u_ofile[NOFILE]; /* pointers to file structures of 0439 open files */ 0440 int u_arg[5]; /* arguments to current system call */ 0441 int u_tsize; /* text size (*64) */ 0442 int u_dsize; /* data size (*64) */ 0443 int u_ssize; /* stack size (*64) */ 0444 int u_sep; /* flag for I and D separation */ 0445 int u_qsav[2]; /* label variable for quits & interrupts */ 0446 int u_ssav[2]; /* label variable for swapping */ 0447 int u_signal[NSIG]; /* disposition of signals */ 0448 int u_utime; /* this process user time */ 0449 int u_stime; /* this process system time */

0450 0451 0452 0453 0454 0455 0456 0457 0458 0459 0460 0461 0462 0463 0464 0465 0466 0467 0468 0469 0470 0471 0472 0473 0474 0475 0476 0477 0478 0479 0480 0481 0482 0483 0484 0485 0486 0487 0488 0489 0490 0491 0492 0493 0494 0495 0496 0497 0498 0499

int u_cutime[2]; int u_cstime[2]; int *u_ar0; int u_prof[4]; char u_intflg;

/* sum of childs’ utimes */ /* sum of childs’ stimes */ /* address of users saved R0 */ /* profile arguments */ /* catch intr from sys */ /* kernel stack per user * extends from u + USIZE*64 * backward not to reach here */

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 04

Sheet 04

} u; /* -------------------------

*/

/* u_error codes */ /* See section "INTRO(II)" of * the UNIX Programmer’s manual * for the meanings of these codes. */ #define EFAULT 106 #define EPERM 1 #define ENOENT 2 #define ESRCH 3 #define EINTR 4 #define EIO 5 #define ENXIO 6 #define E2BIG 7 #define ENOEXEC 8 #define EBADF 9 #define ECHILD 10 #define EAGAIN 11 #define ENOMEM 12 #define EACCES 13 #define ENOTBLK 15 #define EBUSY 16 #define EEXIST 17 #define EXDEV 18 #define ENODEV 19 #define ENOTDIR 20 #define EISDIR 21 #define EINVAL 22 #define ENFILE 23 #define EMFILE 24 #define ENOTTY 25 #define ETXTBSY 26 #define EFBIG 27 #define ENOSPC 28 #define ESPIPE 29 #define EROFS 30 #define EMLINK 31 #define EPIPE 32

Sep

1 09:28 1988

0500 0501 0502 0503 0504 0505 0506 0507 0508 0509 0510 0511 0512 0513 0514 0515 0516 0517 0518 0519 0520 0521 0522 0523 0524 0525 0526 0527 0528 0529 0530 0531 0532 0533 0534 0535 0536 0537 0538 0539 0540 0541 0542 0543 0544 0545 0546 0547 0548 0549

/ low core br4 br5 br6 br7

= = = =

unix/low.s Page 1

200 240 300 340

. = 0^. br 4

1f

/ trap vectors trap; br7+0. trap; br7+1. trap; br7+2. trap; br7+3. trap; br7+4. trap; br7+5. trap; br7+6. . = 40^. .globl 1: jmp jmp

/ / / / / / /

bus error illegal instruction bpt-trace trap iot trap power fail emulator trap system entry

start, dump start dump

. = 60^. klin; br4 klou; br4 . = 70^. pcin; br4 pcou; br4 . = 100^. kwlp; br6 kwlp; br6 . = 114^. trap; br7+7.

/ 11/70 parity

. = 200^. lpou; br4 . = 220^. rkio; br5 . = 240^. trap; br7+7. trap; br7+8. trap; br7+9.

/ programmed interrupt / flotaing point / segmentation violation

Sep

0550 0551 0552 0553 0554 0555 0556 0557 0558 0559 0560 0561 0562 0563 0564 0565 0566 0567 0568 0569 0570 0571 0572 0573 0574 0575 0576 0577 0578 0579 0580 0581 0582 0583 0584 0585 0586 0587 0588 0589 0590 0591 0592 0593 0594 0595 0596 0597 0598 0599

1 09:28 1988

unix/low.s Page 2

///////////////////////////////////////////////////////// / interface code to C ///////////////////////////////////////////////////////// .globl

call, trap

.globl klin:

_klrint jsr r0,call; _klrint

.globl klou:

_klxint jsr r0,call; _klxint

.globl pcin:

_pcrint jsr r0,call; _pcrint

.globl pcou:

_pcpint jsr r0,call; _pcpint

.globl kwlp:

_clock jsr

r0,call; _clock

.globl lpou:

_lpint jsr

r0,call; _lpint

.globl rkio:

_rkintr jsr r0,call; _rkintr

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 05

Sheet 05

Sep

1 09:28 1988

0600 0601 0602 0603 0604 0605 0606 0607 0608 0609 0610 0611 0612 0613 0614 0615 0616 0617 0618 0619 0620 0621 0622 0623 0624 0625 0626 0627 0628 0629 0630 0631 0632 0633 0634 0635 0636 0637 0638 0639 0640 0641 0642 0643 0644 0645 0646 0647 0648 0649

/ machine language assist / for 11/40 / non-UNIX mfpi mtpi wait rtt reset

unix/m40.s Page 1

Sep

instructions = 6500^tst = 6600^tst = 1 = 6 = 5

/* ------------------------*/ .globl start, _end, _edata, _main start: bit $1,SSR0 bne start / loop if restart reset / initialize systems segments mov mov mov clr mov

$KISA0,r0 $KISD0,r1 $200,r4 r2 $6,r3

mov mov add sob

r2,(r0)+ $77406,(r1)+ r4,r2 r3,1b

1: / 4k rw

/ initialize user segment mov ash bic mov mov

$_end+63.,r2 $-6,r2 $!1777,r2 r2,(r0)+ $USIZE-1\r[0] = 077406; 1562 for(;;) { 1563 UISA->r[0] = i; 1564 if(fuibyte(0) < 0) 1565 break; 1566 clearseg(i); 1567 maxmem++; 1568 mfree(coremap, 1, i); 1569 i++; 1570 } 1571 if(cputype == 70) 1572 for(i=0; ir[i] = ir[7] = ka6[1]; /* io segment */

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 15

Sheet 15

Sep

1 09:28 1988

unix/main.c Page 3

Sep

1 09:28 1988

unix/main.c Page 4

1600 UISD->r[7] = 077406; 1601 lks = CLOCK1; 1602 if(fuiword(lks) == -1) { 1603 lks = CLOCK2; 1604 if(fuiword(lks) == -1) 1605 panic("no clock"); 1606 } 1607 *lks = 0115; 1608 1609 /* 1610 * set up ’known’ i-nodes 1611 */ 1612 1613 cinit(); 1614 binit(); 1615 iinit(); 1616 rootdir = iget(rootdev, ROOTINO); 1617 rootdir->i_flag =& ~ILOCK; 1618 u.u_cdir = iget(rootdev, ROOTINO); 1619 u.u_cdir->i_flag =& ~ILOCK; 1620 1621 /* 1622 * make init process 1623 * enter scheduling loop 1624 * with system process 1625 */ 1626 1627 if(newproc()) { 1628 expand(USIZE+1); 1629 estabur(0, 1, 0, 0); 1630 copyout(icode, 0, sizeof icode); 1631 /* 1632 * Return goes to loc. 0 of user init 1633 * code just copied out. 1634 */ 1635 return; 1636 } 1637 sched(); 1638 } 1639 /* ------------------------*/ 1640 1641 /* 1642 * Set up software prototype segmentation 1643 * registers to implement the 3 pseudo 1644 * text,data,stack segment sizes passed 1645 * as arguments. 1646 * The argument sep specifies if the 1647 * text and data+stack segments are to 1648 * be separated. 1649 */

1650 estabur(nt, nd, ns, sep) 1651 { 1652 register a, *ap, *dp; 1653 1654 if(sep) { 1655 if(cputype == 40) 1656 goto err; 1657 if(nseg(nt) > 8 || nseg(nd)+nseg(ns) > 8) 1658 goto err; 1659 } else 1660 if(nseg(nt)+nseg(nd)+nseg(ns) > 8) 1661 goto err; 1662 if(nt+nd+ns+USIZE > maxmem) 1663 goto err; 1664 a = 0; 1665 ap = &u.u_uisa[0]; 1666 dp = &u.u_uisd[0]; 1667 while(nt >= 128) { 1668 *dp++ = (127>7); } /* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 17

Sheet 17

Sep

1 09:28 1988

1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849

# /* */

unix/slp.c Page 1

#include "../param.h" #include "../user.h" #include "../proc.h" #include "../text.h" #include "../systm.h" #include "../file.h" #include "../inode.h" #include "../buf.h" /* ------------------------*/ /* * Create a new process-- the internal version of * sys fork. * It returns 1 in the new process. * How this happens is rather hard to understand. * The essential fact is that the new process is created * in such a way that it appears to have started executing * in the same call to newproc as the parent; * but in fact the code that runs is that of swtch. * The subtle implication of the return value of swtch * (see above) is that this is the value that newproc’s * caller in the new process sees. */ newproc() { int a1, a2; struct proc *p, *up; register struct proc *rpp; register *rip, n; p = NULL; /* * First, just locate a slot for a process * and copy the useful info from this process into it. * The panic "cannot happen" because fork already * checked for the existence of a slot. */ retry: mpid++; if(mpid < 0) { mpid = 0; goto retry; } for(rpp = &proc[0]; rpp < &proc[NPROC]; rpp++) { if(rpp->p_stat == NULL && p==NULL) p = rpp; if (rpp->p_pid==mpid)

Sep

1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899

1 09:28 1988

unix/slp.c Page 2

goto retry; } if ((rpp = p)==NULL) panic("no procs"); /* * make proc entry for new proc */ rip = u.u_procp; up = rip; rpp->p_stat = SRUN; rpp->p_flag = SLOAD; rpp->p_uid = rip->p_uid; rpp->p_ttyp = rip->p_ttyp; rpp->p_nice = rip->p_nice; rpp->p_textp = rip->p_textp; rpp->p_pid = mpid; rpp->p_ppid = rip->p_ppid; rpp->p_time = 0; /* * make duplicate entries * where needed */ for(rip = &u.u_ofile[0]; rip < &u.u_ofile[NOFILE];) if((rpp = *rip++) != NULL) rpp->f_count++; if((rpp=up->p_textp) != NULL) { rpp->x_count++; rpp->x_ccount++; } u.u_cdir->i_count++; /* * Partially simulate the environment * of the new process so that when it is actually * created (by copying) it will look right. */ savu(u.u_rsav); rpp = p; u.u_procp = rpp; rip = up; n = rip->p_size; a1 = rip->p_addr; rpp->p_size = n; a2 = malloc(coremap, n); /* * If there is not enough core for the * new process, swap put the current process to

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 18

Sheet 18

Sep

1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949

1 09:28 1988

unix/slp.c Page 3

Sep

1 09:28 1988

unix/slp.c Page 4

* generate the copy. */ if(a2 == NULL) { rip->p_stat = SIDL; rpp->p_addr = a1; savu(u.u_ssav); xswap(rpp, 0, 0); rpp->p_flag =| SSWAP; rip->p_stat = SRUN; } else { /* * There is core, so just copy. */ rpp->p_addr = a2; while(n--) copyseg(a1++, a2++); } u.u_procp = rip; return(0);

1950 1951 goto loop; 1952 1953 sloop: 1954 runin++; 1955 sleep(&runin, PSWP); 1956 1957 loop: 1958 spl6(); 1959 n = -1; 1960 for(rp = &proc[0]; rp < &proc[NPROC]; rp++) 1961 if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0 && 1962 rp->p_time > n) { 1963 p1 = rp; 1964 n = rp->p_time; 1965 } 1966 if(n == -1) { 1967 runout++; 1968 sleep(&runout, PSWP); } 1969 goto loop; /* ------------------------*/ 1970 } 1971 /* 1972 /* * The main loop of the scheduling (swapping) 1973 * see if there is core for that process * process. 1974 */ * The basic idea is: 1975 * see if anyone wants to be swapped in; 1976 spl0(); * swap out processes until there is room; 1977 rp = p1; * swap him in; 1978 a = rp->p_size; * repeat. 1979 if((rp=rp->p_textp) != NULL) * Although it is not remarkably evident, the basic 1980 if(rp->x_ccount == 0) * synchronization here is on the runin flag, which is 1981 a =+ rp->x_size; * slept on and is set once per second by the clock routine. 1982 if((a=malloc(coremap, a)) != NULL) * Core shuffling therefore take place once per second. 1983 goto found2; * 1984 * panic: swap error -- IO error while swapping. 1985 /* * this is the one panic that should be 1986 * none found, * handled in a less drastic way. Its 1987 * look around for easy core * very hard. 1988 */ */ 1989 sched() 1990 slp6(); { 1991 for(rp = &proc[0]; rp < &proc[NPROC]; rp++) struct proc *p1; 1992 if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD && register struct proc *rp; 1993 (rp->p_stat == SWAIT || rp->p_stat==SSTOP)) register a, n; 1994 goto found1; 1995 /* 1996 /* * find user to swap in 1997 * no easy core, * of users ready, select one out longest 1998 * if this process is deserving, */ 1999 * look around for

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 19

Sheet 19

Sep

1 09:28 1988

unix/slp.c Page 5

Sep

1 09:28 1988

unix/slp.c Page 6

2000 * oldest process in core 2001 */ 2002 2003 if(n < 3) 2004 goto sloop; 2005 n = -1; 2006 for(rp = &proc[0]; rp < &proc[NPROC]; rp++) 2007 if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD && 2008 (rp->p_stat==SRUN || rp->p_stat==SSLEEP) && 2009 rp->p_time > n) { 2010 p1 = rp; 2011 n = rp->p_time; 2012 } 2013 if(n < 2) 2014 goto sloop; 2015 rp = p1; 2016 2017 /* 2018 * swap user out 2019 */ 2020 2021 found1: 2022 slp0(); 2023 rp->p_flag =& ~SLOAD; 2024 xswap(rp, 1, 0); 2025 goto loop; 2026 2027 /* 2028 * swap user in 2029 */ 2030 2031 found2: 2032 if((rp=p1->p_textp) != NULL) { 2033 if(rp->x_ccount == 0) { 2034 if(swap(rp->x_daddr, a, rp->x_size, B_READ)) 2035 goto swaper; 2036 rp->x_caddr = a; 2037 a =+ rp->x_size; 2038 } 2039 rp->x_ccount++; 2040 } 2041 rp = p1; 2042 if(swap(rp->p_addr, a, rp->p_size, B_READ)) 2043 goto swaper; 2044 mfree(swapmap, (rp->p_size+7)/8, rp->p_addr); 2045 rp->p_addr = a; 2046 rp->p_flag =| SLOAD; 2047 rp->p_time = 0; 2048 goto loop; 2049

2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099

swaper: panic("swap error"); } /* -------------------------

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 20

Sheet 20

*/

/* * Give up the processor till a wakeup occurs * on chan, at which time the process * enters the scheduling queue at priority pri. * The most important effect of pri is that when * pri=0 signals will be processed. * Callers of this routine must be prepared for * premature return, and check that the reason for * sleeping has gone away. */ sleep(chan, pri) { register *rp, s; s = PS->integ; rp = u.u_procp; if(pri >= 0) { if(issig()) goto psig; spl6(); rp->p_wchan = chan; rp->p_stat = SWAIT; rp->p_pri = pri; spl0(); if(runin != 0) { runin = 0; wakeup(&runin); } swtch(); if(issig()) goto psig; } else { spl6(); rp->p_wchan = chan; rp->p_stat = SSLEEP; rp->p_pri = pri; spl0(); swtch(); } PS->integ = s; return; /* * If priority was low (>=0) and

Sep

1 09:28 1988

unix/slp.c Page 7

2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149

* there has been a signal, * execute non-local goto to * the qsav location. * (see trap1/trap.c) */ psig: aretu(u.u_qsav); } /*--------------------------

*/

/* * Wake up all processes sleeping on chan. */ wakeup(chan) { register struct proc *p; register c, i; c = chan; p = &proc[0]; i = NPROC; do { if(p->p_wchan == c) { setrun(p); } p++; } while(--i); } /* -------------------------

*/

/* * Set the process running; * arrange for it to be swapped in if necessary. */ setrun(p) { register struct proc *rp; rp = p; rp->p_wchan = 0; rp->p_stat = SRUN; if(rp->p_pri < curpri) runrun++; if(runout != 0 && (rp->p_flag&SLOAD) == 0) { runout = 0; wakeup(&runout); } } /* -------------------------

*/

Sep

1 09:28 1988

unix/slp.c Page 8

2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199

/* * Set user priority. * The rescheduling flag (runrun) * is set if the priority is higher * than the currently running process. */ setpri(up) { register *pp, p; pp = up; p = (pp->p_cpu & 0377)/16; p =+ PUSER + pp->p_nice; if(p > 127) p = 127; if(p > curpri) runrun++; pp->p_pri = p; } /* -------------------------

*/

/* * This routine is called to reschedule the CPU. * if the calling process is not in RUN state, * arrangements for it to restart must have * been made elsewhere, usually by calling via sleep. */ swtch() { static struct proc *p; register i, n; register struct proc *rp; if(p == NULL) p = &proc[0]; /* * Remember stack of caller */ savu(u.u_rsav); /* * Switch to scheduler’s stack */ retu(proc[0].p_addr); loop: runrun = 0; rp = p; p = NULL; n = 128;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 21

Sheet 21

Sep

1 09:28 1988

2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 } 2249 /*

unix/slp.c Page 9

Sep

/* * Search for highest-priority runnable process */ i = NPROC; do { rp++; if(rp >= &proc[NPROC]) rp = &proc[0]; if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)!=0) { if(rp->p_pri < n) { p = rp; n = rp->p_pri; } } } while(--i); /* * If no process is runnable, idle. */ if(p == NULL) { p = rp; idle(); goto loop; } rp = p; curpri = n; /* Switch to stack of the new process and set up * his segmentation registers. */ retu(rp->p_addr); sureg(); /* * If the new process paused because it was * swapped out, set the stack level to the last call * to savu(u_ssav). This means that the return * which is executed immediately after the call to aretu * actually returns from the last routine which did * the savu. * * You are not expected to understand this. */ if(rp->p_flag&SSWAP) { rp->p_flag =& ~SSWAP; aretu(u.u_ssav); } /* The value returned here has many subtle implications. * See the newproc comments. */ return(1); -------------------------

*/

2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299

1 09:28 1988

unix/slp.c Page 10

/* * Change the size of the data+stack regions of the process. * If the size is shrinking, it’s easy-- just release the * extra core. If it’s growing, and there is core, just * allocate it and copy the image, taking care to reset * registers to account for the fact that the system’s * stack has moved. * If there is no core, arrange for the process to be * swapped out after adjusting the size requirement-* when it comes in, enough core will be allocated. * Because of the ssave and SSWAP flags, control will * resume after the swap in swtch, which executes the return * from this stack level. * * After the expansion, the caller will take care of copying * the user’s stack towards or away from the data area. */ expand(newsize) { int i, n; register *p, a1, a2; p = u.u_procp; n = p->p_size; p->p_size = newsize; a1 = p->p_addr; if(n >= newsize) { mfree(coremap, n-newsize, a1+newsize); return; } savu(u.u_rsav); a2 = malloc(coremap, newsize); if(a2 == NULL) { savu(u.u_ssav); xswap(p, 1, n); p->p_flag =| SSWAP; swtch(); /* no return */ } p->p_addr = a2; for(i=0; ip_addr); sureg(); } /* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 22

Sheet 22

Sep

1 09:28 1988

2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349

# /* */ #include #include #include #include

unix/prf.c Page 1

"../param.h" "../seg.h" "../buf.h" "../conf.h"

/* * Address and structure of the * KL-11 console device registers. */ struct { int rsr; int rbr; int xsr; int xbr; }; /* ------------------------*/ /* * In case console is off, * panicstr contains argument to last * call to panic. */ char

*panicstr;

/* * Scaled down version of C library printf. * Only %s %l %d (==%l) %o are recognized. * Used to print diagnostic information * directly on console tty. * Since it is not interrupt driven, * all system activities are pretty much * suspended. * Printf should not be used for chit-chat. */ printf(fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9,xa,xb,xc) char fmt[]; { register char *s; register *adx, c; adx = &x1; loop: while((c = *fmt++) != ’%’) { if(c == ’\0’)

Sep

2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399

1 09:28 1988

unix/prf.c Page 2

return putchar(c); } c = *fmt++; if(c == ’d’ || c == ’l’ || c == ’o’) printn(*adx, c==’o’? 8: 10); if(c == ’s’) { s = *adx; while(c = *s++) putchar(c); } adx++; goto loop; } /* -------------------------

*/

/* * Print an unsigned integer in base b. */ printn(n, b) { register a; if(a = ldiv(n, b)) printn(a, b); putchar(lrem(n, b) + ’0’); } /* -------------------------

*/

/* * Print a character on console. * Attempts to save and restore device * status. * If the switches are 0, all * printing is inhibited. */ putchar(c) { register rc, s; rc = c; if(SW->integ == 0) return; while((KL->xsr&0200) ==0) ; if(rc == 0) return; s = KL->xsr; KL->xsr = 0; KL->xbr = rc;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 23

Sheet 23

Sep

2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449

1 09:28 1988

unix/prf.c Page 3

if(rc == ’\n’) { putchar(’\r’); putchar(0177); putchar(0177); } putchar(0); KL->xsr = s;

Sep

1 09:28 1988

2450 2451 2452 2453 2454 2455 } 2456 /* } 2457 /* ------------------------*/ 2458 2459 /* 2460 * Panic is called on unresolvable 2461 * fatal errors. 2462 * It syncs, prints "panic: mesg" and 2463 * then loops. 2464 */ 2465 panic(s) 2466 char *s; 2467 { 2468 panicstr = s; 2469 update(); 2470 printf("panic: %s\n", s); 2471 for(;;) 2472 idle(); 2473 } 2474 /* ------------------------*/ 2475 2476 /* 2477 * prdev prints a warning message of the 2478 * form "mesg on dev x/y". 2479 * x and y are the major and minor parts of 2480 * the device argument. 2481 */ 2482 prdev(str, dev) 2483 { 2484 2485 printf("%s on dev %l/%l\n", str, dev.d_major, dev.d_minor); 2486 } 2487 /* ------------------------*/ 2488 2489 /* 2490 * deverr prints a diagnostic from 2491 * a device driver. 2492 * It prints the device, block number, 2493 * and an octal word (usually some error 2494 * status register) passed as argument. 2495 */ 2496 deverror(bp, o1, o2) 2497 int *bp; 2498 { 2499

unix/prf.c Page 4

register *rbp; rbp = bp; prdev("err", rbp->b_dev); printf("bn%l er%o %o\n", rbp->b_blkno, o1, o2); -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 24

Sheet 24

Sep

1 09:28 1988

2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549

# /* */

unix/malloc.c Page 1

Sep

2550 2551 2552 2553 /* 2554 * Structure of the coremap and swapmap 2555 * arrays. Consists of non-zero count 2556 * and base address of that many 2557 * contiguous units. 2558 * (The coremap unit is 64 bytes, 2559 * the swapmap unit is 512 bytes) 2560 * The addresses are increasing and 2561 * the list is terminated with the 2562 * first zero count. 2563 */ 2564 struct map 2565 { 2566 char *m_size; 2567 char *m_addr; 2568 }; 2569 /* ------------------------*/ 2570 2571 /* 2572 * Allocate size units from the given 2573 * map. Return the base of the allocated 2574 * space. 2575 * Algorithm is first fit. 2576 */ 2577 malloc(mp, size) 2578 struct map *mp; 2579 { 2580 register int a; 2581 register struct map *bp; 2582 2583 for (bp = mp; bp->m_size; bp++) { 2584 if (bp->m_size >= size) { 2585 a = bp->m_addr; 2586 bp->m_addr =+ size; 2587 if ((bp->m_size =- size) == 0) 2588 do { 2589 bp++; 2590 (bp-1)->m_addr = bp->m_addr; 2591 } while((bp-1)->m_size = bp->m_size); 2592 return(a); 2593 } 2594 } 2595 return(0); 2596 } 2597 /*---------------------*/ 2598 2599

1 09:28 1988

unix/malloc.c Page 2

/* * Free the previously allocated space aa * of size units into the specified map. * Sort aa into map and combine on * one or both ends if possible. */ mfree(mp, size, aa) struct map *mp; { register struct map *bp; register int t; register int a; a = aa; for (bp = mp; bp->m_addrm_size!=0; bp++); if (bp>mp && (bp-1)->m_addr+(bp-1)->m_size == a) { (bp-1)->m_size =+ size; if (a+size == bp->m_addr) { (bp-1)->m_size =+ bp->m_size; while (bp->m_size) { bp++; (bp-1)->m_addr = bp->m_addr; (bp-1)->m_size = bp->m_size; } } } else { if (a+size == bp->m_addr && bp->m_size) { bp->m_addr =- size; bp->m_size =+ size; } else if(size) do { t = bp->m_addr; bp->m_addr = a; a = t; t = bp->m_size; bp->m_size = size; bp++; } while (size = t); } } /*-----------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 25

Sheet 25

2 Traps, Interrupts and System Calls Process Management

Sep

1 09:28 1988

2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649

/* * Location of the users’ stored * registers relative to R0. * Usage is u.u_ar0[XX]. */ #define R0 (0) #define R1 (-2) #define R2 (-9) #define R3 (-8) #define R4 (-7) #define R5 (-6) #define R6 (-3) #define R7 (1) #define RPS (2) #define

unix/reg.h Page 1

TBIT

020

/* PS trace bit */

Sep

1 09:28 1988

2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699

# #include #include #include #include #include #include #define #define #define #define #define

unix/trap.c Page 1

"../param.h" "../systm.h" "../user.h" "../proc.h" "../reg.h" "../seg.h" EBIT UMODE SETD SYS USER

1 0170000 0170011 0104400 020

/* /* /* /* /*

user error bit in PS: C-bit */ user-mode bits in PS word */ SETD instruction */ sys (trap) instruction */ user-mode flag added to dev */

/* * structure of the system entry table (sysent.c) */ struct sysent { int count; /* argument count */ int (*call)(); /* name of handler */ } sysent[64]; /* ------------------------*/ /* * Offsets of the user’s registers relative to * the saved r0. See reg.h */ char regloc[9] { R0, R1, R2, R3, R4, R5, R6, R7, RPS }; /* ------------------------*/ /* * Called from l40.s or l45.s when a processor trap occurs. * The arguments are the words saved on the system stack * by the hardware and software during the trap processing. * Their order is dictated by the hardware and the details * of C’s calling sequence. They are peculiar in that * this call is not ’by value’ and changed user registers * get copied back on return. * dev is the kind of trap that occurred. */ trap(dev, sp, r1, nps, r0, pc, ps) { register i, a; register struct sysent *callp; savfp(); if ((ps&UMODE) == UMODE)

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 26

Sheet 26

Sep

2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749

1 09:28 1988

unix/trap.c Page 2

dev =| USER; u.u_ar0 = &r0; switch(dev) { /* * Trap not expected. * Usually a kernel mode bus error. * The numbers printed are used to * find the hardware PS/PC as follows. * (all numbers in octal 18 bits) * address_of_saved_ps = * (ka6*0100) + aps - 0140000; * address_of_saved_pc = * address_of_saved_ps - 2; */ default: printf("ka6 = %o\n", *ka6); printf("aps = %o\n", &ps); printf("trap type %o\n", dev); panic("trap"); case 0+USER: /* bus error */ i = SIGBUS; break; /* * If illegal instructions are not * being caught and the offending instruction * is a SETD, the trap is ignored. * This is because C produces a SETD at * the beginning of every program which * will trap on CPUs without 11/45 FPU. */ case 1+USER: /* illegal instruction */ if(fuiword(pc-2)==SETD && u.u_signal[SIGINS]==0) goto out; i = SIGINS; break; case 2+USER: /* bpt or trace */ i = SIGTRC; break; case 3+USER: /* iot */ i = SIGIOT; break; case 5+USER: /* emt */ i = SIGEMT; break;

Sep

2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799

1 09:28 1988

unix/trap.c Page 3

case 6+USER: /* sys call */ u.u_error = 0; ps =& ~EBIT; callp = &sysent[fuiword(pc-2)&077]; if (callp == sysent) { /* indirect */ a = fuiword(pc); pc =+ 2; i = fuword(a); if ((i & ~077) != SYS) i = 077; /* illegal */ callp = &sysent[i&077]; for(i=0; icount; i++) u.u_arg[i] = fuword(a =+ 2); } else { for(i=0; icount; i++) { u.u_arg[i] = fuiword(pc); pc =+ 2; } } u.u_dirp = u.u_arg[0]; trap1(callp->call); if(u.u_intflg) u.u_error = EINTR; if(u.u_error < 100) { if(u.u_error) { ps =| EBIT; r0 = u.u_error; } goto out; } i = SIGSYS; break; /* * Since the floating exception is an * imprecise trap, a user generated * trap may actually come from kernel * mode. In this case, a signal is sent * to the current process to be picked * up later. */ case 8: /* floating exception */ psignal(u.u_procp, SIGFPT); return; case 8+USER: i = SIGFPT; break;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 27

Sheet 27

Sep

2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849

1 09:28 1988

unix/trap.c Page 4

/* * If the user SP is below the stack segment, * grow the stack automatically. * This relies on the ability of the hardware * to restart a half executed instruction. * On the 11/40 this is not the case and * the routine backup/l40.s may fail. * The classic example is on the instruction * cmp -(sp),-(sp) */ case 9+USER: /* segmentation exception */ a = sp; if(backup(u.u_ar0) == 0) if(grow(a)) goto out; i = SIGSEG; break; } psignal(u.u_procp, i);

Sep

2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 out: 2870 if(issig()) 2871 psig(); 2872 setpri(u.u_procp); 2873 } 2874 /* ------------------------*/ 2875 2876 /* 2877 * Call the system-entry routine f (out of the 2878 * sysent table). This is a subroutine for trap, and 2879 * not in-line, because if a signal occurs 2880 * during processing, an (abnormal) return is simulated from 2881 * the last caller to savu(qsav); if this took place 2882 * inside of trap, it wouldn’t have a chance to clean up. 2883 * 2884 * If this occurs, the return takes place without 2885 * clearing u_intflg; if it’s still set, trap 2886 * marks an error which means that a system 2887 * call (like read on a typewrite) got interrupted 2888 * by a signal. 2889 */ 2890 trap1(f) 2891 int (*f)(); 2892 { 2893 2894 u.u_intflg = 1; 2895 savu(u.u_qsav); 2896 (*f)(); 2897 u.u_intflg = 0; 2898 } 2899

1 09:28 1988

unix/trap.c Page 5

/* -------------------------

*/

/* * nonexistent system call-- set fatal error code. */ nosys() { u.u_error = 100; } /*------------------------*/ /* * Ignored system call */ nullsys() { } /* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 28

Sheet 28

Sep

1 09:28 1988

2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949

# /* */

unix/sysent.c Page 1

/* * This table is the switch used to transfer * to the appropriate routine for processing a system call. * Each row contains the number of arguments expected * and a pointer to the routine. */ int sysent[] { 0, &nullsys, /* 0 = indir */ 0, &rexit, /* 1 = exit */ 0, &fork, /* 2 = fork */ 2, &read, /* 3 = read */ 2, &write, /* 4 = write */ 2, &open, /* 5 = open */ 0, &close, /* 6 = close */ 0, &wait, /* 7 = wait */ 2, &creat, /* 8 = creat */ 2, &link, /* 9 = link */ 1, &unlink, /* 10 = ulink */ 2, &exec, /* 11 = exec */ 1, &chdir, /* 12 = chdir */ 0, >ime, /* 13 = time */ 3, &mknod, /* 14 = mknod */ 2, &chmod, /* 15 = chmod */ 2, &chown, /* 16 = chown */ 1, &sbreak, /* 17 = break */ 2, &stat, /* 18 = stat */ 2, &seek, /* 19 = seek */ 0, &getpid, /* 20 = getpid */ 3, &smount, /* 21 = mount */ 1, &sumount, /* 22 = unmount */ 0, &setuid, /* 23 = setuid */ 0, &getuid, /* 24 = getuid */ 0, &stime, /* 25 = stime */ 3, &ptrace, /* 26 = ptrace */ 0, &nosys, /* 27 = x */ 1, &fstat, /* 28 = fstat */ 0, &nosys, /* 29 = x */ 1, &nullsys, /* inoperative /* 30 = smdate */ 1, &stty, /* 31 = stty */ 1, >ty, /* 32 = gtty */ 0, &nosys, /* 33 = x */ 0, &nice, /* 34 = nice */ 0, &sslep, /* 35 = sleep */ 0, &sync, /* 36 = sync */ 1, &kill, /* 37 = kill */

Sep

1 09:28 1988

unix/sysent.c Page 2

2950 0, &getswit, 2951 0, &nosys, 2952 0, &nosys, 2953 0, &dup, 2954 0, &pipe, 2955 1, ×, 2956 4, &profil, 2957 0, &nosys, 2958 0, &setgid, 2959 0, &getgid, 2960 2, &ssig, 2961 0, &nosys, 2962 0, &nosys, 2963 0, &nosys, 2964 0, &nosys, 2965 0, &nosys, 2966 0, &nosys, 2967 0, &nosys, 2968 0, &nosys, 2969 0, &nosys, 2970 0, &nosys, 2971 0, &nosys, 2972 0, &nosys, 2973 0, &nosys, 2974 0, &nosys, 2975 0, &nosys, 2976 }; 2977 /* ------------------------2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999

/* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /*

38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

= = = = = = = = = = = = = = = = = = = = = = = = = =

switch */ x */ x */ dup */ pipe */ times */ prof */ tui */ setgid */ getgid */ sig */ x */ x */ x */ x */ x */ x */ x */ x */ x */ x */ x */ x */ x */ x */ x */

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 29

Sheet 29

Sep

1 09:28 1988

3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049

# #include #include #include #include #include #include #include

unix/sys1.c Page 1

"../param.h" "../systm.h" "../user.h" "../proc.h" "../buf.h" "../reg.h" "../inode.h"

/* * exec system call. * Because of the fact that an I/O buffer is used * to store the caller’s arguments during exec, * and more buffers are needed to read in the text file, * deadly embraces waiting for free buffers are possible. * Therefore the number of processes simultaneously * running in exec has to be limited to NEXEC. */ #define EXPRI -1 exec() { int ap, na, nc, *bp; int ts, ds, sep; register c, *ip; register char *cp; extern uchar; /* * pick up file names * and check various modes * for execute permission */ ip = namei(&uchar, 0); if(ip == NULL) return; while(execnt >= NEXEC) sleep(&execnt, EXPRI); execnt++; bp = getblk(NODEV); if(access(ip, IEXEC) || (ip->i_mode&IFMT)!=0) goto bad; /* * pack up arguments into * allocated disk buffer */ cp = bp->b_addr;

Sep

3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099

1 09:28 1988

unix/sys1.c Page 2

na = 0; nc = 0; while(ap = fuword(u.u_arg[1])) { na++; if(ap == -1) goto bad; u.u_arg[1] =+ 2; for(;;) { c = fubyte(ap++); if(c == -1) goto bad; *cp++ = c; nc++; if(nc > 510) { u.u_error = E2BIG; goto bad; } if(c == 0) break; } } if((nc&1) != 0) { *cp++ = 0; nc++; } /* read in first 8 bytes * of file for segment * sizes: * w0 = 407/410/411 (410 -> RO text) (411 -> sep ID) * w1 = text size * w2 = data size * w3 = bss size */ u.u_base = &u.u_arg[0]; u.u_count = 8; u.u_offset[1] = 0; u.u_offset[0] = 0; u.u_segflg = 1; readi(ip); u.u_segflg = 0; if(u.u_error) goto bad; sep = 0; if(u.u_arg[0] == 0407) { u.u_arg[2] =+ u.u_arg[1]; u.u_arg[1] = 0; } else if(u.u_arg[0] == 0411)

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 30

Sheet 30

Sep

1 09:28 1988

3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149

unix/sys1.c Page 3

sep++; else if(u.u_arg[0] != 0410) { u.u_error = ENOEXEC; goto bad; } if(u.u_arg[1]!=0&&(ip->i_flag&ITEXT)==0&&ip->i_count!=1){ u.u_error = ETXTBSY; goto bad; } /* * find text and data sizes * try them out for possible * exceed of max sizes */ ts = ((u.u_arg[1]+63)>>6) & 01777; ds = ((u.u_arg[2]+u.u_arg[3]+63)>>6) & 0177; if(estabur(ts, ds, SSIZE, sep)) goto bad; /* * allocate and clear core * at this point, committed * to the new image */ u.u_prof[3] = 0; xfree(); expand(USIZE); xalloc(ip); c = USIZE+ds+SSIZE; expand(c); while(--c >= USIZE) clearseg(u.u_procp->p_addr+c); /* read in data segment */ estabur(0, ds, 0, 0); u.u_base = 0; u.u_offset[1] = 020+u.u_arg[1]; u.u_count = u.u_arg[2]; readi(ip); /* * initialize stack segment */ u.u_tsize = ts; u.u_dsize = ds;

Sep

1 09:28 1988

unix/sys1.c Page 4

3150 u.u_ssize = SSIZE; 3151 u.u_sep = sep; 3152 estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep); 3153 cp = bp->b_addr; 3154 ap = -nc - na*2 - 4; 3155 u.u_ar0[R6] = ap; 3156 suword(ap, na); 3157 c = -nc; 3158 while(na--) { 3159 suword(ap=+2, c); 3160 do 3161 subyte(c++, *cp); 3162 while(*cp++); 3163 } 3164 suword(ap+2, -1); 3165 3166 /* 3167 * set SUID/SGID protections, if no tracing 3168 */ 3169 3170 if ((u.u_procp->p_flag&STRC)==0) { 3171 if(ip->i_mode&ISUID) 3172 if(u.u_uid != 0) { 3173 u.u_uid = ip->i_uid; 3174 u.u_procp->p_uid = ip->i_uid; 3175 } 3176 if(ip->i_mode&ISGID) 3177 u.u_gid = ip->i_gid; 3178 } 3179 3180 /* clear sigs, regs, and return */ 3181 3182 c = ip; 3183 for(ip = &u.u_signal[0]; ip < &u.u_signal[NSIG]; ip++) 3184 if((*ip & 1) == 0) 3185 *ip = 0; 3186 for(cp = ®loc[0]; cp < ®loc[6];) 3187 u.u_ar0[*cp++] = 0; 3188 u.u_ar0[R7] = 0; 3189 for(ip = &u.u_fsav[0]; ip < &u.u_fsav[25];) 3190 *ip++ = 0; 3191 ip = c; 3192 3193 bad: 3194 iput(ip); 3195 brelse(bp); 3196 if(execnt >= NEXEC) 3197 wakeup(&execnt); 3198 execnt--; 3199 }

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 31

Sheet 31

Sep

1 09:28 1988

unix/sys1.c Page 5

3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249

/* -------------------------

Sep

*/

/* exit system call: * pass back caller’s r0 */ rexit() { u.u_arg[0] = u.u_ar0[R0] p_flag =& ~STRC; for(q = &u.u_signal[0]; q < &u.u_signal[NSIG];) *q++ = 1; for(q = &u.u_ofile[0]; q < &u.u_ofile[NOFILE]; q++) if(a = *q) { *q = NULL; closef(a); } iput(u.u_cdir); xfree(); a = malloc(swapmap, 1); if(a == NULL) panic("out of swap"); p = getblk(swapdev, a); bcopy(&u, p->b_addr, 256); bwrite(p); q = u.u_procp; mfree(coremap, q->p_size, q->p_addr); q->p_addr = a; q->p_stat = SZOMB; loop: for(p = &proc[0]; p < &proc[NPROC]; p++) if(q->p_ppid == p->p_pid) { wakeup(&proc[1]); wakeup(p);

3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299

1 09:28 1988

unix/sys1.c Page 6

for(p = &proc[0]; p < &proc[NPROC]; p++) if(q->p_pid == p->p_ppid) { p->p_ppid = 1; if (p->p_stat == SSTOP) setrun(p); } swtch(); /* no return */ } q->p_ppid = 1; goto loop; } /* -------------------------

*/

/* Wait system call. * Search for a terminated (zombie) child, * finally lay it to rest, and collect its status. * Look also for stopped (traced) children, * and pass back status from them. */ wait() { register f, *bp; register struct proc *p; f = 0; loop: for(p = &proc[0]; p < &proc[NPROC]; p++) if(p->p_ppid == u.u_procp->p_pid) { f++; if(p->p_stat == SZOMB) { u.u_ar0[R0] = p->p_pid; bp = bread(swapdev, f=p->p_addr); mfree(swapmap, 1, f); p->p_stat = NULL; p->p_pid = 0; p->p_ppid = 0; p->p_sig = 0; p->p_ttyp = 0; p->p_flag = 0; p = bp->b_addr; u.u_cstime[0] =+ p->u_cstime[0]; dpadd(u.u_cstime, p->u_cstime[1]); dpadd(u.u_cstime, p->u_stime); u.u_cstime[0] =+ p->u_cutime[0]; dpadd(u.u_cutime, p->u_cutime[1]); dpadd(u.u_cutime, p->u_utime); u.u_ar0[R1] = p->u_arg[0]; brelse(bp); return;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 32

Sheet 32

Sep

3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349

1 09:28 1988

unix/sys1.c Page 7

Sep

} if(p->p_stat == SSTOP) { if((p->p_flag&SWTED) == 0) { p->p_flag =| SWTED; u.u_ar0[R0] = p->p_pid; u.u_ar0[R1] = (p->p_sigp_stat == NULL) goto found; u.u_error = EAGAIN; goto out; found: if(newproc()) { u.u_ar0[R0] = p1->p_pid; u.u_cstime[0] = 0; u.u_cstime[1] = 0; u.u_stime = 0; u.u_cutime[0] = 0; u.u_cutime[1] = 0; u.u_utime = 0; return; } u.u_ar0[R0] = p2->p_pid; out: u.u_ar0[R7] =+ 2; } /* -------------------------

*/

3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399

1 09:28 1988

unix/sys1.c Page 8

/* break system call. * -- bad planning: "break" is a dirty word in C. */ sbreak() { register a, n, d; int i; /* set n to new data size * set d to new-old * set n to new total size */ n = (((u.u_arg[0]+63)>>6) & 01777); if(!u.u_sep) n =- nseg(u.u_tsize) * 128; if(n < 0) n = 0; d = n - u.u_dsize; n =+ USIZE+u.u_ssize; if(estabur(u.u_tsize, u.u_dsize+d, u.u_ssize, u.u_sep)) return; u.u_dsize =+ d; if(d > 0) goto bigger; a = u.u_procp->p_addr + n - u.u_ssize; i = n; n = u.u_ssize; while(n--) { copyseg(a-d, a); a++; } expand(i); return; bigger: expand(n); a = u.u_procp->p_addr + n; n = u.u_ssize; while(n--) { a--; copyseg(a-d, a); } while(d--) clearseg(--a); } /* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 33

Sheet 33

Sep

1 09:28 1988

3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449

# /* * Everything in this file is * a routine implementing a system call. */ #include #include #include #include #include #include

unix/sys4.c Page 1

"../param.h" "../user.h" "../reg.h" "../inode.h" "../systm.h" "../proc.h"

getswit() { u.u_ar0[R0] = SW->integ; } /* -------------------------

*/

gtime() { u.u_ar0[R0] = time[0]; u.u_ar0[R1] = time[1]; } /* -------------------------

*/

stime() { if(suser()) { time[0] = u.u_ar0[R0]; time[1] = u.u_ar0[R1]; wakeup(tout); } } /* -------------------------

*/

setuid() { register uid; uid = u.u_ar0[R0].lobyte; if(u.u_ruid == uid.lobyte || suser()) { u.u_uid = uid; u.u_procp->p_uid = uid; u.u_ruid = uid; } }

Sep

1 09:28 1988

unix/sys4.c Page 2

3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499

/* -------------------------

*/

getuid() { u.u_ar0[R0].lobyte = u.u_ruid; u.u_ar0[R0].hibyte = u.u_uid; } /* -------------------------

*/

setgid() { register gid; gid = u.u_ar0[R0].lobyte; if(u.u_rgid == gid.lobyte || suser()) { u.u_gid = gid; u.u_rgid = gid; } } /* -------------------------

*/

getgid() { u.u_ar0[R0].lobyte = u.u_rgid; u.u_ar0[R0].hibyte = u.u_gid; } /* -------------------------

*/

getpid() { u.u_ar0[R0] = u.u_procp->p_pid; } /* ------------------------*/ sync() { update(); } /* -------------------------

*/

nice() { register n; n = u.u_ar0[R0]; if(n > 20) n = 20;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 34

Sheet 34

Sep

3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549

1 09:28 1988

unix/sys4.c Page 3

Sep

if(n < 0 && !suser()) n = 0; u.u_procp->p_nice = n; } /* -------------------------

*/

/* * Unlink system call. * panic: unlink -- "cannot happen" */ unlink() { register *ip, *pp; extern uchar; pp = namei(&uchar, 2); if(pp == NULL) return; prele(pp); ip = iget(pp->i_dev, u.u_dent.u_ino); if(ip == NULL) panic("unlink -- iget"); if((ip->i_mode&IFMT)==IFDIR && !suser()) goto out; u.u_offset[1] =- DIRSIZ+2; u.u_base = &u.u_dent; u.u_count = DIRSIZ+2; u.u_dent.u_ino = 0; writei(pp); ip->i_nlink--; ip->i_flag =| IUPD; out: iput(pp); iput(ip); } /* -------------------------

*/

chdir() { register *ip; extern uchar; ip = namei(&uchar, 0); if(ip == NULL) return; if((ip->i_mode&IFMT) != IFDIR) { u.u_error = ENOTDIR; bad: iput(ip);

3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599

1 09:28 1988

unix/sys4.c Page 4

return; } if(access(ip, IEXEC)) goto bad; iput(u.u_cdir); u.u_cdir = ip; prele(ip); } /* -------------------------

*/

chmod() { register *ip; if ((ip = owner()) == NULL) return; ip->i_mode =& ~07777; if (u.u_uid) u.u_arg[1] =& ~ISVTX; ip->i_mode =| u.u_arg[1]&07777; ip->i_flag =| IUPD; iput(ip); } /* -------------------------

*/

chown() { register *ip; if (!suser() || (ip = owner()) == NULL) return; ip->i_uid = u.u_arg[1].lobyte; ip->i_gid = u.u_arg[1].hibyte; ip->i_flag =| IUPD; iput(ip); } /* ------------------------/* * * * * *

*/

Change modified date of file: time to r0-r1; sys smdate; file This call has been withdrawn because it messes up incremental dumps (pseudo-old files aren’t dumped). It works though and you can uncomment it if you like.

smdate() { register struct inode *ip; register int *tp; int tbuf[2];

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 35

Sheet 35

Sep

3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649

1 09:28 1988

unix/sys4.c Page 5

Sep

if ((ip = owner()) == NULL) return; ip->i_flag =| IUPD; tp = &tbuf[2]; *--tp = u.u_ar0[R1]; *--tp = u.u_ar0[R0]; iupdat(ip, tp); ip->i_flag =& ~IUPD; iput(ip); } */ /* -------------------------

*/

ssig() { register a; a = u.u_arg[0]; if(a=NSIG || a ==SIGKIL) { u.u_error = EINVAL; return; } u.u_ar0[R0] = u.u_signal[a]; u.u_signal[a] = u.u_arg[1]; if(u.u_procp->p_sig == a) u.u_procp->p_sig = 0; } /* -------------------------

*/

kill() { register struct proc *p, *q; register a; int f; f = 0; a = u.u_ar0[R0]; q = u.u_procp; for(p = &proc[0]; p < &proc[NPROC]; p++) { if(p == q) continue; if(a != 0 && p->p_pid != a) continue; if(a==0&&(p->p_ttyp!=q->p_ttyp||pp_uid) continue; f++; psignal(p, u.u_arg[0]);

3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699

1 09:28 1988

unix/sys4.c Page 6

} if(f == 0) u.u_error = ESRCH; } /* -------------------------

*/

times() { register *p; for(p = &u.u_utime; p < &u.u_utime+6;) { suword(u.u_arg[0], *p++); u.u_arg[0] =+ 2; } } /* -------------------------

*/

profil() { u.u_prof[0] u.u_prof[1] u.u_prof[2] u.u_prof[3]

= = = =

u.u_arg[0] & ~1; u.u_arg[1]; u.u_arg[2]; (u.u_arg[3]>>1) &

} /* -------------------------

/* base of sample buf */ /* size of same */ /* pc offset */ 077777; /* pc scale */ */

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 36

Sheet 36

Sep

1 09:28 1988

3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749

# #include #include #include #include #define #define

unix/clock.c Page 1

"../param.h" "../systm.h" "../user.h" "../proc.h" UMODE SCHMAG

0170000 10

/* * clock is called straight from * the real time clock interrupt. * * Functions: * reprime clock * copy *switches to display * implement callouts * maintain user/system times * maintain date * profile * tout wakeup (sys sleep) * lightning bolt wakeup (every 4 sec) * alarm clock signals * jab the scheduler */ clock(dev, sp, r1, nps, r0, pc, ps) { register struct callo *p1, *p2; register struct proc *pp; /* * restart clock */ *lks = 0115; /* * display register */ display(); /* * callouts * if done, just return * else update first non-zero time */ if(callout[0].c_func == 0) goto out;

Sep

1 09:28 1988

unix/clock.c Page 2

3750 p2 = &callout[0]; 3751 while(p2->c_timec_func!=0) 3752 p2++; 3753 p2->c_time--; 3754 3755 /* 3756 * if ps is high, just return 3757 */ 3758 3759 if((ps&0340) != 0) 3760 goto out; 3761 3762 /* 3763 * callout 3764 */ 3765 3766 spl5(); 3767 if(callout[0].c_time c_func != 0 && p1->c_time c_func)(p1->c_arg); 3771 p1++; 3772 } 3773 p2 = &callout[0]; 3774 while(p2->c_func = p1->c_func) { 3775 p2->c_time = p1->c_time; 3776 p2->c_arg = p1->c_arg; 3777 p1++; 3778 p2++; 3779 } 3780 } 3781 3782 /* 3783 * lightning bolt time-out 3784 * and time of day 3785 */ 3786 3787 out: 3788 if((ps&UMODE) == UMODE) { 3789 u.u_utime++; 3790 if(u.u_prof[3]) 3791 incupc(ps, u.u_prof); 3792 } else 3793 u.u_stime++; 3794 pp = u.u_procp; 3795 if(++pp->p_cpu == 0) 3796 pp->p_cpu--; 3797 if(++lbolt >= HZ) { 3798 if((ps&0340) != 0) 3799 return;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 37

Sheet 37

Sep

3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849

1 09:28 1988

unix/clock.c Page 3

Sep

lbolt =- HZ; if(++time[1] == 0) ++time[0]; spl1(); if(time[1]==tout[1] && time[0]==tout[0]) wakeup(tout); if((time[1]&03) == 0) { runrun++; wakeup(&lbolt); } for(pp = &proc[0]; pp < &proc[NPROC]; pp++) if (pp->p_stat) { if(pp->p_time != 127) pp->p_time++; if((pp->p_cpu & 0377) > SCHMAG) pp->p_cpu =- SCHMAG; else pp->p_cpu = 0; if(pp->p_pri > PUSER) setpri(pp); } if(runin!=0) { runin = 0; wakeup(&runin); } if((ps&UMODE) == UMODE) { u.u_ar0 = &r0; if(issig()) psig(); setpri(u.u_procp); } } } /* -------------------------

*/

/* * timeout is called to arrange that * fun(arg) is called in tim/HZ seconds. * An entry is sorted into the callout * structure. The time in each structure * entry is the number of HZ’s more * than the previous entry. * In this way, decrementing the * first entry has the effect of * updating all entries. */ timeout(fun, arg, tim) { register struct callo *p1, *p2; register t; int s;

1 09:28 1988

3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 } 3874 /* 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899

unix/clock.c Page 4

t = tim; s = PS->integ; p1 = &callout[0]; spl7(); while(p1->c_func != 0 && p1->c_time c_time; p1++; } p1->c_time =- t; p2 = p1; while(p2->c_func != 0) p2++; while(p2 >= p1) { (p2+1)->c_time = p2->c_time; (p2+1)->c_func = p2->c_func; (p2+1)->c_arg = p2->c_arg; p2--; } p1->c_time = t; p1->c_func = fun; p1->c_arg = arg; PS->integ = s; -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 38

Sheet 38

Sep

1 09:28 1988

3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949

# /* */ #include #include #include #include #include #include

unix/sig.c Page 1

"../param.h" "../systm.h" "../user.h" "../proc.h" "../inode.h" "../reg.h"

/* * Priority for tracing */ #define IPCPRI (-1) /* * Structure to access an array of integers. */ struct { int inta[]; }; /* ------------------------*/ /* * Tracing variables. * Used to pass trace command from * parent to child being traced. * This data base cannot be * shared and is locked * per user. */ struct { int ip_lock; int ip_req; int ip_addr; int ip_data; } ipc; /* ------------------------*/ /* * Send the specified signal to * all processes with ’tp’ as its * controlling teletype. * Called by tty.c for quits and * interrupts. */ signal(tp, sig)

Sep

1 09:28 1988

3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999

{

unix/sig.c Page 2

register struct proc *p; for(p = &proc[0]; p < &proc[NPROC]; p++) if(p->p_ttyp == tp) psignal(p, sig); } /* -------------------------

*/

/* * Send the specified signal to * the specified process. */ psignal(p, sig) int *p; { register *rp; if(sig >= NSIG) return; rp = p; if(rp->p_sig != SIGKIL) rp->p_sig = sig; if(rp->p_stat > PUSER) rp->p_stat = PUSER; if(rp->p_stat == SWAIT) setrun(rp); } /* -------------------------

*/

/* * Returns true if the current * process has a signal to process. * This is asked at least once * each time a process enters the * system. * A signal does not do anything * directly to a process; it sets * a flag that asks the process to * do something to itself. */ issig() { register n; register struct proc *p; p = u.u_procp; if(n = p->p_sig) { if (p->p_flag&STRC) { stop();

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 39

Sheet 39

Sep

4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049

1 09:28 1988

unix/sig.c Page 3

Sep

if ((n = p->p_sig) == 0) return(0); } if((u.u_signal[n]&1) == 0) return(n); } return(0); } /* -------------------------

*/

/* * Enter the tracing STOP state. * In this state, the parent is * informed and the process is able to * receive commands from the parent. */ stop() { register struct proc *pp, *cp; loop: cp = u.u_procp; if(cp->p_pid != 1) for (pp = &proc[0]; pp < &proc[NPROC]; pp++) if (pp->p_pid == cp->p_ppid) { wakeup(pp); cp->p_stat = SSTOP; swtch(); if ((cp->p_flag&STRC)==0 || procxmt()) return; goto loop; } exit(); } /* ------------------------*/ /* * Perform the action specified by * the current signal. * The usual sequence is: * if(issig()) * psig(); */ psig() { register n, p; register *rp; rp = u.u_procp; n = rp->p_sig;

4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099

1 09:28 1988

unix/sig.c Page 4

rp->p_sig = 0; if((p=u.u_signal[n]) != 0) { u.u_error = 0; if(n != SIGINS && n != SIGTRC) u.u_signal[n] = 0; n = u.u_ar0[R6] - 4; grow(n); suword(n+2, u.u_ar0[RPS]); suword(n, u.u_ar0[R7]); u.u_ar0[R6] = n; u.u_ar0[RPS] =& ~TBIT; u.u_ar0[R7] = p; return; } switch(n) { case case case case case case case case case

SIGQIT: SIGINS: SIGTRC: SIGIOT: SIGEMT: SIGFPT: SIGBUS: SIGSEG: SIGSYS: u.u_arg[0] = n; if(core()) n =+ 0200;

} u.u_arg[0] = (u.u_ar0[R0]p_size - USIZE; estabur(0, s, 0, 0); u.u_base = 0; u.u_count = s*64; u.u_segflg = 0; writei(ip); } iput(ip); return(u.u_error==0); } /* -------------------------

*/

/* * grow the stack to include the SP * true return in successful. */ grow(sp) char *sp; { register a, si, i; if(sp >= -u.u_ssize*64) return(0); si = ldiv(-sp, 64) - u.u_ssize + SINCR; if(si p_size+si); a = u.u_procp->p_addr + u.u_procp->p_size;

4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199

1 09:28 1988

unix/sig.c Page 6

for(i=u.u_ssize; i; i--) { a--; copyseg(a-si, a); } for(i=si; i; i--) clearseg(--a); u.u_ssize =+ si; return(1); } /* -------------------------

*/

/* * sys-trace system call. */ ptrace() { register struct proc *p; if (u.u_arg[2] p_flag =| STRC; return; } for (p=proc; p < &proc[NPROC]; p++) if (p->p_stat==SSTOP && p->p_pid==u.u_arg[0] && p->p_ppid==u.u_procp->p_pid) goto found; u.u_error = ESRCH; return; found: while (ipc.ip_lock) sleep(&ipc, IPCPRI); ipc.ip_lock = p->p_pid; ipc.ip_data = u.u_ar0[R0]; ipc.ip_addr - u.u_arg[1] & ~01; ipc.ip_req = u.u_arg[2]; p->p_flag =& ~SWTED; setrun(p); while (ipc.ip_req > 0) sleep(&ipc, IPCPRI); u.u_ar0[R0] = ipc.ip_data; if (ipc.ip_req < 0) u.u_error = EIO; ipc.ip_lock = 0; wakeup(&ipc); } /* -------------------------

*/

/*

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 41

Sheet 41

Sep

1 09:28 1988

unix/sig.c Page 7

Sep

1 09:28 1988

unix/sig.c Page 8

4200 * Code that the child process 4201 * executes to implement the command 4202 * of the parent process in tracing. 4203 */ 4204 procxmt() 4205 { 4206 register int i; 4207 register int *p; 4208 4209 if (ipc.ip_lock != u.u_procp->p_pid) 4210 return(0); 4211 i = ipc.ip_req; 4212 ipc.ip_req = 0; 4213 wakeup(&ipc); 4214 switch (i) { 4215 4216 /* read user I */ 4217 case 1: 4218 if (fuibyte(ipc.ip_addr) == -1) 4219 goto error; 4220 ipc.ip_data = fuiword(ipc.ip_addr); 4221 break; 4222 4223 /* read user D */ 4224 case 2: 4225 if (fubyte(ipc.ip_addr) == -1) 4226 goto error; 4227 ipc.ip_data = fuword(ipc.ip_addr); 4228 break; 4229 4230 /* read u */ 4231 case 3: 4232 i = ipc.ip_addr; 4233 if (i= (USIZE1]; 4236 break; 4237 4238 /* write user I (for now, always an error) */ 4239 case 4: 4240 if (suiword(ipc.ip_addr, 0) < 0) 4241 goto error; 4242 suiword(ipc.ip_addr, ipc.ip_data); 4243 break; 4244 4245 /* write user D */ 4246 case 5: 4247 if (suword(ipc.ip_addr, 0) < 0) 4248 goto error; 4249 suword(ipc.ip_addr, ipc.ip_data);

4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 } 4286 /* 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299

break;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 42

Sheet 42

/* write u */ case 6: p = &u.inta[ipc.ip_addr>>1]; if (p >= u.u_fsav && p < &u.u_fsav[25]) goto ok; for (i=0; ip_sig = ipc.ip_data; return(1); /* force exit */ case 8: exit(); default: error: ipc.ip_req = -1; } return(0); -------------------------

*/

3 Program Swapping Basic Input/Output Block Devices

Sep

1 09:28 1988

unix/text.h Page 1

Sep

4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349

/* 4350 * Text structure. 4351 * One allocated per pure 4352 * procedure on swap device. 4353 * Manipulated by text.c 4354 */ 4355 struct text 4356 { 4357 int x_daddr; /* disk address of segment */ 4358 int x_caddr; /* core address, if loaded */ 4359 int x_size; /* size (*64) */ 4360 int *x_iptr; /* inode of prototype */ 4361 char x_count; /* reference count */ 4362 char x_ccount; /* number of loaded references */ 4363 } text[NTEXT]; 4364 /* ------------------------*/ 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399

1 09:28 1988

# #include #include #include #include #include #include

unix/text.c Page 1

"../param.h" "../systm.h" "../user.h" "../proc.h" "../text.h" "../inode.h"

/* Swap out process p. * The ff flag causes its core to be freed-* it may be off when called to create an image for a * child process in newproc. * Os is the old size of the data area of the process, * and is supplied during core expansion swaps. * * panic: out of swap space * panic: swap error -- IO error */ xswap(p, ff, os) int *p; { register *rp, a; rp = p; if(os == 0) os = rp->p_size; a = malloc(swapmap, (rp->p_size+7)/8); if(a == NULL) panic("out of swap space"); xccdec(rp->p_textp); rp->p_flag =| SLOCK; if(swap(a, rp->p_addr, os, 0)) panic("swap error"); if(ff) mfree(coremap, os, rp->p_addr); rp->p_addr = a; rp->p_flag =& ~(SLOAD|SLOCK); rp->p_time = 0; if(runout) { runout = 0; wakeup(&runout); } } /* -------------------------

*/

/* * relinquish use of the shared text segment * of a process. */ xfree() { register *xp, *ip;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 43

Sheet 43

Sep

1 09:28 1988

unix/text.c Page 2

4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449

4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 } 4465 /* ------------------------*/ 4466 4467 /* Attach to a shared text segment. 4468 * If there is no shared text, just return. 4469 * If there is, hook up to it: 4470 * if it is not currently being used, it has to be read 4471 * in from the inode (ip) and established in the swap space. 4472 * If it is being used, but not currently in core, 4473 * a swap has to be done to get it back. 4474 * The full coroutine glory has to be invoked-4475 * see slp.c-- because if the calling process 4476 * is misplaced in core the text image might not fit. 4477 * Quite possibly the code after "out:" could check to 4478 * see if the text does fit and simply swap it in. 4479 * 4480 * panic: out of swap space 4481 */ 4482 xalloc(ip) 4483 int *ip; 4484 { 4485 register struct text *xp; 4486 register *rp, ts; 4487 4488 if(u.u_arg[1] == 0) return; 4489 rp = NULL; 4490 for(xp = &text[0]; xp < &text[NTEXT]; xp++) 4491 if(xp->x_iptr == NULL) { 4492 if(rp == NULL) 4493 rp = xp; 4494 } else 4495 if(xp->x_iptr == ip) { 4496 xp->x_count++; 4497 u.u_procp->p_textp = xp; 4498 goto out; 4499 if((xp=u.u_procp->p_textp) != NULL) { u.u_procp->p_textp == NULL; xccdec(xp); if(--xp->x_count == 0) { ip = xp->x_iptr; if((ip->i_mode&ISVTX) == 0) { xp->x_iptr = NULL; mfree(swapmap, (xp->x_size+7)/8, xp->x_daddr); ip->i_flag =& ~ITEXT; iput(ip); } } }

Sep

1 09:28 1988

unix/text.c Page 3

} if((xp=rp) == NULL) panic("out of text"); xp->x_count = 1; xp->x_ccount = 0; xp->x_iptr = ip; ts = ((u.u_arg[1]+63)>>6) & 01777; xp->x_size = ts; if((xp->x_daddr = malloc(swapmap, (ts+7)/8)) == NULL) panic("out of swap space"); expand(USIZE+ts); estabur(0, ts, 0, 0); u.u_count = u.u_arg[1]; u.u_offset[1] = 020; u.u_base = 0; readi(ip); rp = u.u_procp; rp->p_flag =| SLOCK; swap(xp->x_daddr, rp->p_addr+USIZE, ts, 0); rp->p_flag =& ~SLOCK; rp->p_textp = xp; rp = ip; rp->i_flag =| ITEXT; rp->i_count++; expand(USIZE); out: if(xp->x_ccount == 0) { savu(u.u_rsav); savu(u.u_ssav); xswap(u.u_procp, 1, 0); u.u_procp->p_flag =| SSWAP; swtch(); /* no return */ } xp->x_ccount++; } /* ------------------------*/ /* Decrement the in-core usage count of a shared text * segment. When it drops to zero, free the core space. */ xccdec(xp) int *xp; { register *rp; if((rp=xp)!=NULL && rp->x_ccount!=0) if(--rp->x_ccount == 0) mfree(coremap, rp->x_size, rp->x_caddr); }

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 44

Sheet 44

Sep

1 09:28 1988

unix/buf.h Page 1

Sep

4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549

/* 4550 * Each buffer in the pool is usually doubly linked into two 4551 * lists: for the device with which it is currently associat-4552 * ed (always) and also for a list of blocks available for 4553 * allocation for other use (usually). 4554 * The latter list is kept in last-used order, and the two 4555 * lists are doubly linked to make it easy to remove 4556 * a buffer from one list when it was found by 4557 * looking through the other. 4558 * A buffer is on the available list, and is liable 4559 * to be reassigned to another disk block, if and only 4560 * if it is not marked BUSY. When a buffer is busy, the 4561 * available-list pointers can be used for other purposes. 4562 * Most drivers use the forward ptr as a link in their I/O 4563 * active queue. 4564 * A buffer header contains all the information required 4565 * to perform I/O. 4566 * Most of the routines which manipulate these things 4567 * are in bio.c. 4568 */ 4569 struct buf 4570 { 4571 int b_flags; /* see defines below */ 4572 struct buf *b_forw; /* headed by devtab of b_dev */ 4573 struct buf *b_back; /* " */ 4574 struct buf *av_forw; /* position on free list, */ 4575 struct buf *av_back; /* if not BUSY*/ 4576 int b_dev; /* major+minor device name */ 4577 int b_wcount; /* transfer count (usu. words) */ 4578 char *b_addr; /* low order core address */ 4579 char *b_xmem; /* high order core address */ 4580 char *b_blkno; /* block # on device */ 4581 char b_error; /* returned after I/O */ 4582 char *b_resid; /* words not transferred after 4583 error */ 4584 } buf[NBUF]; 4585 /* ------------------------*/ 4586 4587 /* 4588 * Each block device has a devtab, which contains private 4589 * state stuff and 2 list heads: the b_forw/b_back list, 4590 * which is doubly linked and has all the buffers currently 4591 * associated with the major device; 4592 * and the d_actf/d_actl list, which is private to the 4593 * device but in fact is always used for the head and tail 4594 * of the I/O queue for the device. 4595 * Various routines in bio.c look at b_forw/b_back 4596 * (notice they are the same as in the buf structure) 4597 * but the rest is private to each device driver. 4598 */ 4599

1 09:28 1988

unix/buf.h Page 2

struct devtab { char d_active; /* char d_errcnt; /* struct buf *b_forw; /* struct buf *b_back; /* struct buf *d_actf; /* struct buf *d_actl; /* }; /* -------------------------

busy flag */ error count (for recovery)*/ first buffer for this dev */ last buffer for this dev */ head of I/O queue */ tail of I/O queue */ */

/* * This is the head of the queue of available * buffers-- all unused except for the 2 list heads. */ struct

buf bfreelist;

/* * These */ #define #define #define #define #define #define

B_WRITE B_READ B_DONE B_ERROR B_BUSY B_PHYS

0 01 02 04 010 020

#define

B_MAP

040

#define

B_WANTED

0100

#define #define

B_RELOC B_ASYNC

0200 0400

#define

B_DELWRI

01000

flags are kept in b_flags. /* non-read pseudo-flag */ /* read when I/O occurs */ /* transaction finished */ /* transaction aborted */ /* not on av_forw/back list */ /* Physical IO potentially using the Unibus map */ /* This block has the UNIBUS map allocated */ /* issue wakeup when BUSY goes off */ /* no longer used */ /* don’t wait wait for I/O completion */ /* don’t write till block leaves available list */

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 45

Sheet 45

Sep

1 09:28 1988

unix/conf.h Page 1

4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649

/* Used to dissect integer device code * into major (driver designation) and * minor (driver parameter) parts. */ struct { char d_minor; char d_major; }; /* ------------------------*/ /* Declaration of block device * switch. Each entry (row) is * the only link between the * main unix code and the driver. * The initialization of the * device switches is in the * file conf.c. */ struct bdevsw { int (*d_open)(); int (*d_close)(); int (*d_strategy)(); int *d_tab; } bdevsw[]; /* ------------------------*/ /* Nblkdev is the number of entries * (rows) in the block switch. It is * set in binit/bio.c by making * a pass over the switch. * Used in bounds checking on major * device numbers. */ int nblkdev; /* Character device switch. */ struct cdevsw { int (*d_open)(); int (*d_close)(); int (*d_read)(); int (*d_write)(); int (*d_sgtty)(); } cdevsw[]; /* -------------------------

*/

/* Number of character switch entries. * Set by cinit/tty.c */ int nchrdev;

Sep

1 09:28 1988

unix/conf.c Page 1

4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699

/* * this file is created, along with the file "low.s", * by the program "mkconf.c", to reflect the actual * configuration of peripheral devices on a system. */ int (*bdevsw[])() { &nulldev, &nulldev, &rkstrategy, &nodev, &nodev, &nodev, 0, /* rp &nodev, &nodev, &nodev, 0, /* rf &nodev, &nodev, &nodev, 0, /* tm &nodev, &nodev, &nodev, 0, /* tc &nodev, &nodev, &nodev, 0, /* hs &nodev, &nodev, &nodev, 0, /* hp &nodev, &nodev, &nodev, 0, /* ht 0 };

&rktab, /*rk */ */ */ */ */ */ */ */

int (*cdevsw[])() { &klopen, &klclose, &klread, &klwrite, &klsgtty, /* console */ &pcopen, &pcclose, &pcread, &pcwrite, &nodev, /* pc */ &lpopen, &lpclose, &nodev, &lpwrite, &nodev, /* lp */ &nodev, &nodev, &nodev, &nodev, &nodev, /* dc &nodev, &nodev, &nodev, &nodev, &nodev, /* dh &nodev, &nodev, &nodev, &nodev, &nodev, /* dp &nodev, &nodev, &nodev, &nodev, &nodev, /* dj &nodev, &nodev, &nodev, &nodev, &nodev, /* dn &nulldev, &nulldev, &mmread, &mmwrite, &nodev, /* mem */ &nulldev, &nulldev, &rkread, &rkwrite, &nodev, /* rk */ &nodev, &nodev, &nodev, &nodev, &nodev, /* rf &nodev, &nodev, &nodev, &nodev, &nodev, /* rp &nodev, &nodev, &nodev, &nodev, &nodev, /* tm &nodev, &nodev, &nodev, &nodev, &nodev, /* hs &nodev, &nodev, &nodev, &nodev, &nodev, /* hp &nodev, &nodev, &nodev, &nodev, &nodev, /* ht 0 }; int int int int

*/ */ */ */ */

*/ */ */ */ */ */

rootdev {(0b_flags&B_DONE) == 0) { rbp->b_flags =| B_READ; rbp->b_wcount = -256; (*bdevsw[adev.d_major].d_strategy)(rbp); } } if (rablkno && !incore(dev, rablkno)) { rabp = getblk(dev, rablkno); if (rabp->b_flags & B_DONE) brelse(rabp); else { rabp->b_flags =| B_READ|B_ASYNC; rabp->b_wcount = -256; (*bdevsw[adev.d_major].d_strategy)(rabp); } } if (rbp==0) return(bread(dev, blkno));

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 47

Sheet 47

Sep

4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849

1 09:28 1988

unix/bio.c Page 3

iowait(rbp); return(rbp); } /* -------------------------

*/

/* * Write the buffer, waiting for completion. * The release the buffer. */ bwrite(bp) struct buf *bp; { register struct buf *rbp; register flag; rbp = bp; flag = rbp->b_flags; rbp->b_flags =& ~(B_READ | B_DONE | B_ERROR | B_DELWRI); rbp->b_wcount = -256; (*bdevsw[rbp->b_dev.d_major].d_strategy)(rbp); if ((flag&B_ASYNC) == 0) { iowait(rbp); brelse(rbp); } else if ((flag&B_DELWRI)==0) geterror(rbp); } /* -------------------------

*/

/* * Release the buffer, marking it so that if it is grabbed * for another purpose it will be written out before being * given up (e.g. when writing a partial block where it is * assumed that another write for the same block will soon * follow). This can’t be done for magtape, since writes * must be done in the same order as requested. */ bdwrite(bp) struct buf *bp; { register struct buf *rbp; register struct devtab *dp; rbp = bp; dp = bdevsw[rbp->b_dev.d_major].d_tab; if (dp == &tmtab || dp == &httab) bawrite(rbp); else { rbp->b_flags =| B_DELWRI | B_DONE; brelse(rbp); }

Sep

1 09:28 1988

unix/bio.c Page 4

4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899

} /* -------------------------

*/

/* Release the buffer, start I/O on it, but don’t wait * for completion */ bawrite(bp) struct buf *bp; { register struct buf *rbp; rbp = bp; rbp->b_flags =| B_ASYNC; bwrite(rbp); } /* -------------------------

*/

/* release the buffer, with no I/O implied. */ brelse(bp) struct buf *bp; { register struct buf *rbp, **backp; register int sps; rbp = bp; if (rbp->b_flags&B_WANTED) wakeup(rbp); if (bfreelist.b_flags&B_WANTED) { bfreelist.b_flags =& ~B_WANTED; wakeup(&bfreelist); } if (rbp->b_flags&B_ERROR) rbp->b_dev.d_minor = -1; /* no assoc. on error */ backp = &bfreelist.av_back; sps = PS->integ; spl6(); rbp->b_flags =& ~(B_WANTED|B_BUSY|B_ASYNC); (*backp)->av_forw = rbp; rbp->av_back = *backp; *backp = rbp; rbp->av_forw = &bfreelist; PS->integ = sps; } /* -------------------------

*/

/* See if the block is associated with some buffer * (mainly to avoid getting hung up on a wait in breada) */ incore(adev, blkno)

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 48

Sheet 48

Sep

1 09:28 1988

4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949

{

unix/bio.c Page 5

Sep

4950 4951 4952 4953 4954 dev = adev; 4955 dp = bdevsw[adev.d_major].d_tab; 4956 for (bp=dp->b_forw; bp != dp; bp = bp->b_forw) 4957 if (bp->b_blkno==blkno && bp->b_dev==dev) 4958 return(bp); 4959 return(0); 4960 } 4961 /* ------------------------*/ 4962 4963 /* Assign a buffer for the given block. If the appropriate 4964 * block is already associated, return it; otherwise search 4965 * for the oldest non-busy buffer and reassign it. 4966 * When a 512-byte area is wanted for some random reason 4967 * (e.g. during exec, for the user arglist) getblk can be 4968 * called with device NODEV to avoid unwanted associativity. 4969 */ 4970 getblk(dev, blkno) 4971 { 4972 register struct buf *bp; 4973 register struct devtab *dp; 4974 extern lbolt; 4975 4976 if(dev.d_major >= nblkdev) 4977 panic("blkdev"); 4978 4979 loop: 4980 if (dev < 0) 4981 dp = &bfreelist; 4982 else { 4983 dp = bdevsw[dev.d_major].d_tab; 4984 if(dp == NULL) 4985 panic("devtab"); 4986 for (bp=dp->b_forw; bp != dp; bp = bp->b_forw) { 4987 if (bp->b_blkno!=blkno || bp->b_dev!=dev) 4988 continue; 4989 spl6(); 4990 if (bp->b_flags&B_BUSY) { 4991 bp->b_flags =| B_WANTED; 4992 sleep(bp, PRIBIO); 4993 spl0(); 4994 goto loop; 4995 } 4996 spl0(); 4997 notavail(bp); 4998 return(bp); 4999 register int dev; register struct buf *bp; register struct devtab *dp;

1 09:28 1988

unix/bio.c Page 6

} } spl6(); if (bfreelist.av_forw == &bfreelist) { bfreelist.b_flags =| B_WANTED; sleep(&bfreelist, PRIBIO); spl0(); goto loop; } spl0(); notavail(bp = bfreelist.av_forw); if (bp->b_flags & B_DELWRI) { bp->b_flags =| B_ASYNC; bwrite(bp); goto loop; } bp->b_flags = B_BUSY | B_RELOC; bp->b_back->b_forw = bp->b_forw; bp->b_forw->b_back = bp->b_back; bp->b_forw = dp->b_forw; bp->b_back = dp; dp->b_forw->b_back = bp; dp->b_forw = bp; bp->b_dev = dev; bp->b_blkno = blkno; return(bp); } /* -------------------------

*/

/* Wait for I/O completion on the buffer; return errors * to the user. */ iowait(bp) struct buf *bp; { register struct buf *rbp; rbp = bp; spl6(); while ((rbp->b_flags&B_DONE)==0) sleep(rbp, PRIBIO); spl0(); geterror(rbp); } /* -------------------------

*/

/* Unlink a buffer from the available list and mark it busy. * (internal interface) */ notavil(bp)

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 49

Sheet 49

Sep

1 09:28 1988

unix/bio.c Page 7

5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049

struct buf *bp; { register struct buf *rbp; register int sps; rbp = bp; sps = PS->integ; spl6(); rbp->av_back->av_forw = rbp->av_forw; rbp->av_forw->av_back = rbp->av_back; rbp->b_flags =| B_BUSY; PS->integ = sps; } /* -------------------------

*/

/* Mark I/O complete on a buffer, release it if i/o is * asynchronous, and wake up anyone waiting for it. */ iodone(bp) struct buf *bp; { register struct buf *rbp; rbp = bp; if(rbp->b_flags*B_MAP) mapfree(rbp); rbp->b_flags =| B_DONE; if (rbp->b_flags&B_ASYNC) brelse(rbp); else { rbp->b_flags =& ~B_WANTED; wakeup(rbp); } } /* -------------------------

*/

/* Zero the core associated with a buffer. */ clrbuf(bp) int *bp; { register *p; register c; p = bp->b_addr; c = 256; do *p++ = 0; while(--c); }

Sep

1 09:28 1988

unix/bio.c Page 8

5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099

/* -------------------------

*/

/* Initialize the buffer I/O system by freeing * all buffers and setting all device buffer lists to empty. */ binit() { register struct buf *bp; register struct devtab *dp; register int i; struct bdevsw *bdp; bfreelist.b_forw = bfreelist.b_back = bfreelist.av_forw = bfreelist.av_back = &bfreelist; for (i=0; ib_dev = -1; bp->b_addr = buffers[i]; bp->b_back = &bfreelist; bp->b_forw = bfreelist.b_forw; bfreelist.b_forw->b_back = bp; bfreelist.b_forw = bp; bp->b_flags = B_BUSY; brelse(bp); } i = 0; for (bdp = bdevsw; bdp->d_open; bdp++) { dp = bdp->d_tab; if(dp) { dp->b_forw = dp; dp->b_back = dp; } i++; } nblkdev = i; } /* -------------------------

*/

/* Device start routine for disks * and other devices that have the register * layout of the older DEC controllers (RF, RK, RP, TM) */ #define IENABLE 0100 #define WCOM 02 #define RCOM 04 #define GO 01 devstart(bp, devloc, devblk, hbcom) struct buf *bp; int *devloc; {

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 50

Sheet 50

Sep

5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149

1 09:28 1988

unix/bio.c Page 9

register int *dp; register struct buf *rbp; register int com; dp = devloc; rbp = bp; *dp = devblk; /* *--dp = rbp->b_addr; /* *--dp = rbp->b_wcount; /* com = (hbcomb_xmem; *dp = devblk; /* block address */ *--dp = rbp->b_addr; /* buffer address */ *--dp = rbp->b_wcount; /* word count */ com = IENABLE | GO | ((rbp->b_xmem & 03) b_flags&B_READ) /* command + x-mem */ com =| RHRCOM; else com =| RHWCOM; *--dp = com; } /* -------------------------

*/

/* * 11/70 routine to allocate the * UNIBUS map and initialize for

Sep

1 09:28 1988

unix/bio.c Page 10

5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199

* a unibus device. * The code here and in * rhstart assumes that an rh on an 11/70 * is an rh70 and contains 22 bit addressing. */ int maplock; mapalloc(abp) struct buf *abp; { register i, a; register struct buf *bp; if(cputype != 70) return; spl6(); while(maplock&B_BUSY) { maplock =| B_WANTED; sleep(&maplock, PSWP); } maplock =| B_BUSY; spl0(); bp = abp; bp->b_flags =| B_MAP; a = bp->b_xmem; for(i=16; ir[i+1] = a; for(a++; ir[i+1] = a; bp->b_xmem = 1; } /* -------------------------

*/

mapfree(bp) struct buf *bp; { bp->b_flags =& ~B_MAP; if(maplock&B_WANTED) wakeup(&maplock); maplock = 0; } /* -------------------------

*/

/* * swap I/O */ swap(blkno, coreaddr, count, rdflg) { register int *fp;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 51

Sheet 51

Sep

5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249

1 09:28 1988

unix/bio.c Page 11

fp = &swbuf.b_flags; spl6(); while (*fp&B_BUSY) { *fp =| B_WANTED; sleep(fp, PSWP); } *fp = B_BUSY | B_PHYS | rdflg; swbuf.b_dev = swapdev; swbuf.b_wcount = - (count8].d_strategy)(&swbuf); spl6(); while((*fp&B_DONE)==0) sleep(fp, PSWP); if (*fp&B_WANTED) wakeup(fp); spl0(); *fp =& ~(B_BUSY|B_WANTED); return(*fp&B_ERROR); } /* -------------------------

*/

/* make sure all write-behind blocks * on dev (or NODEV for all) * are flushed out. * (from umount and update) */ bflush(dev) { register struct buf *bp; loop: spl6(); for (bp = bfreelist.av_forw; bp != &bfreelist; bp = bp->av_forw) { if (bp->b_flags&B_DELWRI && (dev == NODEV||dev == bp->b_dev)) { bp->b_flags =| B_ASYNC; notavail(bp); bwrite(bp); goto loop; } } spl0(); } /* ------------------------*/ /*

Sep

1 09:28 1988

unix/bio.c Page 12

5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299

* Raw I/O. The arguments are * The strategy routine for the device * A buffer, which will always be a special buffer * header owned exclusively by the device for this purpose * The device number * Read/write flag * Essentially all the work is computing physical addresses * and validating them. */ physio(strat, abp, dev, rw) struct buf *abp; int (*strat)(); { register struct buf *bp; register char *base; register int nb; int ts; bp = abp; base = u.u_base; /* * Check odd base, odd count, and address wraparound */ if (base&01 || u.u_count&01 || base>=base+u.u_count) goto bad; ts = (u.u_tsize+127) & ~0177; if (u.u_sep) ts = 0; nb = (base>>6) & 01777; /* * Check overlap with text. (ts and nb now * in 64-byte clicks) */ if (nb < ts) goto bad; /* * Check that transfer is either entirely in the * data or in the stack: that is, either * the end is in the data or the start is in the stack * (remember wraparound was already checked). */ if ((((base+u.u_count)>>6)&01777) >= ts+u.u_dsize && nb < 1024-u.u_ssize) goto bad; spl6(); while (bp->b_flags&B_BUSY) { bp->b_flags =| B_WANTED; sleep(bp, PRIBIO); } bp->b_flags = B_BUSY | B_PHYS | rw;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 52

Sheet 52

Sep

1 09:28 1988

unix/bio.c Page 13

5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349

bp->b_dev = dev; /* * Compute physical address by simulating * the segmentation hardware. */ bp->b_addr = base&077; base = (u.u_sep? UDSA: UISA)->r[nb>>7] + (nb&0177); bp->b_addr =+ base>10) & 077; bp->b_blkno = lshift(u.u_offset, -9); bp->b_wcount = -((u.u_count>>1) & 077777); bp->b_error = 0; u.u_procp->p_flag =| SLOCK; (*strat)(bp); spl6(); while ((bp->b_flags&B_DONE) == 0) sleep(bp, PRIBIO); u.u_procp->p_flag =& ~SLOCK; if (bp->b_flags&B_WANTED) wakeup(bp); spl0(); bp->b_flags =& ~(B_BUSY|B_WANTED); u.u_count = (-bp->b_resid)b_error)==0) u.u_error = EIO; } /* -------------------------

*/

Sep

1 09:28 1988

5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399

# /* */

unix/rk.c Page 1

/* * RK disk driver */ #include #include #include #include

"../param.h" "../buf.h" "../conf.h" "../user.h"

#define #define #define

RKADDR NRK NRKBLK

0177400 4 4872

#define #define #define #define #define #define #define #define

RESET GO DRESET IENABLE DRY ARDY WLO CTLRDY

0 01 014 0100 0200 0100 020000 0200

struct { int rkds; int rker; int rkcs; int rkwc; int rkba; int rkda; }; /* ------------------------struct struct

devtab buf

*/

rktab; rrkbuf;

rkstrategy(abp) struct buf *abp; { register struct buf *bp; register *qc, *ql; int d; bp = abp; if(bp->b_flags&B_PHYS) mapalloc(bp); d = bp->b_dev.d_minor-7;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 53

Sheet 53

Sep

5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449

1 09:28 1988

unix/rk.c Page 2

Sep

if(d b_blkno >= NRKBLK*d) { bp->b_flags =| B_ERROR; iodone(bp); return; } bp->av_forw = 0; spl5(); if (rktab.d_actf==0) rktab.d_actf = bp; else rktab.d_actl->av_forw = bp; rktab.d_actl = bp; if (rktab.d_active==0) rkstart(); spl0(); } /* -------------------------

*/

rkaddr(bp) struct buf *bp; { register struct buf *p; register int b; int d, m; p = bp; b = p->b_blkno; m = p->b_dev.d_minor - 7; if(m b_dev.d_minor; else { d = lrem(b, m); b = ldiv(b, m); } return(drkds); RKADDR->rkcs = RESET|GO; while((RKADDR->rkcs&CTLRDY) == 0) ; if (++rktab.d_errcnt b_flags =| B_ERROR; } rktab.d_errcnt = 0; rktab.d_actf = bp->av_forw; iodone(bp); rkstart(); } /* -------------------------

*/

rkread(dev) { physio(rkstrategy, &rrkbuf, dev, B_READ); } /* ------------------------*/ rkwrite(dev) { physio(rkstrategy, &rrkbuf, dev, B_WRITE); } /* ------------------------*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 54

Sheet 54

4 Files and Directories File Systems Pipes

Sep

1 09:28 1988

unix/file.h Page 1

Sep

5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549

/* 5550 * One file structure is allocated 5551 * for each open/creat/pipe call. 5552 * Main use is to hold the read/write 5553 * pointer associated with each open 5554 * file. 5555 */ 5556 struct file 5557 { 5558 char f_flag; 5559 char f_count; /* reference count */ 5560 int f_inode; /* pointer to inode structure */ 5561 char *f_offset[2]; /* read/write character pointer */5562 } file[NFILE]; 5563 /* ------------------------*/ 5564 5565 /* flags */ 5566 #define FREAD 01 5567 #define FWRITE 02 5568 #define FPIPE 04 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599

1 09:28 1988

unix/filsys.h Page 1

/* * Definition of the unix super block. * The root super block is allocated and * read in iinit/alloc.c. Subsequently * a super block is allocated and read * with each mount (smount/sys3.c) and * released with umount (sumount/sys3.c). * A disk block is ripped of for storage. * See alloc.c for general alloc/free * routines for free list and I list. */ struct filsys { int s_isize; /* size in blocks of I list */ int s_fsize; /* size in blocks of entire volume */ int s_nfree; /* number of in core free blocks (between 0 and 100) */ int s_free[100]; /* in core free blocks */ int s_ninode; /* number of in core I nodes (0-100) */ int s_inode[100];/* in core free I nodes */ char s_flock; /* lock during free list manipulation */ char s_ilock; /* lock during I list manipulation */ char s_fmod; /* super block modified flag */ char s_ronly; /* mounted read-only flag */ int s_time[2]; /* current date of last update */ int pad[50]; }; /* ------------------------*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 55

Sheet 55

Sep

1 09:28 1988

unix/ino.h Page 1

5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649

/* * Inode structure as it appears on * the disk. Not used by the system, * but by things like check, df, dump. */ struct inode { int i_mode; char i_nlink; char i_uid; char i_gid; char i_size0; char *i_size1; int i_addr[8]; int i_atime[2]; int i_mtime[2]; }; /* ------------------------*/ /* modes */ #define IALLOC #define IFMT #define IFDIR #define IFCHR #define IFBLK #define ILARG #define ISUID #define ISGID #define ISVTX #define IREAD #define IWRITE #define IEXEC

0100000 060000 040000 020000 060000 010000 04000 02000 01000 0400 0200 0100

Sep

1 09:28 1988

unix/inode.h Page 1

5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699

/* The I node is the focus of all * file activity in unix. There is a unique * inode allocated for each active file, * each current directory, each mounted-on * file, text file, and the root. An inode is ’named’ * by its dev/inumber pair. (iget/iget.c) * Data, from mode on, is read in * from permanent inode on volume. */ struct inode { char i_flag; char i_count; /* reference count */ int i_dev; /* device where inode resides */ int i_number; /* i number, 1-to-1 with device address */ int i_mode; char i_nlink; /* directory entries */ char i_uid; /* owner */ char i_gid; /* group of owner */ char i_size0; /* most significant of size */ char *i_size1; /* least sig */ int i_addr[8];/* device addresses constituting file */ int i_lastr; /* last logical block read (for read-ahead) */ } inode[NINODE]; /* ------------------------*/ /* flags */ #define ILOCK #define IUPD #define IACC #define IMOUNT #define IWANT #define ITEXT

01 02 04 010 020 040

/* modes */ #define IALLOC #define IFMT #define IFDIR #define IFCHR #define IFBLK #define ILARG #define ISUID #define ISGID #define ISVTX #define IREAD #define IWRITE #define IEXEC

0100000 060000 040000 020000 060000 010000 04000 02000 01000 0400 0200 0100

/* /* /* /* /* /*

inode is locked */ inode has been modified */ inode access time to be updated */ inode is mounted on */ some process waiting on lock */ inode is pure text prototype */

/* /* /* /* /* /* /* /* /* /*

file is used */ type of file */ directory */ character special */ block special, 0 is regular */ large addressing algorithm */ set user id on execution */ set group id on execution */ save swapped text even after use */ read, write, execute permissions */

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 56

Sheet 56

Sep

1 09:28 1988

5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749

# #include #include #include #include #include #include

unix/sys2.c Page 1

Sep

"../param.h" "../systm.h" "../user.h" "../reg.h" "../file.h" "../inode.h"

/* * read system call */ read() { rdwr(FREAD); } /* ------------------------/* * write system call */ write() { rdwr(FWRITE); } /* -------------------------

*/

*/

/* * common code for read and write calls: * check permissions, set base, count, and offset, * and switch out to readi, writei, or pipe code. */ rdwr(mode) { register *fp, m; m = mode; fp = getf(u.u_ar0[R0]); if(fp == NULL) return; if((fp->f_flag&m) == 0) { u.u_error = EBADF; return; } u.u_base = u.u_arg[0]; u.u_count = u.u_arg[1]; u.u_segflg = 0; if(fp->f_flag&FPIPE) { if(m==FREAD) readp(fp); else writep(fp);

5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799

1 09:28 1988

unix/sys2.c Page 2

} else { u.u_offset[1] = fp->f_offset[1]; u.u_offset[0] = fp->f_offset[0]; if(m==FREAD) readi(fp->f_inode); else writei(fp->f_inode); dpadd(fp->f_offset, u.u_arg[1]-u.u_count); } u.u_ar0[R0] = u.u_arg[1]-u.u_count; } /* -------------------------

*/

/* * open system call */ open() { register *ip; extern uchar; ip = namei(&uchar, 0); if(ip == NULL) return; u.u_arg[1]++; open1(ip, u.u_arg[1], 0); } /* -------------------------

*/

/* * creat system call */ creat() { register *ip; extern uchar; ip = namei(&uchar, 1); if(ip == NULL) { if(u.u_error) return; ip = maknode(u.u_arg[1]&07777&(~ISVTX)); if (ip==NULL) return; open1(ip, FWRITE, 2); } open1(ip, FWRITE, 1); } /* -------------------------

*/

/*

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 57

Sheet 57

Sep

1 09:28 1988

unix/sys2.c Page 3

Sep

5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849

* common code for open and creat. * Check permissions, allocate an open file structure, * and call the device open routine if any. */ open1(ip, mode, trf) int *ip; { register struct file *fp; register *rip, m; int i; rip = ip; m = mode; if(trf != 2) { if(m&FREAD) access(rip, IREAD); if(m&FWRITE) { access(rip, IWRITE); if((rip->i_mode&IFMT) == IFDIR) u.u_error = EISDIR; } } if(u.u_error) goto out; if(trf) itrunc(rip); prele(rip); if ((fp = falloc()) == NULL) goto out; fp->f_flag = m&(FREAD|FWRITE); fp->f_inode = rip; i = u.u_ar0[R0]; openi(rip, m&FWRITE); if(u.u_error == 0) return; u.u_ofile[i] = NULL; fp->f_count--; out: iput(rip); } /* -------------------------

*/

/* * close system call */ close() { register *fp;

5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899

1 09:28 1988

unix/sys2.c Page 4

fp = getf(u.u_ar0[R0]); if(fp == NULL) return; u.u_ofile[u.u_ar0[R0]] = NULL; closef(fp); } /* -------------------------

*/

/* * seek system call */ seek() { int n[2]; register *fp, t; fp = getf(u.u_ar0[R0]); if(fp == NULL) return; if(fp->f_flag&FPIPE) { u.u_error = ESPIPE; return; } t = u.u_arg[1]; if(t > 2) { n[1] = u.u_arg[0]7; if(t == 3) n[0] =& 0777; } else { n[1] = u.u_arg[0]; n[0] = 0; if(t!=0 && n[1]f_offset[0]; dpadd(n, fp->f_offset[1]); break; default: n[0] =+ fp->f_inode->i_size0&0377; dpadd(n, fp->f_inode->i_size1); case 0: case 3: ;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 58

Sheet 58

Sep

5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949

1 09:28 1988

unix/sys2.c Page 5

} fp->f_offset[1] = n[1]; fp->f_offset[0] = n[0]; } /* -------------------------

*/

/* link system call */ link() { register *ip, *xp; extern uchar; ip = namei(&uchar, 0); if(ip == NULL) return; if(ip->i_nlink >= 127) { u.u_error = EMLINK; goto out; } if((ip->i_mode&IFMT)==IFDIR && !suser()) goto out; /* * ulock to avoid possible hanging in namei */ ip->i_flag =& ~ILOCK; u.u_dirp = u.u_arg[1]; xp = namei(&uchar, 1); if(xp != NULL) { u.u_error = EEXIST; iput(xp); } if(u.u_error) goto out; if(u.u_pdir->i_dev != ip->i_dev) { iput(u.u_pdir); u.u_error = EXDEV; goto out; } wdir(ip); ip->i_nlink++; ip->i_flag =| IUPD; out: iput(ip); } /* -------------------------

*/

/*

Sep

1 09:28 1988

unix/sys2.c Page 6

5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999

* mknod system call */ mknod() { register *ip; extern uchar; if(suser()) { ip = namei(&uchar, 1); if(ip != NULL) { u.u_error = EEXIST; goto out; } } if(u.u_error) return; ip = maknode(u.u_arg[1]); if (ip==NULL) return; ip->i_addr[0] = u.u_arg[2]; out: iput(ip); } /* -------------------------

*/

/* sleep system call * not to be confused with the sleep internal routine. */ sslep() { char *d[2]; spl7(); d[0] = time[0]; d[1] = time[1]; dpadd(d, u.u_ar0[R0]); while(dpcmp(d[0], d[1], time[0], time[1]) > 0) { if(dpcmp(tout[0], tout[1], time[0], time[1]) 0) { tout[0] = d[0]; tout[1] = d[1]; } sleep(tout, PSLEP); } spl0(); } /* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 59

Sheet 59

Sep

1 09:28 1988

6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049

# #include #include #include #include #include #include #include #include #include

unix/sys3.c Page 1

Sep

"../param.h" "../systm.h" "../reg.h" "../buf.h" "../filsys.h" "../user.h" "../inode.h" "../file.h" "../conf.h"

/* * the fstat system call. */ fstat() { register *fp; fp = getf(u.u_ar0[R0]); if(fp == NULL) return; stat1(fp->f_inode, u.u_arg[0]); } /* -------------------------

*/

/* * the stat system call. */ stat() { register ip; extern uchar; ip = namei(&uchar, 0); if(ip == NULL) return; stat1(ip, u.u_arg[1]); iput(ip); } /* -------------------------

*/

/* * The basic routine for fstat and stat: * get the inode and pass appropriate parts back. */ stat1(ip, ub) int ip; { register i, *bp, *cp;

6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099

1 09:28 1988

unix/sys3.c Page 2

iupdat(ip, time); bp = bread(ip->i_dev, ldiv(ip->i_number+31, 16)); cp = bp->b_addr + 32*lrem(ip->i_number+31, 16) +24; ip = &(ip->i_dev); for(i=0; ii_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0) goto out; smp = NULL; for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) { if(mp->m_bufp != NULL) { if(d == mp->m_dev) goto out; } else if(smp == NULL) smp = mp; } if(smp == NULL) goto out; (*bdevsw[d.d_major].d_open)(d, !u.u_arg[2]); if(u.u_error) goto out; mp = bread(d, 1); if(u.u_error) { brelse(mp); goto out1; } smp->m_inodp = ip; smp->m_dev = d; smp->m_bufp = getblk(NODEV); bcopy(mp->b_addr, smp->m_bufp->b_addr, 256); smp = smp->m_bufp->b_addr; smp->s_ilock = 0; smp->s_flock = 0; smp->s_ronly = u.u_arg[2] & 1; brelse(mp); ip->i_flag =| IMOUNT; prele(ip); return; out: u.u_error = EBUSY; out1: iput(ip); } /* -------------------------

*/

/* * the umount system call. */ sumount() { int d; register struct inode *ip; register struct mount *mp;

6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199

1 09:28 1988

unix/sys3.c Page 4

update(); d = getmdev(); if(u.u_error) return; for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) if(mp->m_bufp!=NULL && d==mp->m_dev) goto found; u.u_error = EINVAL; return; found: for(ip = &inode[0]; ip < &inode[NINODE]; ip++) if(ip->i_number!=0 && d==ip->i_dev) { u.u_error = EBUSY; return; } (*bdevsw[d.d_major].d_close)(d, 0); ip = mp->m_inodp; ip->i_flag =& ~IMOUNT; iput(ip); ip = mp->m_bufp; mp->m_bufp = NULL; brelse(ip); } /* ------------------------*/ /* * Common code for mount and umount. * Check that the user’s argument is a reasonable thing * on which to mount, and return the device number if so. */ getmdev() { register d, *ip; extern uchar; ip = namei(&uchar, 0); if(ip == NULL) return; if((ip->i_mode&IFMT) != IFBLK) u.u_error = ENOTBLK; d = ip->i_addr[0]; if(ip->i_addr[0].d_major >= nblkdev) u.u_error = ENXIO; iput(ip); return(d); } /* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 61

Sheet 61

Sep

1 09:28 1988

6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249

# /* */

unix/rdwri.c Page 1

Sep

6250 6251 6252 6253 #include "../param.h" 6254 #include "../inode.h" 6255 #include "../user.h" 6256 #include "../buf.h" 6257 #include "../conf.h" 6258 #include "../systm.h" 6259 6260 /* 6261 * Read the file corresponding to 6262 * the inode pointed at by the argument. 6263 * the actual read arguments are found 6264 * in the variables: 6265 * u_base core address for destination 6266 * u_offset byte offset in file 6267 * u_count number of bytes to read 6268 * u_segflg read to kernel/user 6269 */ 6270 readi(aip) 6271 struct inode *aip; 6272 { 6273 int *bp; 6274 int lbn, bn, on; 6275 register dn, n; 6276 register struct inode *ip; 6277 6278 ip = aip; 6279 if(u.u_count == 0) 6280 return; 6281 ip->i_flag =| IACC; 6282 if((ip->i_mode&IFMT) == IFCHR) { 6283 (*cdevsw[ip->i_addr[0].d_major].d_read)(ip->i_addr[0]); 6284 return; 6285 } 6286 6287 do { 6288 lbn = bn = lshift(u.u_offset, -9); 6289 on = u.u_offset[1] & 0777; 6290 n = min(512-on, u.u_count); 6291 if((ip->i_mode&IFMT) != IFBLK) { 6292 dn = dpcmp(ip->i_size0&0377, ip->i_size1, 6293 u.u_offset[0], u.u_offset[1]); 6294 if(dn i_dev; } else { dn = ip->i_addr[0]; rablock = bn+1; } if (ip->i_lastr+1 == lbn) bp = breada(dn, bn, rablock); else bp = bread(dn, bn); ip->i_lastr = lbn; iomove(bp, on, n, B_READ); brelse(bp); } while(u.u_error==0 && u.u_count!=0); } /* -------------------------

*/

/* * Write the file corresponding to * the inode pointed at by the argument. * the actual read arguments are found * in the variables: * u_base core address for source * u_offset byte offset in file * u_count number of bytes to write * u_segflg write to kernel/user */ writei(aip) struct inode *aip; { int *bp; int lbn, bn, on; register dn, n; register struct inode *ip; ip = aip; ip->i_flag =| IACC|IUPD; if((ip->i_mode&IFMT) == IFCHR) { (*cdevsw[ip->i_addr[0].d_major].d_write)(ip->i_addr[0]); return; } if (u.u_count == 0) return; do { bn = lshift(u.u_offset, -9); on = u.u_offset[1] & 0777; n = min(512-on, u.u_count); if((ip->i_mode&IFMT) != IFBLK) { if ((bn = bmap(ip, bn)) == 0) return;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 62

Sheet 62

Sep

6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349

1 09:28 1988

unix/rdwri.c Page 3

dn = ip->i_dev; } else dn = ip->i_addr[0]; if(n == 512) bp = getblk(dn, bn); else bp = bread(dn, bn); iomove(bp, on, n, B_WRITE); if(u.u_error != 0) brelse(bp); else if ((u.u_offset[1]&0777)==0) bawrite(bp); else bdwrite(bp); if(dpcmp(ip->i_size0&0377, ip->i_size1, u.u_offset[0], u.u_offset[1]) < 0 && (ip->i_mode&(IFBLK&IFCHR)) == 0) { ip->i_size0 = u.u_offset[0]; ip->i_size1 = u.u_offset[1]; } ip->i_flag =| IUPD; } while(u.u_error==0 && u.u_count!=0); } /* -------------------------

*/

/* Return the logical maximum * of the 2 arguments. */ max(a, b) char *a, *b; { if(a > b) return(a); return(b); } /* -------------------------

*/

/* Return the logical minimum * of the 2 arguments. */ min(a, b) char *a, *b; { if(a < b) return(a); return(b); } /* -------------------------

*/

Sep

1 09:28 1988

unix/rdwri.c Page 4

6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399

/* Move ’an’ bytes at byte location * &bp->b_addr[o] to/from (flag) the * user/kernel (u.segflg) area starting at u.base. * Update all the arguments by the number * of bytes moved. * * There are 2 algorithms, * if source address, dest address and count * are all even in a user copy, * then the machine language copyin/copyout * is called. * If not, its done byte-by-byte with * cpass and passc. */ iomove(bp, o, an, flag) struct buf *bp; { register char *cp; register int n, t; n = an; cp = bp->b_addr + o; if(u.u_segflg==0 && ((n | cp | u.u_base)&01)==0) { if (flag==B_WRITE) cp = copyin(u.u_base, cp, n); else cp = copyout(cp, u.u_base, n); if (cp) { u.u_error = EFAULT; return; } u.u_base =+ n; dpadd(u.u_offset, n); u.u_count =- n; return; } if (flag==B_WRITE) { while(n--) { if ((t = cpass()) < 0) return; *cp++ = t; } } else while (n--) if(passc(*cp++) < 0) return; } /* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 63

Sheet 63

Sep

1 09:28 1988

6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449

# #include #include #include #include #include #include

unix/subr.c Page 1

"../param.h" "../conf.h" "../inode.h" "../user.h" "../buf.h" "../systm.h"

/* Bmap defines the structure of file system storage * by returning the physical block number on a device given * the inode and the logical block number in a file. * When convenient, it also leaves the physical * block number of the next block of the file in rablock * for use in read-ahead. */ bmap(ip, bn) struct inode *ip; int bn; { register *bp, *bap, nb; int *nbp, d, i; d = ip->i_dev; if(bn & ~077777) { u.u_error = EFBIG; return(0); } if((ip->i_mode&ILARG) == 0) { /* small file algorithm */ if((bn & ~7) != 0) { /* convert small to large */ if ((bp = alloc(d)) == NULL) return(NULL); bap = bp->b_addr; for(i=0; ii_addr[i]; ip->i_addr[i] = 0; } ip->i_addr[0] = bp->b_blkno; bdwrite(bp); ip->i_mode =| ILARG; goto large; } nb = ip->i_addr[bn]; if(nb == 0 && (bp = alloc(d)) != NULL) { bdwrite(bp);

Sep

6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499

1 09:28 1988

unix/subr.c Page 2

nb = bp->b_blkno; ip->i_addr[bn] = nb; ip->i_flag =| IUPD; } rablock = 0; if (bni_addr[bn+1]; return(nb); } /* large file algorithm */ large: i = bn>>8; if(bn & 0174000) i = 7; if((nb=ip->i_addr[i]) == 0) { ip->i_flag =| IUPD; if ((bp = alloc(d)) == NULL) return(NULL); ip->i_addr[i] = bp->b_blkno; } else bp = bread(d, nb); bap = bp->b_addr; /* "huge" fetch of double indirect block */ if(i == 7) { i = ((bn>>8) & 0377) - 7; if((nb=bap[i]) == 0) { if((nbp = alloc(d)) == NULL) { brelse(bp); return(NULL); } bap[i] = nbp->b_blkno; bdwrite(bp); } else { brelse(bp); nbp = bread(d, nb); } bp = nbp; bap = bp->b_addr; } /* normal indirect fetch */ i = bn & 0377; if((nb=bap[i]) == 0 && (nbp = alloc(d)) != NULL) { nb = nbp->b_blkno; bap[i] = nb;

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 64

Sheet 64

Sep

6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549

1 09:28 1988

unix/subr.c Page 3

Sep

bdwrite(nbp); bdwrite(bp); } else brelse(bp); rablock = 0; if(i < 255) rablock = bap[i+1]; return(nb); } /* -------------------------

*/

/* Pass back c to the user at his location u_base; * update u_base, u_count, and u_offset. Return -1 * on the last character of the user’s read. * u_base is in the user address space unless u_segflg * is set. */ passc(c) char c; { if(u.u_segflg) *u.u_base =c; else if(subyte(u.u_base, c) < 0) { u.u_error = EFAULT; return(-1); } u.u_count--; if(++u.u_offset[1] == 0) u.u_offset[0]++; u.u_base++; return(u.u_count == 0? -1: 0); } /* -------------------------

*/

/* * Pick up and return the next character from the user’s * write call at location u_base; * update u_base, u_count, and u_offset. Return -1 * when u_count is exhausted. u_base is in the user’s * address space unless u_segflg is set. */ cpass() { register c; if(u.u_count == 0) return(-1); if(u.u_segflg) c = *u.u_base; else

6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599

1 09:28 1988

unix/subr.c Page 4

if((c=fubyte(u.u_base)) < 0) { u.u_error = EFAULT; return(-1); } u.u_count--; if(++u.u_offset[1] == 0) u.u_offset[0]++; u.u_base++; return(c&0377); } /* -------------------------

*/

/* * Routine which sets a user error; placed in * illegal entries in the bdevsw and cdevsw tables. */ nodev() { u.u_error = ENODEV; } /* -------------------------

*/

/* * Null routine; placed in insignificant entries * in the bdevsw and cdevsw tables. */ nulldev() { } /* ------------------------*/ /* * copy count words from from to to. */ bcopy(from, to, count) int *from, *to; { register *a, *b, c; a = from; b = to; c = count; do *b++ = *a++; while(--c); } /* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 65

Sheet 65

Sep

1 09:28 1988

6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649

# /* */ #include #include #include #include #include #include #include

unix/fio.c Page 1

Sep

"../param.h" "../user.h" "../filsys.h" "../file.h" "../conf.h" "../inode.h" "../reg.h"

/* * Convert a user supplied * file descriptor into a pointer * to a file structure. * Only task is to check range * of the descriptor. */ getf(f) { register *fp, rf; rf = f; if(rf=NOFILE) goto bad; fp = u.u_ofile[rf]; if(fp != NULL) return(fp); bad: u.u_error = EBADF; return(NULL); } /* -------------------------

*/

/* * Internal form of close. * Decrement reference count on * file structure and call closei * on last closef. * Also make sure the pipe protocol * does not constipate. */ closef(fp) int *fp; { register *rfp, *ip; rfp = fp; if(rfp->f_flag&FPIPE) {

6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699

1 09:28 1988

unix/fio.c Page 2

ip = rfp->f_inode; ip->i_mode =& ~(IREAD|IWRITE); wakeup(ip+1); wakeup(ip+2); } if(rfp->f_count f_inode, rfp->f_flag&FWRITE); rfp->f_count--; } /* -------------------------

*/

/* * Decrement reference count on an * inode due to the removal of a * referencing file structure. * On the last closei, switchout * to the close entry point of special * device handler. * Note that the handler gets called * on every open and only on the last * close. */ closei(ip, rw) int *ip; { register *rip; register dev, maj; rip = ip; dev = rip->i_addr[0]; maj = rip->i_addr[0].d_major; if(rip->i_count i_mode&IFMT) { case IFCHR: (*cdevsw[maj].d_close)(dev, rw); break; case IFBLK: (*bdevsw[maj].d_close)(dev, rw); } iput(rip); } /* ------------------------/* * * * *

*/

openi called to allow handler of special files to initialize and validate before actual IO. Called on all sorts of opens

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 66

Sheet 66

Sep

1 09:28 1988

unix/fio.c Page 3

6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749

* and also on mount. */ openi(ip, rw) int *ip; { register *rip; register dev, maj;

Sep

rip = ip; dev = rip->i_addr[0]; maj = rip->i_addr[0].d_major; switch(rip->i_mode&IFMT) { case IFCHR: if(maj >= nchrdev) goto bad; (*cdevsw[maj].d_open)(dev, rw); break; case IFBLK: if(maj >= nblkdev) goto bad; (*bdevsw[maj].d_open)(dev, rw); } return; bad: u.u_error = ENXIO; } /* -------------------------

*/

/* * Check mode permission on inode pointer. * Mode is READ, WRITE, or EXEC. * In the case of WRITE, the * read-only status of the file * system is checked. * Also in WRITE, prototype text * segments cannot be written. * The mode is shifted to select * the owner/group/other fields. * The super user is granted all * permissions except for EXEC where * at least one of the EXEC bits must * be on. */ access(aip, mode) int *aip; { register *ip, m;

6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799

1 09:28 1988

unix/fio.c Page 4

ip = aip; m = mode; if(m == IWRITE) { if(getfs(ip->i_dev)->s_ronly != 0) { u.u_error = EROFS; return(1); } if(ip->i_flag & ITEXT) { u.u_error = ETXTBSY; return(1); } } if(u.u_uid == 0) { if(m == IEXEC && (ip->i_mode & (IEXEC | (IEXEC>>3) | (IEXEC>>6))) == 0) goto bad; return(0); } if(u.u_uid != ip->i_uid) { m =>> 3; if(u.u_gid != ip->i_gid) m =>> 3; } if((ip->i_mode&m) != 0) return(0); bad: u.u_error = EACCES; return(1); } /* -------------------------

*/

/* * Look up a pathname and test if * the resultant inode is owned by the * current user. * If not, try for super-user. * If permission is granted, * return inode pointer. */ owner() { register struct inode *ip; extern uchar(); if ((ip = namei(uchar, 0)) == NULL) return(NULL); if(u.u_uid == ip->i_uid) return(ip);

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 67

Sheet 67

Sep

6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849

1 09:28 1988

unix/fio.c Page 5

Sep

if (suser()) return(ip); iput(ip); return(NULL); } /* -------------------------

*/

/* * Test if the current user is the * super user. */ suser() { if(u.u_uid == 0) return(1); u.u_error = EPERM; return(0); } /* -------------------------

*/

/* * Allocate a user file descriptor. */ ufalloc() { register i; for (i=0; if_count==0) { u.u_ofile[i] = fp; fp->f_count++; fp->f_offset[0] = 0; fp->f_offset[1] = 0; return(fp); } printf("no file\n"); u.u_error = ENFILE; return(NULL); -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 68

Sheet 68

Sep

1 09:28 1988

6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949

# /* */ #include #include #include #include #include #include #include

unix/alloc.c Page 1

"../param.h" "../systm.h" "../filsys.h" "../conf.h" "../buf.h" "../inode.h" "../user.h"

/* * iinit is called once (from main) * very early in initialization. * It reads the root’s super block * and initializes the current date * from the last modified date. * * panic: iinit -- cannot read the super * block. Usually because of an IO error. */ iinit() { register *cp, *bp; (*bdevsw[rootdev.d_major].d_open)(rootdev, 1); bp = bread(rootdev, 1); cp = getblk(NODEV); if(u.u_error) panic("iinit"); bcopy(bp->b_addr, cp->b_addr, 256); brelse(bp); mount[0].m_bufp = cp; mount[0].m_dev = rootdev; cp = cp->b_addr; cp->s_flock = 0; cp->s_ilock = 0; cp->s_ronly = 0; time[0] = cp->s_time[0]; time[1] = cp->s_time[1]; } /* ------------------------/* ------------------------/* * * * *

*/ */

alloc will obtain the next available free disk block from the free list of the specified device. The super block has up to 100 remembered

Sep

1 09:28 1988

unix/alloc.c Page 2

6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999

* free blocks; the last of these is read to * obtain 100 more . . . * * no space on dev x/y -- when * the free list is exhausted. */ alloc(dev) { int bno; register *bp, *ip, *fp; fp = getfs(dev); while(fp->s_flock) sleep(&fp->s_flock, PINOD); do { if(fp->s_nfree s_free[--fp->s_nfree]; if(bno == 0) goto nospace; } while (badblock(fp, bno, dev)); if(fp->s_nfree s_flock++; bp = bread(dev, bno); ip = bp->b_addr; fp->s_nfree = *ip++; bcopy(ip, fp->s_free, 100); brelse(bp); fp->s_flock = 0; wakeup(&fp->s_flock); } bp = getblk(dev, bno); clrbuf(bp); fp->s_fmod = 1; return(bp); nospace: fp->s_nfree = 0; prdev("no space", dev); u.u_error = ENOSPC; return(NULL); } /*------------------------/*-------------------------

*/ */

/* * place the specified disk block * back on the free list of the * specified device. */

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 69

Sheet 69

Sep

1 09:28 1988

unix/alloc.c Page 3

7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049

free(dev, bno) { register *fp, *bp, *ip;

Sep

fp = getfs(dev); fp->s_fmod = 1; while(fp->s_flock) sleep(&fp->s_flock, PINOD); if (badblock(fp, bno, dev)) return; if(fp->s_nfree s_nfree = 1; fp->s_free[0] = 0; } if(fp->s_nfree >= 100) { fp->s_flock++; bp = getblk(dev, bno); ip = bp->b_addr; *ip++ = fp->s_nfree; bcopy(fp->s_free, ip, 100); fp->s_nfree = 0; bwrite(bp); fp->s_flock = 0; wakeup(&fp->s_flock); } fp->s_free[fp->s_nfree++] = bno; fp->s_fmod = 1; } /* ------------------------/* -------------------------

*/ */

/* * Check that a block number is in the * range between the I list and the size * of the device. * This is used mainly to check that a * garbage file system has not been mounted. * * bad block on dev x/y -- not in range */ badblock(afp, abn, dev) { register struct filsys *fp; register char *bn; fp = afp; bn = abn; if (bn < fp->s_isize+2 || bn >= fp->s_fsize) { prdev("bad block", dev); return(1);

7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099

1 09:28 1988

unix/alloc.c Page 4

} return(0); } /* ------------------------/* -------------------------

*/ */

/* * Allocate an unused I node * on the specified device. * Used with file creation. * The algorithm keeps up to * 100 spare I node in the * super block. When this runs out, * a linear search through the * I list is instituted to pick * up 100 more. */ ialloc(dev) { register *fp, *bp, *ip; int i, j, k, ino; fp = getfs(dev); while(fp->s_ilock) sleep(&fp->s_ilock, PINOD); loop: if(fp->s_ninode > 0) { ino = fp->s_inode[--fp->s_ninode]; ip = iget(dev, ino); if (ip==NULL) return(NULL); if(ip->i_mode == 0) { for(bp = &ip->i_mode; bp < &ip->i_addr[8];) *bp++ = 0; fp->s_fmod = 1; return(ip); } /* * Inode was allocated after all. * Look some more. */ iput(ip); goto loop; } fp->s_ilock++; ino = 0; for(i=0; is_isize; i++) { bp = bread(dev, i+2); ip = bp->b_addr; for(j=0; js_ninode++] = ino; if(fp->s_ninode >= 100) break; cont:; } brelse(bp); if(fp->s_ninode >= 100) break; } fp->s_ilock = 0; wakeup(&fp->s_ilock); if (fp->s_ninode > 0) goto loop; prdev("Out of inodes", dev); u.u_error = ENOSPC; return(NULL); } /* ------------------------/* -------------------------

*/ */

/* * Free the specified I node * on the specified device. * The algorithm stores up * to 100 I nodes in the super * block and throws away any more. */ ifree(dev, ino) { register *fp; fp = getfs(dev); if(fp->s_ilock) return; if(fp->s_ninode >= 100) return; fp->s_inode[fp->s_ninode++] = ino; fp->s_fmod = 1; } /* ------------------------/* -------------------------

*/ */

/*

Sep

1 09:28 1988

unix/alloc.c Page 6

7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199

* getfs maps a device number into * a pointer to the incore super * block. * The algorithm is a linear * search through the mount table. * A consistency check of the * in core free-block and i-node * counts. * * bad count on dev x/y -- the count * check failed. At this point, all * the counts are zeroed which will * almost certainly lead to "no space" * diagnostic * panic: no fs -- the device is not mounted. * this "cannot happen" */ getfs(dev) { register struct mount *p; register char *n1, *n2; for(p = &mount[0]; p < &mount[NMOUNT]; p++) if(p->m_bufp != NULL && p->m_dev == dev) { p = p->m_bufp->b_addr; n1 = p->s_nfree; n2 = p->s_ninode; if(n1 > 100 || n2 > 100) { prdev("bad count", dev); p->s_nfree = 0; p->s_ninode = 0; } return(p); } panic("no fs"); } /* ------------------------/* -------------------------

*/ */

/* * update is the internal name of * ’sync’. It goes through the disk * queues to initiate sandbagged IO; * goes through the I nodes to write * modified nodes; and it goes through * the mount table to initiate modified * super blocks. */

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 71

Sheet 71

Sep

7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249

1 09:28 1988

unix/alloc.c Page 7

update() { register struct inode *ip; register struct mount *mp; register *bp; if(updlock) return; updlock++; for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) if(mp->m_bufp != NULL) { ip = mp->m_bufp->b_addr; if(ip->s_fmod==0 || ip->s_ilock!=0 || ip->s_flock!=0 || ip->s_ronly!=0) continue; bp = getblk(mp->m_dev, 1); ip->s_fmod = 0; ip->s_time[0] = time[0]; ip->s_time[1] = time[1]; bcopy(ip, bp->b_addr, 256); bwrite(bp); } for(ip = &inode[0]; ip < &inode[NINODE]; ip++) if((ip->i_flag&ILOCK) == 0) { ip->i_flag =| ILOCK; iupdat(ip, time); prele(ip); } updlock = 0; bflush(NODEV); } /* ------------------------/* -------------------------

*/ */

Sep

1 09:28 1988

7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299

# #include #include #include #include #include #include #include

unix/iget.c Page 1

"../param.h" "../systm.h" "../user.h" "../inode.h" "../filsys.h" "../conf.h" "../buf.h"

/* * Look up an inode by device,inumber. * If it is in core (in the inode structure), * honor the locking protocol. * If it is not in core, read it in from the * specified device. * If the inode is mounted on, perform * the indicated indirection. * In all cases, a pointer to a locked * inode structure is returned. * * printf warning: no inodes -- if the inode * structure is full * panic: no imt -- if the mounted file * system is not in the mount table. * "cannot happen" */ iget(dev, ino) { register struct inode *p; register *ip2; int *ip1; register struct mount *ip; loop: ip = NULL; for(p = &inode[0]; p< &inode[NINODE]; p++) { if(dev==p->i_dev && ino==p->i_number) { if((p->i_flag&ILOCK) != 0) { p->i_flag =| IWANT; sleep(p, PINOD); goto loop; } if((p->i_flag&IMOUNT) != 0) { for (ip = &mount[0]; ip < &mount[NMOUNT]; ip++) if (ip->m_inodp == p) { dev = ip->m_dev; ino = ROOTINO; goto loop; }

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 72

Sheet 72

Sep

7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349

1 09:28 1988

unix/iget.c Page 2

Sep

panic("no imt"); } p->i_count++; p->i_flag =| ILOCK; return(p); } if(ip==NULL && p->i_count==0) ip = p; } if((p=ip) == NULL) { printf("Inode table overflow\n"); u.u_error = ENFILE; return(NULL); } p->i_dev = dev; p->i_number = ino; p->i_flag = ILOCK; p->i_count++; p->i_lastr = -1; ip = bread(dev, ldiv(ino+31,16)); /* * Check I/O errors */ if (ip->b_flags&B_ERROR) { brelse(ip); iput(p); return(NULL); } ip1 = ip->b_addr + 32*lrem(ino+31, 16); ip2 = &p->i_mode; while(ip2 < &p->i_addr[8]) *ip2++ = *ip1++; brelse(ip); return(p); } /* -------------------------

*/

/* * Decrement reference count of * an inode structure. * On the last reference, * write the inode out and if necessary, * truncate and deallocate the file. */ iput(p) struct inode *p; { register *rp; rp = p;

7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399

1 09:28 1988

unix/iget.c Page 3

if(rp->i_count == 1) { rp->i_flag =| ILOCK; if(rp->i_nlink i_mode = 0; ifree(rp->i_dev, rp->i_number); } iupdat(rp, time); prele(rp); rp->i_flag = 0; rp->i_number = 0; } rp->i_count--; prele(rp); } /* -------------------------

*/

/* * Check accessed and update flags on * an inode structure. * If either is on, update the inode * with the corresponding dates * set to the argument tm. */ iupdat(p, tm) int *p; int *tm; { register *ip1, *ip2, *rp; int *bp, i; rp = p; if((rp->i_flag&(IUPD|IACC)) != 0) { if(getfs(rp->i_dev)->s_ronly) return; i = rp->i_number+31; bp = bread(rp->i_dev, ldiv(i,16)); ip1 = bp->b_addr + 32*lrem(i, 16); ip2 = &rp->i_mode; while(ip2 < &rp->i_addr[8]) *ip1++ = *ip2++; if(rp->i_flag&IACC) { *ip1++ = time[0]; *ip1++ = time[1]; } else ip1 =+ 2; if(rp->i_flag&IUPD) { *ip1++ = *tm++; *ip1++ = *tm; }

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 73

Sheet 73

Sep

7400 7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449

1 09:28 1988

unix/iget.c Page 4

bwrite(bp); } } /* -------------------------

*/

/* * Free all the disk blocks associated * with the specified inode structure. * The blocks of the file are removed * in reverse order. This FILO * algorithm will tend to maintain * a contiguous free list much longer * than FIFO. */ itrunc(ip) int *ip; { register *rp, *bp, *cp; int *dp, *ep; rp = ip; if((rp->i_mode&(IFCHR&IFBLK)) != 0) return; for(ip = &rp->i_addr[7]; ip >= &rp->i_addr[0]; ip--) if(*ip) { if((rp->i_mode&ILARG) != 0) { bp = bread(rp->i_dev, *ip); for(cp = bp->b_addr+512; cp >= bp->b_addr; cp--) if(*cp) { if(ip == &rp->i_addr[7]) { dp = bread(rp->i_dev, *cp); for(ep = dp->b_addr+512; ep >= dp->b_addr; ep--) if(*ep) free(rp->i_dev, *ep); brelse(dp); } free(rp->i_dev, *cp); } brelse(bp); } free(rp->i_dev, *ip); *ip = 0; } rp->i_mode =& ~ILARG; rp->i_size0 = 0; rp->i_size1 = 0; rp->i_flag =| IUPD; }

Sep

1 09:28 1988

unix/iget.c Page 5

7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499

/* -------------------------

*/

/* * Make a new file. */ maknode(mode) { register *ip; ip = ialloc(u.u_pdir->i_dev); if (ip==NULL) return(NULL); ip->i_flag =| IACC|IUPD; ip->i_mode = mode|IALLOC; ip->i_nlink = 1; ip->i_uid = u.u_uid; ip->i_gid = u.u_gid; wdir(ip); returm(ip); } /* -------------------------

*/

/* * Write a directory entry with * parameters left as side effects * to a call to namei. */ wdir(ip) int *ip; { register char *cp1, *cp2; u.u_dent.u_ino = ip->i_number; cp1 = &u.u_dent.u_name[0]; for(cp2 = &u.u_dbuf[0]; cp2 < &u.u_dbuf[DIRSIZ];) *cp1++ = *cp2++; u.u_count = DIRSIZ+2; u.u_segflg = 1; u.u_base = &u.u_dent; writei(u.u_pdir); iput(u.u_pdir); } /* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 74

Sheet 74

Sep

1 09:28 1988

7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549

# #include #include #include #include #include

unix/nami.c Page 1

"../param.h" "../inode.h" "../user.h" "../systm.h" "../buf.h"

/* * Convert a pathname into a pointer to * an inode. Note that the inode is locked. * * func = function called to get next char of name * &uchar if name is in user space * &schar if name is in system space * flag = 0 if name is sought * 1 if name is to be created * 2 if name is to be deleted */ namei(func, flag) int (*func)(); { register struct inode *dp; register c; register char *cp; int eo, *bp; /* * If name starts with ’/’ start from * root: otherwise start from current dir. */ dp = u.u_cdir; if((c=(*func)()) == ’/’); dp = rootdir; iget(dp->i_dev, dp->i_number); while(c == ’/’) c = (*func)(); if(c == ’\0’ && flag != 0) { u.u_error = ENOENT; goto out; } cloop: /* * Here dp contains pointer * to last component matched. */ if(u.u_error) goto out;

Sep

1 09:28 1988

unix/nami.c Page 2

7550 if(c == ’\0’) 7551 return(dp); 7552 7553 /* 7554 * If there is another component, 7555 * dp must be a directory and 7556 * must have x permission. 7557 */ 7558 7559 if((dp->i_mode&IFMT) != IFDIR) { 7560 u.u_error = ENOTDIR; 7561 goto out; 7562 } 7563 if(access(dp, IEXEC)) 7564 goto out; 7565 7566 /* Gather up name into 7567 * users’ dir buffer. 7568 */ 7569 7570 cp = &u.u_dbuf[0]; 7571 while(c!=’/’ && c!=’\0’ && u.u_error==0) { 7572 if(cp < &u.u_dbuf[DIRSIZ]) 7573 *cp++ = c; 7574 c = (*func)(); 7575 } 7576 while(cp < &u.u_dbuf[DIRSIZ]) 7577 *cp++ = ’\0’; 7578 while(c == ’/’) 7579 c = (*func)(); 7580 if(u.u_error) 7581 goto out; 7582 7583 /* Set up to search a directory. */ 7584 7585 u.u_offset[1] = 0; 7586 u.u_offset[0] = 0; 7587 u.u_segflg = 1; 7588 eo = 0; 7589 u.u_count = ldiv(dp->i_size1, DIRSIZ+2); 7590 bp = NULL; 7591 7592 eloop: 7593 7594 /* 7595 * If at the end of the directory, 7596 * the search failed. Report what 7597 * is appropriate as per flag. 7598 */ 7599

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 75

Sheet 75

Sep

7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649

1 09:28 1988

unix/nami.c Page 3

Sep

if(u.u_count == 0) { 7650 if(bp != NULL) 7651 brelse(bp); 7652 if(flag==1 && c==’\0’) { 7653 if(access(dp, IWRITE)) 7654 goto out; 7655 u.u_pdir = dp; 7656 if(eo) 7657 u.u_offset[1] = eo-DIRSIZ-2; else 7658 dp->i_flag =| IUPD; 7659 return(NULL); 7660 } 7661 u.u_error = ENOENT; 7662 goto out; 7663 } 7664 7665 /* 7666 * If offset is on a block boundary, 7667 * read the next directory block. 7668 * Release previous if it exists. 7669 */ 7670 7671 if((u.u_offset[1]&0777) == 0) { 7672 if(bp != NULL) 7673 brelse(bp); 7674 bp = bread(dp->i_dev, 7675 bmap(dp, ldiv(u.u_offset[1], 512))); 7676 } 7677 7678 /* Note first empty directory slot 7679 * in eo for possible creat. 7680 * String compare the directory entry 7681 * and the current component. 7682 * If they do not match, go back to eloop. 7683 */ 7684 7685 bcopy(bp->b_addr+(u.u_offset[1]&0777), &u.u_dent, 7686 (DIRSIZ+2)/2); 7687 u.u_offset[1] =+ DIRSIZ+2; 7688 u.u_count--; 7689 if(u.u_dent.u_ino == 0) { 7690 if(eo == 0) 7691 eo = u.u_offset[1]; 7692 goto eloop; 7693 } 7694 for(cp = &u.u_dbuf[0]; cp < &u.u_dbuf[DIRSIZ]; cp++) 7695 if(*cp != cp[u.u_dent.u_name - u.u_dbuf]) 7696 goto eloop; 7697 7698 7699

1 09:28 1988

unix/nami.c Page 4

/* Here a component matched is a directory. * If there is more pathname, go back to * cloop, otherwise return. */ if(bp != NULL) brelse(bp); if(flag==2 && c==’\0’) { if(access(dp, IWRITE)) goto out; return(dp); } bp = dp->i_dev; iput(dp); dp = iget(bp, u.u_dent.u_ino); if(dp == NULL) return(NULL); goto cloop; out: iput(dp); return(NULL); } /* -------------------------

*/

/* * Return the next character from the * kernel string pointed at by dirp. */ schar() { return(*u.u_dirp++ & 0377); } /* -------------------------

*/

/* Return the next character from the * user string pointed at by dirp. */ uchar() { register c; c = fubyte(u.u_dirp++); if(c == -1) u.u_error = EFAULT; return(c); } /* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 76

Sheet 76

Sep

1 09:28 1988

7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749

#include #include #include #include #include #include

unix/pipe.c Page 1

"../param.h" "../systm.h" "../user.h" "../inode.h" "../file.h" "../reg.h"

/* Max allowable buffering per pipe. * This is also the max size of the * file created to implement the pipe. * If this size is bigger than 4096, * pipes will be implemented in LARGe * files, which is probably not good. */ #define

PIPSIZ

4096

/* The sys-pipe entry. * Allocate an inode on the root device. * Allocate 2 file structures. * Put it all together with flags. */ pipe() { register *ip, *rf, *wf; int r; ip = ialloc(rootdev); if(ip == NULL) return; rf = falloc(); if(rf == NULL) { iput(ip); return; } r = u.u_ar0[R0]; wf = falloc(); if(wf == NULL) { rf->f_count = 0; u.u_ofile[r] = NULL; iput(ip); return; } u.u_ar0[R1] = u.u_ar0[R0]; u.u_ar0[R0] = r; wf->f_flag = FWRITE|FPIPE; wf->f_inode = ip; rf->f_flag = FREAD|FPIPE; rf->f_inode = ip;

Sep

7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799

1 09:28 1988

unix/pipe.c Page 2

ip->i_count = 2; ip->i_flag = IACC|IUPD; ip->i_mode = IALLOC; } /* -------------------------

*/

/* Read call directed to a pipe. */ readp(fp) int *fp; { register *rp, *ip; rp = fp; ip = rp->f_inode; loop: /* Very conservative locking. */ plock(ip); /* If the head (read) has caught up with * the tail (write), reset both to 0. */ if(rp->f_offset[1] == ip->i_size1) { if(rp->f_offset[1] != 0) { rp->f_offset[1] = 0; ip->i_size1 = 0; if(ip->i_mode&IWRITE) { ip->i_mode =& ~IWRITE; wakeup(ip+1); } } /* If there are not both reader and * writer active, return without * satisfying read. */ prele(ip); if(ip->i_count < 2) return; ip->i_mode =| IREAD; sleep(ip+2, PPIPE); goto loop; } /* Read and return */ u.u_offset[0] = 0; u.u_offset[1] = rp->f_offset[1]; readi(ip); rp->f_offset[1] = u.u_offset[1]; prele(ip);

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 77

Sheet 77

Sep

1 09:28 1988

unix/pipe.c Page 3

7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849

} /* -------------------------

Sep

*/

/* Write call directed to a pipe. */ writep(fp) { register *rp, *ip, c; rp = fp; ip = rp->f_inode; c = u.u_count; loop: /* If all done, return. */ plock(ip); if(c == 0) { prele(ip); u.u_count = 0; return; } /* If there are not both read and * write sides of the pipe active, * return error and signal too. */ if(ip->i_count < 2) { prele(ip); u.u_error = EPIPE; psignal(u.u_procp, SIGPIPE); return; } /* If the pipe is full, * wait for reads to delete * and truncate it. */ if(ip->i_size1 == PIPSIZ) { ip->i_mode =| IWRITE; prele(ip); sleep(ip+1, PPIPE); goto loop; } /* Write what is possible and * loop back. */ u.u_offset[0] = 0; u.u_offset[1] = ip->i_size1; u.u_count = min(c, PIPSIZ-u.u_offset[1]); c =- u.u_count; writei(ip); prele(ip);

7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899

1 09:28 1988

unix/pipe.c Page 4

if(ip->i_mode&IREAD) { ip->i_mode =& ~IREAD; wakeup(ip+2); } goto loop; } /* -------------------------

*/

/* Lock a pipe. * If its already locked, * set the WANT bit and sleep. */ plock(ip) int *ip; { register *rp; rp = ip; while(rp->i_flag&ILOCK) { rp->i_flag =| IWANT; sleep(rp, PPIPE); } rp->i_flag =| ILOCK; } /* -------------------------

*/

/* Unlock a pipe. * If WANT bit is on, * wakeup. * This routine is also used * to ulock inodes in general. */ prele(ip) int *ip; { register *rp; rp = ip; rp->i_flag =& ~ILOCK; if(rp->i_flag&IWANT) { rp->i_flag =& ~IWANT; wakeup(rp); } } /* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 78

Sheet 78

5 Character Oriented Special Files

Sep

1 09:28 1988

unix/tty.h Page 1

7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949

/* * A clist structure is the head * of a linked list queue of characters. * The characters are stored in 4-word * blocks containing a link and 6 characters. * The routines getc and putc (m45.s or m40.s) * manipulate these structures. */ struct clist { int c_cc; /* character count */ int c_cf; /* pointer to first block */ int c_cl; /* pointer to last block */ }; /* ------------------------*/

Sep

7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 /* 7966 * A tty structure is needed for 7967 * each UNIX character device that 7968 * is used for normal terminal IO. 7969 * The routines in tty.c handle the 7970 * common code associated with 7971 * these structures. 7972 * The definition and device dependent 7973 * code is in each driver (kl.c dc.c dh.c) 7974 */ 7975 struct tty 7976 { 7977 struct clist t_rawq; /* input chars right off device */ 7978 struct clist t_canq; /* input chars after erase and kill */ 7979 struct clist t_outq; /* output list to device */ 7980 int t_flags; /* mode, settable by stty call */ 7981 int *t_addr; /* device address (register or 7982 startup fcn) */ 7983 char t_delct; /* number of delimiters in raw q */ 7984 char t_col; /* printing column of device */ 7985 char t_erase; /* erase character */ 7986 char t_kill; /* kill character */ 7987 char t_state; /* internal state, not visible 7988 externally */ 7989 char t_char; /* character temporary */ 7990 int t_speeds; /* output+input line speed */ 7991 int t_dev; /* device name */ 7992 }; 7993 /* ------------------------*/ 7994 7995 7996 char partab[]; /* ASCII table: parity, character class */ 7997 7998 7999

1 09:28 1988

unix/tty.h Page 2

#define #define

TTIPRI TTOPRI

10 20

#define #define #define #define #define

CERASE CEOT CKILL CQUIT CINTR

’#’ /* default special characters */ 004 ’@’ 034 /* FS, cntl shift L */ 0177 /* DEL */

/* limits */ #define TTHIWAT 50 #define TTLOWAT 30 #define TTYHOG 256 /* modes */ #define HUPCL #define XTABS #define LCASE #define ECHO #define CRMOD #define RAW #define ODDP #define EVENP #define NLDELAY #define TBDELAY #define CRDELAY #define VTDELAY

01 02 04 010 020 040 0100 0200 001400 006000 030000 040000

/* Hardware bits */ #define DONE 0200 #define IENABLE 0100 /* Internal state bits */ #define TIMEOUT 01 #define WOPEN 02 #define #define

ISOPEN SSTART

04 010

#define

CARR_ON 020

#define #define

BUSY ASLEEP

040 0100

/* Delay timeout in progress */ /* Waiting for open to complete */ /* Device is open */ /* Has special start routine at addr */ /* Software copy of carrier-present */ /* Output in progress */ /* Wakeup when output done */

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 79

Sheet 79

Sep

1 09:28 1988

unix/kl.c Page 1

8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049

# /* KL/DL-11 driver */ #include "../param.h" #include "../conf.h" #include "../user.h" #include "../tty.h" #include "../proc.h" /* base address */ #define KLADDR 0177560 /* console */ #define KLBASE 0176500 /* kl and dl11-a */ #define DLBASE 0175610 /* dl-e */ #define NKL11 1 #define NDL11 0 #define DSRDY 02 #define RDRENB 01 struct tty kl11[NKL11+NDL11]; struct klregs { int klrcsr; int klrbuf; int kltcsr; int kltbuf; } /* ------------------------*/ klopen(dev, flag) { register char * addr; register struct tty *tp; if(dev.d_minor >= NKL11+NDL11) { u.u_error = ENXIO; return; } tp = &kl11[dev.d_minor]; if (u.u_procp->p_ttyp == 0) { u.u_procp->p_ttyp = tp; tp->t_dev = dev; } /* set up minor 0 to address KLADDR * set up minor 1 thru NKL11-1 to address from KLBASE * set up minor NKL11 on to address from DLBASE */ addr = KLADDR + 8*dev.d_minor; if(dev.d_minor) addr =+ KLBASE-KLADDR-8; if(dev.d_minor >= NKL11) addr =+ DLBASE-KLBASE-8*NKL11+8; tp->t_addr = addr; if ((tp->t_state&ISOPEN) == 0) { tp->t_state = ISOPEN|CARR_ON; tp->t_flags = XTABS|LCASE|ECHO|CRMOD; tp->t_erase = CERASE; tp->t_kill = CKILL;

Sep

8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099

1 09:28 1988

unix/kl.c Page 2

} addr->klrcsr =| IENABLE|DSRDY|RDRENB; addr->kltcsr =| IENABLE; } /* ------------------------*/ klclose(dev) { register struct tty *tp; tp = &kl11[dev.d_minor]; wflushtty(tp); tp->t_state = 0; } /* ------------------------*/ klread(dev) { ttread(&kl11[dev.d_minor]); } /* ------------------------*/ klwrite(dev) { ttwrite(&kl11[dev.d_minor]); } /* ------------------------*/ klxint(dev) { register struct tty *tp; tp = &kl11[dev.d_minor]; ttstart(tp); if (tp->t_outq.c_cc == 0 || tp->t_outq.c_cc == TTLOWAT) wakeup(&tp->t_outq); } /* ------------------------*/ klrint(dev) { register int c, *addr; register struct tty *tp; tp = &kl11[dev.d_minor]; addr = tp->t_addr; c = addr->klrbuf; addr->klrcsr =| RDRENB; if ((c&0177)==0) addr->kltbuf = c; /* hardware botch */ ttyinput(c, tp); } /* ------------------------*/ klsgtty(dev, v) int *v; { register struct tty *tp; tp = &kl11[dev.d_minor]; ttystty(tp, v); } /* ------------------------*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 80

Sheet 80

Sep

1 09:28 1988

8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149

#

unix/tty.c Page 1

/* general TTY subroutines */

#include #include #include #include #include #include #include #include #include

"../param.h" "../systm.h" "../user.h" "../tty.h" "../proc.h" "../inode.h" "../file.h" "../reg.h" "../conf.h"

/* Input mapping table-- if an entry is non-zero, when the * corresponding character is typed preceded by "\" the * escape sequence is replaced by the table value. * Mostly used for upper-case only terminals. */ char maptab[] { 000,000,000,000,004,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,’|’,000,’#’,000,000,000,’‘’, ’{’,’}’,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, ’@’,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,’~’,000, 000,’A’,’B’,’C’,’D’,’E’,’F’,’G’, ’H’,’I’,’J’,’K’,’L’,’M’,’N’,’O’, ’P’,’Q’,’R’,’S’,’T’,’U’,’V’,’W’, ’X’,’Y’,’Z’,000,000,000,000,000, }; /* ------------------------*/ /* The actual structure of a clist block manipulated by * getc and putc (mch.s) */ struct cblock { struct cblock *c_next; char info[6]; }; /* ------------------------*/ /* The character lists-- space for 6*NCLIST characters */ struct cblock cfree[NCLIST]; /* List head for unused character blocks. */ struct cblock *cfreelist;

Sep

1 09:28 1988

unix/tty.c Page 2

8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199

/* structure of device registers for KL, DL, and DC * interfaces-- more particularly, those for which the * SSTART bit is off and can be treated by general routines * (that is, not DH). */ struct { int ttrcsr; int ttrbuf; int tttcsr; int tttbuf; }; /* ------------------------*/ /* The routine implementing the gtty system call. * Just call lower level routine and pass back values. */ gtty() { int v[3]; register *up, *vp; vp = v; sgtty(vp); if (u.u_error) return; up = u.u_arg[0]; suword(up, *vp++); suword(++up, *vp++); suword(++up, *vp++); } /* ------------------------*/ /* The routine implementing the stty system call. * Read in values and call lower level. */ stty() { register int *up; up = u.u_arg[0]; u.u_arg[0] = fuword(up); u.u_arg[1] = fuword(++up); u.u_arg[2] = fuword(++up); sgtty(0); } /* /* * * * * *

------------------------*/ Stuff common to stty and gtty. Check legality and switch out to individual device routine. v is 0 for stty; the parameters are taken from u.u_arg[]. c is non-zero for gtty and is the place in which the device routines place their information.

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 81

Sheet 81

Sep

1 09:28 1988

unix/tty.c Page 3

Sep

8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239 8240 8241 8242 8243 8244 8245 8246 8247 8248 8249

*/ 8250 sgtty(v) 8251 int *v; 8252 { 8253 register struct file *fp; 8254 register struct inode *ip; 8255 if ((fp = getf(u.u_ar0[R0])) == NULL) 8256 return; 8257 ip = fp->f_inode; 8258 if ((ip->i_mode&IFMT) != IFCHR) { 8259 u.u_error = ENOTTY; 8260 return; 8261 } 8262 (*cdevsw[ip->i_addr[0].d_major].d_sgtty)(ip->i_addr[0],v);8263 } 8264 /* ------------------------*/ 8265 /* Wait for output to drain, then flush output waiting. */ 8266 wflushtty(atp) 8267 struct tty *atp; 8268 { 8269 register struct tty *tp; 8270 tp = atp; 8271 spl5(); 8272 while (tp->t_outq.c_cc) { 8273 tp->t_state =| ASLEEP; 8274 sleep(&tp->t_outq, TTOPRI); 8275 } 8276 flushtty(tp); 8277 spl0(); 8278 } 8279 /* ------------------------*/ 8280 /* Initialize clist by freeing all character blocks, & count 8281 * number of character devices. (Once-only routine) 8282 */ 8283 cinit() 8284 { 8285 register int ccp; 8286 register struct cblock *cp; 8287 register struct cdevsw *cdp; 8288 ccp = cfree; 8289 for (cp=(ccp+07)&~07; cp c_next = cfreelist; 8291 cfreelist = cp; 8292 } 8293 ccp = 0; 8294 for(cdp = cdevsw; cdp->d_open; cdp++) 8295 ccp++; 8296 nchrdev = ccp; 8297 } 8298 /* ------------------------*/ 8299

1 09:28 1988

unix/tty.c Page 4

/* flush all TTY queues */ flushtty(atp) struct tty *atp; { register struct tty *tp; register int sps; tp = atp; while (getc(&tp->t_canq) >= 0); while (getc(&tp->t_outq) >= 0); wakeup(&tp->t_rawq); wakeup(&tp->t_outq); sps = PS->integ; spl5(); while (getc(&tp->t_rawq) >= 0); tp->t_delct = 0; PS->integ = sps; } /* ------------------------*/ /* transfer raw input list to canonical list, * doing erase-kill processing and handling escapes. * It waits until a full line has been typed in cooked mode, * or until any character has been typed in raw mode. */ canon(atp) struct tty *atp; { register char *bp; char *bp1; register struct tty *tp; register int c; tp = atp; spl5(); while (tp->t_delct==0) { if ((tp->t_state&CARR_ON)==0) return(0); sleep(&tp->t_rawq, TTIPRI); } spl0(); loop: bp = &canonb[2]; while ((c=getc(&tp->t_rawq)) >= 0) { if (c==0377) { tp->t_delct--; break; } if ((tp->t_flags&RAW)==0) { if (bp[-1]!=’\\’) { if (c==tp->t_erase) {

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 82

Sheet 82

Sep

8300 8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349

1 09:28 1988

unix/tty.c Page 5

Sep

if (bp > &canonb[2]) bp--; continue;

8350 8351 8352 } 8353 if (c==tp->t_kill) 8354 goto loop; 8355 if (c==CEOT) 8356 continue; 8357 } else 8358 if (maptab[c] && (maptab[c]==c || (tp->t_flags&LCASE))) { 8359 if (bp[-2] != ’\\’) 8360 c = maptab[c]; 8361 bp--; 8362 } 8363 } 8364 *bp++ = c; 8365 if (bp>=canonb+CANBSIZ) 8366 break; 8367 } 8368 bp1 = bp; 8369 bp = &canonb[2]; 8370 c = &tp->t_canq; 8371 while (bpt_flags; 8391 if ((c =& 0177) == ’\r’ && t_flags&CRMOD) 8392 c = ’\n’; 8393 if ((t_flags&RAW)==0 && (c==CQUIT || c==CINTR)) { 8394 signal(tp, c==CINTR? SIGINT:SIGQIT); 8395 flushtty(tp); 8396 return; 8397 } 8398 if (tp->t_rawq.c_cc>=TTYHOG) { 8399

1 09:28 1988

unix/tty.c Page 6

flushtty(tp); return; } if (t_flags&LCASE && c>=’A’ && ct_rawq); if (t_flags&RAW || c==’\n’ || c==004) { wakeup(&tp->t_rawq); if (putc(0377, &tp->t_rawq)==0) tp->t_delct++; } if (t_flags&ECHO) { ttyoutput(c, tp); ttstart(tp); } } /* ------------------------*/ /* put character on TTY output queue, adding delays, * expanding tabs, and handling the CR/NL bit. * It is called both from the top half for output, and from * interrupt level for echoing. * The arguments are the character and the tty structure. */ ttyoutput(ac, tp) struct tty *tp; { register int c; register struct tty *rtp; register char *colp; int ctype; rtp= tp; c = ac&0177; /* Ignore EOT in normal mode to avoid hanging up * certain terminals. */ if (c==004 && (rtp->t_flags&RAW)==0) return; /* Turn tabs to spaces as required */ if (c==’\t’ && rtp->t_flags&XTABS) { do ttyoutput(’ ’, rtp); while (rtp->t_col&07); return; } /* for upper-case-only terminals, * generate escapes. */ if (rtp->t_flags&LCASE) {

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 83

Sheet 83

Sep

8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449

1 09:28 1988

unix/tty.c Page 7

colp = "({)}!|^~’‘"; while(*colp++) if(c == *colp++) { ttyoutput(’\\’, rtp); c = colp[-2]; break; } if (’a’t_outq)) return; /* Calculate delays. * The numbers here represent clock ticks * and are not necessarily optimal for all terminals. * The delays are indicated by characters above 0200, * thus (unfortunately) restricting the transmission * path to 7 bits. */ colp = &rtp->t_col; ctype = partab[c]; c = 0; switch(ctype&077) { /* ordinary */ case 0: (*colp)++; /* non-printing */ case 1: break; /* backspace */ case 2: if (*colp) (*colp)--; break; /* newline */ case 3: ctype = (rtp->t_flags >> 8) & 03; if(ctype == 1) { /* tty 37 */ if (*colp) c = max((*colp>>4) + 3, 6); } else if(ctype == 2) { /* vt05 */ c = 6; } *colp = 0; break;

Sep

8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499

1 09:28 1988

unix/tty.c Page 8

/* tab */ case 4: ctype = (rtp->t_flags >> 10) & 03; if(ctype == 1) { /* tty 37 */ c = 1 - (*colp | ~07); if(c < 5) c = 0; } *colp =| 07; (*colp)++; break; /* vertical motion */ case 5: if(rtp->t_flags & VTDELAY) /* tty 37 */ c = 0177; break; /* carriage return */ case 6: ctype = (rtp->t_flags >> 12) & 03; if(ctype == 1) { /* tn 300 */ c = 5; } else if(ctype == 2) { /* ti 700 */ c = 10; } *colp = 0; } if(c) putc(c|0200, &rtp->t_outq); } /* ------------------------*/ /* Restart typewriter output following a delay * timeout. * The name of the routine is passed to the timeout * subroutine and it is called during a clock interrupt. */ ttrstrt(atp) { register struct tty *tp; tp = atp; tp->t_state =& ~TIMEOUT; ttstart(tp); } /* /* * * * *

------------------------*/ Start output on the typewriter. It is used from the top half after some characters have been put on the output queue, from the interrupt routine to transmit the next character, and after a timeout has finished. If the SSTART bit is off for the tty the work is done

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 84

Sheet 84

Sep

1 09:28 1988

unix/tty.c Page 9

8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 8539 8540 8541 8542 8543 8544 8545 8546 8547 8548 8549

* here, using the protocol of the single-line interfaces * (kl, dl, dc); otherwise the address word of the tty * structure is taken to be the name of the device-dependent * start-up routine. */ ttstart(atp) struct tty *atp; { register int *addr, c; register struct tty *tp; struct { int (*func)(); };

Sep

8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 tp = atp; 8562 addr = tp->t_addr; 8563 if (tp->t_state&SSTART) { 8564 (*addr.func)(tp); 8565 return; 8566 } 8567 if ((addr->tttcsr&DONE)==0 || tp->t_state&TIMEOUT) 8568 return; 8569 if ((c=getc(&tp->t_outq)) >= 0) { 8570 if (ctttbuf = c | (partab[c]&0200); 8572 else { 8573 timeout(ttrstrt, tp, c&0177); 8574 tp->t_state =| TIMEOUT; 8575 } 8576 } 8577 } 8578 /* ------------------------*/ 8579 /* Called from device’s read routine after it has 8580 * calculated the tty-structure given as argument. 8581 * The pc is backed up for the duration of this call. 8582 * In case of a caught interrupt, an RTI will re-execute. 8583 */ 8584 ttread(atp) 8585 struct tty *atp; 8586 { 8587 register struct tty *tp; 8588 8589 tp = atp; 8590 if ((tp->t_state&CARR_ON)==0) 8591 return; 8592 if (tp->t_canq.c_cc || canon(tp)) 8593 while (tp->t_canq.c_cc && passc(getc(&tp->t_canq))>=0); 8594 } 8595 /* ------------------------*/ 8596 /* Called from the device’s write routine after it has 8597 * calculated the tty-structure given as argument. 8598 */ 8599

1 09:28 1988

unix/tty.c Page 10

ttwrite(atp) struct tty *atp; { register struct tty *tp; register int c; tp = atp; if ((tp->t_state&CARR_ON)==0) return; while ((c=cpass())>=0) { spl5(); while (tp->t_outq.c_cc > TTHIWAT) { ttstart(tp); tp->t_state =| ASLEEP; sleep(&tp->t_outq, TTOPRI); } spl0(); ttyoutput(c, tp); } ttstart(tp); } /* ------------------------*/ /* Common code for gtty and stty functions on typewriters. * If v is non-zero then gtty is being done and information * is passed back therein; * if it is zero stty is being done and the input inform* ation is in the u_arg array. */ ttystty(atp, av) int *atp, *av; { register *tp, *v; tp = atp; if(v = av) { *v++ = tp->t_speeds; v->lobyte = tp->t_erase; v->hibyte = tp->t_kill; v[1] = tp->t_flags; return(1); } wflushtty(tp); v = u.u_arg; tp->t_speeds = *v++; tp->t_erase = v->lobyte; tp->t_kill = v->hibyte; tp->t_flags = v[1]; return(0); } /* ------------------------*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 85

Sheet 85

Sep

1 09:28 1988

unix/pc.c Page 1

Sep

8600 8601 8602 8603 8604 8605 8606 8607 8608 8609 8610 8611 8612 8613 8614 8615 8616 8617 8618 8619 8620 8621 8622 8623 8624 8625 8626 8627 8628 8629 8630 8631 8632 8633 8634 8635 8636 8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647 8648 8649

# /* PC-11 Paper tape reader/punch driver */ #include "../param.h" #include "../conf.h" #include "../user.h" #define

PCADDR

0177550

#define #define #define #define

CLOSED WAITING READING EOF

0 1 2 3

#define #define #define #define #define

RDRENB IENABLE DONE BUSY ERROR

01 0100 0200 04000 0100000

#define #define #define #define #define

PCIPRI PCOPRI PCOLWAT PCOHWAT PCIHWAT

30 40 50 100 250

struct { int pcrcsr; int pcrbuf; int pcpcsr; int pcpbuf; }; /* -------------------------

*/

struct clist { int cc; int cf; int cl; }; /* -------------------------

*/

struct pc11 { int pcstate; struct clist pcin; struct clist pcout; } pc11; /* -------------------------

*/

pcopen(dev, flag) {

8650 8651 8652 8653 8654 8655 8656 8657 8658 8659 8660 8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691 8692 8693 8694 8695 8696 8697 8698 8699

1 09:28 1988

unix/pc.c Page 2

extern lbolt; if (flag==0) { if (pc11.pcstate!=CLOSED) { u.u_error = ENXIO; return; } pc11.pcstate = WAITING; while(pc11.pcstate==WAITING) { PCADDR->pcrcsr = IENABLE|RDRENB; sleep(&lbolt, PCIPRI); } } else { PCADDR->pcpcsr =| IENABLE; pcleader(); } } /* -------------------------

*/

pcclose(dev, flag) { if (flag==0) { spl4(); while (getc(&pc11.pcin) >= 0); PCADDR->pcrcsr = 0; pc11.pcstate = CLOSED; spl0(); } else pcleader(); } /* ------------------------*/ pcread() { register int c; spl4(); do { while ((c = getc(&pc11.pcin)) < 0) { if (pc11.pcstate==EOF) goto out; if ((PCADDR->pcrcsr&(ERROR|BUSY|DONE))==0) PCADDR->pcrcsr =| IENABLE|RDRENB; sleep(&pc11.pcin, PCIPRI); } } while(passc(c)>=0); out: spl0(); } /* ------------------------*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 86

Sheet 86

Sep

8700 8701 8702 8703 8704 8705 8706 8707 8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741 8742 8743 8744 8745 8746 8747 8748 8749

1 09:28 1988

unix/pc.c Page 3

Sep

8750 8751 8752 8753 8754 while ((c=cpass())>=0) 8755 pcoutput(c); 8756 } 8757 /* ------------------------*/ 8758 8759 pcstart() 8760 { 8761 register int c; 8762 8763 if (PCADDR->pcpcsr&DONE && (c = getc(&pc11.pcout)) >= 0) 8764 PCADDR->pcpbuf = c; 8765 } 8766 /* ------------------------*/ 8767 8768 pcrint() 8769 { 8770 if (pc11.pcstate==WAITING) { 8771 if (PCADDR->pcrcsr&ERROR) 8772 return; 8773 pc11.pcstate = READING; 8774 } 8775 if (pc11.pcstate==READING) { 8776 if (PCADDR->pcrcsr&ERROR) 8777 pc11.pcstate = EOF; 8778 else { 8779 putc(PCADDR->pcrbuf, &pc11.pcin); 8780 if (pc11.pcin.cc < PCIHWAT) 8781 PCADDR->pcrcsr =| IENABLE|RDRENB; 8782 } 8783 wakeup(&pc11.pcin); 8784 } 8785 } 8786 /* ------------------------*/ 8787 8788 pcpint() 8789 { 8790 8791 pcstart(); 8792 if (pc11.pcout.cc pcpcsr&ERROR) { u.u_error = EIO; return; } if (pc11.pcout.cc >= PCOHWAT) sleep(&pc11.pcout, PCOPRI); putc(c, &pc11.pcout); spl4(); pcstart(); spl0(); } /* -------------------------

*/

pcleader() { register int i; i = 100; do pcoutput(0); while (--i); } /* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 87

Sheet 87

Sep

1 09:28 1988

8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849

# /* */

unix/lp.c Page 1

/* * LP-11 Line printer driver */ #include "../param.h" #include "../conf.h" #include "../user.h" #define

LPADDR

0177514

#define #define

IENABLE 0100 DONE 0200

#define #define #define #define #define

LPPRI LPLWAT LPHWAT EJLINE MAXCOL

10 50 100 60 80

struct { int lpsr; int lpbuf; }; /* ------------------------struct { int cc; int cf; int cl; int flag; int mcc; int ccc; int mlc; } lp11; /* -------------------------

*/

*/

#define CAP

01

/* Set to 0 for 96-char printer, else to 01 */

#define EJECT #define OPEN #define IND

02 04 010 /* Set to 0 for no indent, else to 010 */

#define FORM

014

Sep

1 09:28 1988

unix/lp.c Page 2

8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 8873 8874 8875 8876 8877 8878 8879 8880 8881 8882 8883 8884 8885 8886 8887 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 8899

lpopen(dev, flag) { if(lp11.flag & OPEN || LPADDR->lpsr < 0) { u.u_error = EIO; return; } lp11.flag =| (IND|EJECT|OPEN); LPADDR->lpsr =| IENABLE; lpcanon(FORM); } /* -------------------------

*/

lpclose(dev, flag) { lpcanon(FORM); lp11.flag = 0; } /* -------------------------

*/

lpwrite() { register int c; while ((c=cpass())>=0) lpcanon(c); } /* -------------------------

*/

lpcanon(c) { register c1, c2; c1 = c; if(lp11.flag&CAP) { if(c1>=’a’ && c1= EJLINE && lp11.flag&EJECT) 8977 c1 = FORM; 8978 lpoutput(c1); 8979 if(c1 == FORM) 8980 lp11.mlc = 0; 8981 } 8982 8983 case ’\r’: 8984 lp11.ccc = 0; 8985 if(lp11.flag&IND) 8986 lp11.ccc = 8; 8987 return; 8988 8989 case 010: 8990 if(lp11.ccc > 0) 8991 lp11.ccc--; 8992 return; 8993 8994 case ’ ’: 8995 lp11.ccc++; 8996 return; 8997 8998 default: 8999

1 09:28 1988

unix/lp.c Page 4

if(lp11.ccc < lp11.mcc) { lpoutput(’\r’); lp11.mcc = 0; } if(lp11.ccc < MAXCOL) { while(lp11.ccc > lp11.mcc) { lpoutput(’ ’); lp11.mcc++; } lpoutput(c1); lp11.mcc++; } lp11.ccc++;

case ’|’: c2 = ’!’; goto esc;

} } /* -------------------------

*/

lpstart() { register int c; while (LPADDR->lpsr&DONE && (c = getc(&lp11)) >= 0) LPADDR->lpbuf = c; } /*

------------------------

*/

lpint() { register int c; lpstart(); if (lp11.cc == LPLWAT || lp11.cc == 0) wakeup(&lp11); } /* -------------------------

*/

lpoutput(c) { if (lp11.cc >= LPHWAT) sleep(&lp11, LPPRI); putc(c, &lp11); spl4(); lpstart(); spl0(); } /* -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 89

Sheet 89

Sep

1 09:28 1988

9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017 9018 9019 9020 9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047 9048 9049

# /* */

unix/mem.c Page 1

/* * Memory special * minor device 0 * minor device 1 * minor device 2 */ #include #include #include #include

Sep

file is physical memory is kernel memory is EOF/RATHOLE

"../param.h" "../user.h" "../conf.h" "../seg.h"

mmread(dev) { register c, bn, on; int a, d; if(dev.d_minor == 2) return; do { bn = lshift(u.u_offset, -6); on = u.u_offset[1] & 077; a = UISA->r[0]; d = UISD->r[0]; spl7(); UISA->r[0] = bn; UISD->r[0] = 077406; if(dev.d_minor == 1) UISA->r[0] = (ka6-6)->r[(bn>>7)&07] + (bn & 0177); c = fuibyte(on); UISA->r[0] = a; UISD->r[0] = d; spl0(); } while(u.u_error==0 && passc(c)>=0); } /* -------------------------

*/

mmwrite(dev) { register c, bn, on; int a, d; if(dev.d_minor == 2) { c = u.u_count; u.u_count = 0;

1 09:28 1988

9050 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 } 9073 /* 9074 9075 9076 9077 9078 9079 9080 9081 9082 9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099

unix/mem.c Page 2

u.u_base =+ c; dpadd(u.u_offset, c); return; } for(;;) { bn = lshift(u.u_offset, -6); on = u.u_offset[1] & 077; if ((c=cpass())r[0] = bn; d = UISD->r[0] = 077406; spl7(); UISA->r[0]; UISD->r[0]; if(dev.d_minor == 1) UISA->r[0] = (ka6-6)->r[(bn>>7)&07] + (bn & 0177); suibyte(on, c); UISA->r[0] = a; UISD->r[0] = d; spl0(); } -------------------------

*/

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Reproduced under license from the Western Electric Company, NY Copyright, J. Lions, 1976

Sheet 90

Sheet 90