Sunteți pe pagina 1din 118

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

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 execs */
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 ids */

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 doesnt 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 Programmers 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\<8|6,(r1)+

/ ksr = sysu

/ initialize io segment
/ set up counts on supervisor segments
mov
mov

$IO,(r0)+
$77406,(r1)+

/ rw 4k

/ get a sp and start segmentation


mov
inc

$_u+[USIZE*64.],sp
SSR0

/ clear bss

0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699

1 09:28 1988

mov

unix/m40.s Page 2

$_edata,r0

1:
clr
cmp
blo

(r0)+
r0,$_end
1b

/ clear user block


mov

$_u,r0

clr
cmp
blo

(r0)+
r0,$_u+[USIZE*64.]
1b

1:

/ set up previous mode and call main


/ on return, enter user mode at 0R
mov
jsr
mov
clr
rtt

$30000,PS
pc,_main
$170000,-(sp)
-(sp)

/* ------------------------.globl
_clearseg
_clearseg:
mov
PS,-(sp)
mov
UISA0,-(sp)
mov
$30340,PS
mov
6(sp),UISA0
mov
UISD0,-(sp)
mov
$6,UISD0
clr
r0
mov
$32.,r1
1:
clr
-(sp)
mtpi
(r0)+
sob
r1,1b
mov
(sp)+,UISD0
mov
(sp)+,UISA0
mov
(sp)+,PS
rts
pc

*/

/* ------------------------.globl
_copyseg
_copyseg:
mov
PS,-(sp)
mov
UISA0,-(sp)
mov
UISA1,-(sp)

*/

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 06

Sheet 06

Sep

0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749

1 09:28 1988

unix/m40.s Page 3

mov
mov
mov
mov
mov
mov
mov
mov
clr
mov
mov

$30340,PS
10(sp),UISA0
12(sp),UISA1
UISD0,-(sp)
UISD1,-(sp)
$6,UISD0
$6,UISD1
r2,-(sp)
r0
$8192.,r1
$32.,r2

mfpi
mtpi
sob
mov
mov
mov
mov
mov
mov
rts

(r0)+
(r1)+
r2,1b
(sp)+,r2
(sp)+,UISD1
(sp)+,UISD0
(sp)+,UISA1
(sp)+,UISA0
(sp)+,PS
pc

Sep

1:

/* ------------------------.globl
_savu, _retu, _aretu
_savu:
bis
$340,PS
mov
(sp)+,r1
mov
(sp),r0
mov
sp,(r0)+
mov
r5,(r0)+
bic
$340,PS
jmp
(r1)
_aretu:
bis
mov
mov
br
_retu:
bis
mov
mov
mov
1:
mov
mov
bic
jmp

*/

$340,PS
(sp)+,r1
(sp),r0
1f

$340,PS
(sp)+,r1
(sp),r0
$_u,r0
(r0)+,sp
(r0)+,r5
$340,PS
(r1)

0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797
0798
0799

1 09:28 1988

unix/m40.s Page 4

/* ------------------------.globl
trap, call
/* ------------------------.globl
_trap
trap:
mov
PS,-4(sp)
tst
nofault
bne
1f
mov
SSR0,ssr
mov
SSR2,ssr+4
mov
$1,SSR0
jsr
r0,call1; _trap
/ no return
1:
mov
$1,SSR0
mov
nofault,(sp)
rtt

*/

/* ------------------------.globl
_runrun, _swtch
call1:
tst
-(sp)
bic
$340,PS
br
1f

*/

call:
mov
1:
mov
mfpi
mov
bic
bit
beq
jsr
2:
bis
tstb
beq
bic
jsr
br
2:
tst
mtpi
br
1:
bis
jsr

*/

PS,-(sp)
r1,-(sp)
sp
4(sp),-(sp)
$!37,(sp)
$30000,PS
1f
pc,*(r0)+
$340,PS
_runrun
2f
$340,PS
ps,_swtch
2b
(sp)+
sp
2f
$30000,PS
pc,*(r0)+

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 07

Sheet 07

Sep

0800
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848
0849

1 09:28 1988

cmp

unix/m40.s Page 5

Sep

(sp)+,(sp)+

2:
mov
(sp)+,r1
tst
(sp)+
mov
(sp)+,r0
rtt
/* ------------------------.globl
_fubyte, _subyte
/* ------------------------.globl
_fuibyte, _suibyte
/* ------------------------.globl
_fuword, _suword
/* ------------------------.globl
_fuiword, _suiword
_fuibyte:
_fubyte:
mov
2(sp),r1
bic
$1,r1
jsr
pc,gword
cmp
r1,2(sp)
beq
1f
swab
r0
1:
bic
$!377,r0
rts
pc
_suibyte:
_subyte:
mov
bic
jsr
mov
cmp
beq
movb
br
1:
movb
2:
mov
jsr
clr
rts
_fuiword:
_fuword:
mov
fuword:
jsr
rts

*/
*/
*/
*/

2(sp),r1
$1,r1
pc,gword
r0,-(sp)
r1,4(sp)
1f
6(sp),1(sp)
2f
6(sp),(sp)
(sp)+,r0
pc,pword
r0
pc

2(sp),r1
pc,gword
pc

0850
0851
0852
0853
0854
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866
0867
0868
0869
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879
0880
0881
0882
0883
0884
0885
0886
0887
0888
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899

1 09:28 1988

gword:
mov
bis
mov
mov
mfpi
mov
br
_suiword:
_suword:
mov
mov
suword:
jsr
rts
pword:
mov
bis
mov
mov
mov
mtpi
1:
mov
mov
rts
err:
mov
mov
tst
mov
rts

unix/m40.s Page 6

PS,-(sp)
$340,PS
nofault,-(sp)
$err,nofault
(r1)
(sp)+,r0
1f

2(sp),r1
4(sp),r0
pc,pword
pc

PS,-(sp)
$340,PS
nofault,-(sp)
$err,nofault
r0,-(sp)
(r1)
(sp)+,nofault
(sp)+,PS
pc

(sp)+,nofault
(sp)+,PS
(sp)+
$-1,r0
pc

/* ------------------------.globl
_savfp, _display
_savfp:
_display:
rts
pc

*/

/* ------------------------*/
.globl
_incupc
_incupc:
mov
r2,-(sp)
mov
6(sp),r2 / base of prof with base,leng,off,scale
mov
4(sp),r0
/ pc
sub
4(r2),r0
/ offset

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 08

Sheet 08

Sep

0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933
0934
0935
0936
0937
0938
0939
0940
0941
0942
0943
0944
0945
0946
0947
0948
0949

1 09:28 1988

unix/m40.s Page 7

clc
ror
mul
ashc
inc
bic
cmp
bhis
add
mov
mov
mfpi
inc
mtpi
br

r0
6(r2),r0
$-14.,r0
r1
$1,r1
r1,2(r2)
1f
(r2),r1
nofault,-(sp)
$2f,nofault
(r1)
(sp)
(r1)
3f

clr

6(r2)

Sep

/ scale

/ length
/ base

2:
3:
mov

(sp)+,nofault

1:
mov
rts

(sp)+,r2
pc

/ Character list get/put


/* ------------------------.globl
_getc, _putc
/* ------------------------.globl
_cfreelist
_getc:
mov
mov
mov
bis
bic
mov
beq
movb
bic
mov
dec
bne
clr
clr
br
1:
bit
bne
mov

2(sp),r1
PS,-(sp)
r2,-(sp)
$340,PS
$100,PS
2(r1),r2
9f
(r2)+,r0
$!377,r0
r2,2(r1)
(r1)+
1f
(r1)+
(r1)+
2f
$7,r2
3f
-10(r2),(r1)

/
/
/
/

*/
*/

spl 5
first ptr
empty
character

/ count

/ last block

/ next block

0950
0951
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999

1 09:28 1988

unix/m40.s Page 8

add

$2,(r1)

dec
bic
mov
mov

r2
$7,r2
_cfreelist,(r2)
r2,_cfreelist

mov
mov
rts

(sp)+,r2
(sp)+,PS
pc

clr
mov
mov
mov
rts

4(r1)
$-1,r0
(sp)+,r2
(sp)+,PS
pc

2:

3:

9:

_putc:
mov
2(sp),r0
mov
4(sp),r1
mov
PS,-(sp)
mov
r2,-(sp)
mov
r3,-(sp)
bis
$340,PS
bic
$100,PS
mov
4(r1),r2
bne
1f
mov
_cfreelist,r2
beq
9f
mov
(r2),_cfreelist
clr (r2)+
mov
r2,2(r1)
br
2f
1:
bit
$7,r2
bne
2f
mov
_cfreelist,r3
beq
9f
mov
(r3),_cfreelist
mov
r3,-10(r2)
mov
r3,r2
clr
(r2)+
2:
movb
r0,(r2)+
mov
r2,4(r1)
inc
(r1)
clr
r0
mov
(sp)+,r3
mov
(sp)+,r2
mov
(sp)+,PS

/ spl 5
/ last ptr

/ first ptr

/ count

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 09

Sheet 09

Sep

1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049

1 09:28 1988

unix/m40.s Page 9

rts

pc

mov
mov
mov
mov
rts

pc,r0
(sp)+,r3
(sp)+,r2
(sp)+,PS
pc

Sep

9:

/* ------------------------.globl
_backup
/* ------------------------.globl
_regloc
_backup:
mov
2(sp),ssr+2
mov
r2,-(sp)
jsr
pc,backup
mov
r2,ssr+2
mov
(sp)+,r2
movb
jflg,r0
bne
2f
mov
2(sp),r0
movb
ssr+2,r1
jsr
pc,1f
movb
ssr+3,r1
jsr
pc,1f
movb
_regloc+7,r1
asl
r1
add
r0,r1
mov
ssr+4,(r1)
clr
r0
2:
rts
pc
1:
mov
r1,-(sp)
asr
(sp)
asr
(sp)
asr
(sp)
bic
$!7,r1
movb
_regloc(r1),r1
asl
r1
add
r0,r1
sub
(sp)+,(r1)
rts
pc

*/
*/

/ hard part
/ simulate the ssr2 register missing on 11/40
backup:
clr
mov

r2
$1,bflg

/ backup register ssr1


/ clrs jflg

1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099

1 09:28 1988

mov
jsr
mov
ash
bic
jmp
0:

unix/m40.s Page 10

ssr+4,r0
pc,fetch
r0,r1
$-11.,r0
$!36,r0
*0f(r0)
t00; t01; t02; t03; t04; t05; t06; t07
t10; t11; t12; t13; t14; t15; t16; t17

t00:
clrb

bflg

t10:
mov
swab
bic
jmp
0:

r1,r0
r0
$!16,r0
*0f(r0)
u0; u1; u2; u3; u4; u5; u6; u7

u6:
bit
beq
bit
beq
bit
bne

/ single op, m[tf]pi, sxt, illegal


$400,r1
u5
/ all but m[tf], sxt
$200,r1
1f
/ mfpi
$100,r1
u5
/ sxt

/ simulate mtpi with double (sp)+,dd


bic
$4000,r1
/ turn instr into (sp)+
br
t01
/ simulate
1:
ash
bis
br
u4:
mov
jsr
bis
rts

mfpi with double ss,-(sp)


$6,r1
$46,r1
t01
/ jsr
r1,r0
pc,setreg
$173000,r2
pc

t07:
clrb

/ EIS
bflg

u0:
u5:

/ jmp, swab
/ single op
r1,r0
setreg

mov
br

/ -(sp)

/ assume no fault
/ -2 from sp

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 10

Sheet 10

Sep

1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149

1 09:28 1988

unix/m40.s Page 11

t01:
t02:
t03:
t04:
t05:
t06:
t16:
clrb

/ mov
/ cmp
/ bit
/ bic
/ bis
/ add
/ sub
bflg

t11:
t12:
t13:
t14:
t15:
mov
ash
jsr
swab
mov
jsr

/ movb
/ cmpb
/ bitb
/ bicb
/ bisb
r1,r0
$-6,r0
pc,setreg
r2
r1,r0
pc,setreg

/ if delta(dest) is zero,
/ no need to fetch source
bit
beq

$370,r2
1f

/ if mode(source) is R,
/ no fault is possible
bit
beq

$7000,r1
1f

/ if reg(source) is reg(dest),
/ too bad.
mov
bic
cmpb
beq

r2,-(sp)
$174370,(sp)
1(sp),(sp)+
t17

/ start source cycle


/ pick up value of reg
mov
ash
bic
movb
asl

r1,r0
$-6,r0
$!7,r0
_regloc(r0),r0
r0

Sep

1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199

1 09:28 1988

add
mov

unix/m40.s Page 12

ssr+2,r0
(r0),r0

/ if reg has been incremented,


/ must decrement it before fetch
bit
ble
dec
bit
beq
dec

$174000,r2
2f
r0
$10000,r2
2f
r0

2:
/ if mode is 6,7 fetch and add X(R) to R
bit
beq
bit
beq
mov
mov
sdd
jsr
add

$4000,r1
2f
$2000,r1
2f
r0,-(sp)
ssr+4,r0
$2,r0
pc,fetch
(sp)+,r0

2:
/ fetch operand
/ if mode is 3,5,7 fetch *
jsr
bit
beq
bit
bne

pc,fetch
$1000,r1
1f
$6000,r1
fetch

rts

pc

1:

t17:
u1:
u2:
u3:
u7:
incb
rts

/ illegal
/ br
/ br
/ br
/ illegal
jflg
pc

setreg:
mov
bic
bis

r0,-(sp)
$!7,r0
r0,r2

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 11

Sheet 11

Sep

1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249

1 09:28 1988

unix/m40.s Page 13

mov
ash
bic
movb
tstb
beq
bit
beq
bit
beq

(sp)+,r0
$-3,r0
$!7,r0
0f(r0),r0
bflg
1f
$2,r2
2f
$4,r2
2f

cmp
beq
cmp
beq
asl

r0,$20
2f
r0,$-20
2f
r0

bisb
rts

r0,r2
pc

1:

2:

0: .byte

0,0,10,20,-10,-20,0,0

fetch:
bic
mov
mov
mfpi
mov
mov
rts

$1,r0
nofault,-(sp)
$1f,nofault
(r0)
(sp)+,r0
(sp)+,nofault
pc

1:
mov
clrb
mov
rts
.bss
bflg:
jflg:
.text

(sp)+,nofault
r2
$-1,r0
pc

.=.+1
.=.+1

/* ------------------------.globl
_copyin, _copyout
_copyin:
jsr
pc,copsu
1:
mfpi
(r0)+
mov
(sp)+,(r1)+
sob
r2,1b

Sep

1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
/ clear out dest on fault 1283
1284
1285
1286
1287
1288
1289
1290
1291
*/
1292
1293
1294
1295
1296
1297
1298
1299

1 09:28 1988

br
_copyout:
jsr
1:
mov
mtpi
sob
2:
mov
mov
clr
rts
copsu:
mov
mov
mov
mov
mov
mov
mov
asr
mov
rts

unix/m40.s Page 14

2f

pc,copsu
(r0)+,-(sp)
(r1)+
r2,1b
(sp)+,nofault
(sp)+,r2
r0
pc

(sp)+,r0
r2,-(sp)
nofault,-(sp)
r0,-(sp)
10(sp),r0
12(sp),r1
14(sp),r2
r2
$1f,nofault
pc

1:
mov
mov
mov
rts

(sp)+,nofault
(sp)+,r2
$-1,r0
pc

/* ------------------------.globl
_idle
_idle:
mov
PS,-(sp)
bic
$340,PS
wait
mov
(sp)+,PS
rts
pc

*/

/* ------------------------*/
.globl
_spl0, _spl1, _spl4, _spl5, _spl6, _spl7
_spl0:
bic
$340,PS
rts
pc
_spl1:
bis
bic

$40,PS
$300,PS

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 12

Sheet 12

Sep

1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349

1 09:28 1988

rts
_spl4:
_spl5:
bis
bic
rts

unix/m40.s Page 15

Sep

pc

$340,PS
$100,PS
pc

_spl6:
bis
bic
rts

$340,PS
$40,PS
pc

_spl7:
bis
rts

$340,PS
pc

/* ------------------------.globl
_dpadd
_dpadd:
mov
2(sp),r0
add
4(sp),2(r0)
adc
(r0)
rts
pc

*/

/* ------------------------.globl
_dpcmp
_dpcmp:
mov
2(sp),r0
mov
4(sp),r1
sub
6(sp),r0
sub
8(sp),r1
sbc
r0
bge
1f
cmp
r0,$-1
bne
2f
cmp
r1,$-512.
bhi
3f
2:
mov
$-512.,r0
rts
pc
1:
bne
2f
cmp
r1,$512.
blo
3f
2:
mov
$512.,r1
3:
mov
r1,r0
rts
pc

*/

1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399

1 09:28 1988

unix/m40.s Page 16

/* ------------------------.globl
dump
dump:
bit
$1,SSR0
bne
dump

*/

/ save regs r0,r1,r2,r3,r4,r5,r6,KIA6


/ starting at abs location 4
mov
mov
mov
mov
mov
mov
mov
mov
mov

r0,4
$6,r0
r1,(r0)+
r2,(r0)+
r3,(r0)+
r4,(r0)+
r5,(r0)+
sp,(r0)+
KISA6,(r0)+

/ dump all of core (ie to first mt error)


/ onto mag tape. (9 track or 7 track binary)
mov
mov
clr

$MTC,r0
$60004,(r0)+
2(r0)

mov
inc

$-512.,(r0)
-(r0)

tstb
bge
tst
bge
reset

(r0)
2b
(r0)+
1b

1:

2:

/ end of file and loop


mov
br

$60007,-(r0)
.

/* ------------------------.globl
_ldiv
_ldiv:
clr
r0
mov
2(sp),r1
div
4(sp),r0
rts
pc

*/

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

*/

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 13

Sheet 13

Sep

1 09:28 1988

1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449

.globl
_lrem:
clr
mov
div
mov
rts

unix/m40.s Page 17

_lrem
r0
2(sp),r1
4(sp),r0
r1,r0
pc

/* ------------------------.globl
_lshift
_lshift:
mov
2(sp),r1
mov
(r1)+,r0
mov
(r1),r1
ashc
4(sp),r0
mov
r1,r0
rts
pc

*/

/* ------------------------.globl
csv
csv:
mov
r5,r0
mov
sp,r5
mov
r4,-(sp)
mov
r3,-(sp)
mov
r2,-(sp)
jsr
pc,(r0)

*/

/* ------------------------.globl
cret
cret:
mov
r5,r1
mov
-(r1),r4
mov
-(r1),r3
mov
-(r1),r2
mov
r5,sp
mov
(sp)+,r5
rts
pc

*/

/* ------------------------.globl
_u
_u = 140000
USIZE
= 16.

*/

PS
SSR0
SSR2
KISA0
KISA6
KISD0

=
=
=
=
=
=

177776
177572
177576
172340
172354
172300

Sep

1 09:28 1988

1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499

MTC
UISA0
UISA1
UISD0
UISD1
IO = 7600

=
=
=
=
=

unix/m40.s Page 18

172522
177640
177642
177600
177602

.data
/* ------------------------.globl
_ka6, _cputype
_ka6:
KISA6
_cputype:40.
.bss
/* ------------------------.globl
nofault, ssr, badtrap
nofault:.=.+2
ssr:
.=.+6
badtrap:.=.+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 14

Sheet 14

Sep

1 09:28 1988

1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549

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

unix/main.c Page 1

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

#define
CLOCK1 0177546
#define
CLOCK2 0172540
/*
* Icode is the octal bootstrap
* program executed in user mode
* to bring up the system.
*/
int
icode[]
{
0104413,
/* sys exec; init; initp */
0000014,
0000010,
0000777,
/* br . */
0000014,
/* initp: init; 0 */
0000000,
0062457,
/* init: </etc/init\0> */
0061564,
0064457,
0064556,
0000164,
};
/* ------------------------*/
/*
* Initialization code.
* Called from m40.s or m45.s as
* soon as a stack and segmentation
* have been established.
* Functions:
* clear and free user core
* find which clock is configured
* hand craft 0th process
* call all initialization routines
* fork - process 0 to schedule
*
- process 1 execute bootstrap
*
* panic: no clock -- neither clock responds
* loop at loc 6 in user mode -- /etc/init
* cannot be executed
*/

Sep

1 09:28 1988

unix/main.c Page 2

1550 main()
1551 {
1552
extern schar;
1553
register i, *p;
1554
1555
/*
1556
* zero and free all of core
1557
*/
1558
1559
updlock = 0;
1560
i = *ka6 + USIZE;
1561
UISD->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; i<62; i=+2) {
1573
UBMAP->r[i] = i<<12;
1574
UBMAP->r[i+1] = 0;
1575
}
1576
printf("mem = %l\n", maxmem*5/16);
1577
printf("RESTRICTED RIGHTS\n\n");
1578
printf("Use, duplication or disclosure is subject to\n");
1579
printf("restrictions stated in Contract with Western\n");
1580
printf("Electric Company, Inc.\n");
1581
1582
maxmem = min(maxmem, MAXMEM);
1583
mfree(swapmap, nswap, swplo);
1584
1585
/*
1586
* set up system process
1587
*/
1588
1589
proc[0].p_addr = *ka6;
1590
proc[0].p_size = USIZE;
1591
proc[0].p_stat = SRUN;
1592
proc[0].p_flag =| SLOAD|SSYS;
1593
u.u_procp = &proc[0];
1594
1595
/*
1596
* determine clock
1597
*/
1598
1599
UISA->r[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<<8) | RO;
1669
*ap++ = a;
1670
a =+ 128;
1671
nt =- 128;
1672
}
1673
if(nt) {
1674
*dp++ = ((nt-1)<<8) | RO;
1675
*ap++ = a;
1676
}
1677
if(sep)
1678
while(ap < &u.u_uisa[8]) {
1679
*ap++ = 0;
1680
*dp++ = 0;
1681
}
1682
a = USIZE;
1683
while(nd >= 128) {
1684
*dp++ = (127<<8) | RW;
1685
*ap++ = a;
1686
a =+ 128;
1687
nd =- 128;
1688
}
1689
if(nd) {
1690
*dp++ = ((nd-1)<<8) | RW;
1691
*ap++ = a;
1692
a =+ nd;
1693
}
1694
while(ap < &u.u_uisa[8]) {
1695
*dp++ = 0;
1696
*ap++ = 0;
1697
}
1698
if(sep)
1699
while(ap < &u.u_uisa[16]) {

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 16

Sheet 16

Sep

1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749

1 09:28 1988

unix/main.c Page 5

*dp++ = 0;
*ap++ = 0;
}
a =+ ns;
while(ns >= 128) {
a =- 128;
ns =- 128;
*--dp = (127<<8) | RW;
*--ap = a;
}
if(ns) {
*--dp = ((128-ns)<<8) | RW | ED;
*--ap = a-128;
}
if(!sep) {
ap = &u.u_uisa[0];
dp = &u.u_uisa[8];
while(ap < &u.u_uisa[8])
*dp++ = *ap++;
ap = &u.u_uisd[0];
dp = &u.u_uisd[8];
while(ap < &u.u_uisd[8])
*dp++ = *ap++;
}
sureg();
return(0);
err:
u.u_error = ENOMEM;
return(-1);
}
/*----------------------

*/

/*
* Load the user hardware segmentation
* registers from the software prototype.
* The software registers must have
* been setup prior by estabur.
*/
sureg()
{
register *up, *rp, a;
a = u.u_procp->p_addr;
up = &u.u_uisa[16];
rp = &UISA->r[16];
if(cputype == 40) {
up =- 8;
rp =- 8;
}

Sep

1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799

1 09:28 1988

unix/main.c Page 6

while(rp > &UISA->r[0])


*--rp = *--up + a;
if((up=u.u_procp->p_textp) != NULL)
a =- up->x_caddr;
up = &u.u_uisd[16];
rp = &UISD->r[16];
if(cputype == 40) {
up =- 8;
rp =- 8;
}
while(rp > &UISD->r[0]) {
*--rp = *--up;
if((*rp & WO) == 0)
rp[(UISA-UISD)/2] =- a;
}
}
/* -------------------------

*/

/*
* Return the arg/128 rounded up.
*/
nseg(n)
{
return((n+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 newprocs
* 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 a signal cannot disturb the sleep;
* if the 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 schedulers 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, its easy-- just release the
* extra core. If its growing, and there is core, just
* allocate it and copy the image, taking care to reset
* registers to account for the fact that the systems
* 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 users 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; i<n; i++)
copyseg(a1+i, a2++);
mfree(coremap, n, a1);
retu(p->p_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_addr<=a && bp->m_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 users 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 Cs 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; i<callp->count; i++)
u.u_arg[i] = fuword(a =+ 2);
} else {
for(i=0; i<callp->count; 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 wouldnt have a chance to clean up.
2883
*
2884
* If this occurs, the return takes place without
2885
* clearing u_intflg; if its 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, &gtime,
/* 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, &gtty,
/* 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, &times,
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 callers 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 = &regloc[0]; cp < &regloc[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 callers r0
*/
rexit()
{
u.u_arg[0] = u.u_ar0[R0] << 8;
exit();
}
/* -------------------------

*/

/* Release resources.
* Save u. area for parent to look at.
* Enter zombie state.
* Wake up parent and init processes,
* and dispose of children.
*/
exit()
{
register int *q, a;
register struct proc *p;
u.u_procp->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_sig<<8) |
0177;
return;
}
p->p_flag =& ~(STRC|SWTED);
setrun(p);
}
}
if(f) {
sleep(u.u_procp, PWAIT);
goto loop;
}
u.u_error = ECHILD;
}
/* -------------------------

*/

/* fork system call. */


fork()
{
register struct proc *p1, *p2;
p1 = u.u_procp;
for(p2 = &proc[0]; p2 < &proc[NPROC]; p2++)
if(p2->p_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 arent 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<=0 || 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||p<=&proc[1]))
continue;
if(u.u_uid != 0 && u.u_uid != p->p_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_time<=0 && p2->c_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 <= 0) {
3768
p1 = &callout[0];
3769
while(p1->c_func != 0 && p1->c_time <= 0) {
3770
(*p1->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 HZs 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 <= t) {
t =- p1->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]<<8) | n;
exit();
}
/* -------------------------

*/

/*
* Create a core image on the file "core"
* If you are looking for protection glitches,
* there are probably a wealth of them here
* when this occurs to a suid command.
*
* It writes USIZE block of the
* user.h area followed by the entire
* data+stack segments.
*/
core()
{
register s, *ip;
extern schar;
u.u_error = 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 40

Sheet 40

Sep

4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149

1 09:28 1988

unix/sig.c Page 5

Sep

u.u_dirp = "core";
ip = namei(&schar, 1);
if(ip == NULL) {
if(u.u_error)
return(0);
ip = maknode(0666);
if(ip == NULL)
return(0);
}
if(!access(ip, IWRITE) &&
(ip->i_mode&IFMT) == 0 &&
u.u_uid == u.u_ruid) {
itrunc(ip);
u.u_offset[0] = 0;
u.u_offset[1] = 0;
u.u_base = &u;
u.u_count = USIZE*64;
u.u_segflg = 1;
writei(ip);
s = u.u_procp->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 <= 0)
return(0);
if(estabur(u.u_tsize, u.u_dsize, u.u_ssize+si, u.u_sep))
return(0);
expand(u.u_procp->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] <= 0) {
u.u_procp->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<0 || i >= (USIZE<<6))
4234
goto error;
4235
ipc.ip_data = u.inta[i>>1];
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; i<9; i++)
if (p == &u.u_ar0[regloc[i]])
goto ok;
goto error;
ok:
if (p == &u.u_ar0[RPS]) {
/* assure user space */
ipc.ip_data =| 0170000;
/* priority 0 */
ipc.ip_data =& ~0340;
}
*p = ipc.ip_data;
break;
/* set signal and continue */
case 7:
u.u_procp->p_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 */
/* dont wait wait for I/O
completion */
/* dont 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 {(0<<8)|0};
swapdev {(0<<8)|0};
swplo 4000; /* cannot be zero */
nswap 872;

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 46

Sheet 46

Sep

1 09:28 1988

4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749

#
/*
*/

unix/bio.c Page 1

Sep

4750
4751
4752
4753
#include "../param.h"
4754
#include "../user.h"
4755
#include "../buf.h"
4756
#include "../conf.h"
4757
#include "../systm.h"
4758
#include "../proc.h"
4759
#include "../seg.h"
4760
4761
/*
4762
* This is the set of buffres proper, whose heads
4763
* were declared in buf.h. There can exist buffer
4764
* headers not pointing here that are used purely
4765
* as arguments to the I/O routines to describe
4766
* I/O to be done-- e.g. swbuf, just below, for
4767
* swapping.
4768
*/
4769
char
buffers[NBUF][514];
4770
struct
buf
swbuf;
4771
4772
/*
4773
* Declarations of the tables for the magtape devices;
4774
* see bdwrite.
4775
*/
4776
int
tmtab;
4777
int
httab;
4778
4779
/*
4780
* The following several routines allocate and free
4781
* buffers with various side effects. In general the
4782
* arguments to an allocate routine are a device and
4783
* a block number, and the value is a pointer to
4784
* the buffer header; the buffer is marked "busy"
4785
* so that no one else can touch it. If the block was
4786
* already in core, no I/O need be done; if it is
4787
* already busy, the process waits until it becomes free.
4788
* The following routines allocate a buffer:
4789
* getblk
4790
* bread
4791
* breada
4792
* Eventually the buffer must be released, possibly with the 4793
* side effect of writing it out, by using one of
4794
* bwrite
4795
* bdwrite
4796
* bawrite
4797
* brelse
4798
*/
4799

1 09:28 1988

unix/bio.c Page 2

/* Read in (if necessary) the block and


* return a buffer pointer.
*/
bread(dev, blkno)
{
register struct buf *rbp;
rbp = getblk(dev, blkno);
if (rbp->b_flags&B_DONE)
return(rbp);
rbp->b_flags =| B_READ;
rbp->b_wcount = -256;
(*bdevsw[dev.d_major].d_strategy)(rbp);
iowait(rbp);
return(rbp);
}
/* -------------------------

*/

/*
* Read in the block, like bread, but also start I/O on the
* read-ahead block (which is not allocated to the caller)
*/
breada(adev, blkno, rablkno)
{
register struct buf *rbp, *rabp;
register int dev;
dev = adev;
rbp = 0;
if (!incore(dev, blkno)) {
rbp = getblk(dev, blkno);
if ((rbp->b_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 cant 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 dont 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; i<NBUF; i++) {
bp = &buf[i];
bp->b_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 = (hbcom<<8) | IENABLE | GO |
((rbp->b_xmem & 03) << 4);
if (rbp->b_flags&B_READ)
/*
com =| RCOM;
else
com =| WCOM;
*--dp = com;
}
/* -------------------------

block address */
buffer address */
word count */

command + x-mem */

*/

/* startup routine for RH controllers. */


#define
RHWCOM 060
#define
RHRCOM 070
rhstart(bp, devloc, devblk, abae)
struct buf *bp;
int *devloc, *abae;
{
register int *dp;
register struct buf *rbp;
register int com;
dp = devloc;
rbp = bp;
if(cputype == 70)
*abae = rbp->b_xmem;
*dp = devblk;
/* block address */
*--dp = rbp->b_addr;
/* buffer address */
*--dp = rbp->b_wcount;
/* word count */
com = IENABLE | GO |
((rbp->b_xmem & 03) << 8);
if (rbp->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; i<32; i=+2)
UBMAP->r[i+1] = a;
for(a++; i<48; i=+2)
UBMAP->r[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 = - (count<<5); /* 32 w/block */
swbuf.b_blkno = blkno;
swbuf.b_addr = coreaddr<<6;
/* 64 b/block */
swbuf.b_xmem = (coreaddr>>10) & 077;
(*bdevsw[swapdev>>8].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<<6;
bp->b_xmem = (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)<<1;
geterror(bp);
return;
bad:
u.u_error = EFAULT;
}
/* ------------------------*/
/*
* Pick up the devices error number and pass it to the
* user; if there is an error but the number is 0 set a
* generalised code. Actually the latter is always true
* because devices dont yet return specific errors.
*/
geterror(abp)
struct buf *abp;
{
register struct buf *bp;
bp = abp;
if (bp->b_flags&B_ERROR)
if ((u.u_error = bp->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 <= 0)
d = 1;
if (bp->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 <= 0)
d = p->b_dev.d_minor;
else {
d = lrem(b, m);
b = ldiv(b, m);
}
return(d<<13 | (b/12)<<4 | b%12);
}
/* -------------------------

*/

rkstart()
{
register struct buf *bp;
if ((bp = rktab.d_actf) == 0)
return;
rktab.d_active++;
devstart(bp, &RKADDR->rkda, rkaddr(bp), 0);
}
/* -------------------------

*/

5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499

1 09:28 1988

unix/rk.c Page 3

rkintr()
{
register struct buf *bp;
if (rktab.d_active == 0)
return;
bp = rktab.d_actf;
rktab.d_active = 0;
if (RKADDR->rkcs < 0) {
/* error bit */
deverror(bp, RKADDR->rker, RKADDR->rkds);
RKADDR->rkcs = RESET|GO;
while((RKADDR->rkcs&CTLRDY) == 0) ;
if (++rktab.d_errcnt <= 10) {
rkstart();
return;
}
bp->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]<<9;
n[0] = 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]<0)
n[0] = -1;
}
switch(t) {
case 1:
case 4:
n[0] =+ fp->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 ||
dpcmp(tout[0], tout[1], d[0], d[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; i<14; i++) {
suword(ub, *ip++);
ub =+ 2;
}
for(i=0; i<4; i++) {
suword(ub, *cp++);
ub =+ 2;
}
brelse(bp);
}
/* -------------------------

*/

/*
* the dup system call.
*/
dup()
{
register i, *fp;
fp = getf(u.u_ar0[R0]);
if(fp == NULL)
return;
if ((i = ufalloc()) < 0)
return;
u.u_ofile[i] = fp;
fp->f_count++;
}
/* -------------------------

*/

/*
* the mount system call.
*/
smount()
{
int d;
register *ip;
register struct mount *mp, *smp;
extern uchar;
d = getmdev();
if(u.u_error)
return;
u.u_dirp = u.u_arg[1];
ip = namei(&uchar, 0);
if(ip == NULL)
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 60

Sheet 60

Sep

6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149

1 09:28 1988

unix/sys3.c Page 3

Sep

if(ip->i_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 users 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 <= 0)
6295
return;
6296
n = min(n, dn);
6297
if ((bn = bmap(ip, lbn)) == 0)
6298
return;
6299

1 09:28 1988

unix/rdwri.c Page 2

dn = ip->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; i<8; i++) {
*bap++ = ip->i_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 (bn<7)
rablock = ip->i_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 users 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 users
* 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 users
* 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<0 || 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 <= 1)
closei(rfp->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 <= 1)
switch(rip->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; i<NOFILE; i++)
if (u.u_ofile[i] == NULL) {
u.u_ar0[R0] = 1;
return(i);
}
u.u_error = EMFILE;
return(-1);
}
/* -------------------------

*/

/*
* Allocate a user file descriptor
* and a file structure.
* Initialize the descriptor
* to point at the file structure.
*
* no file -- if there are no available
*
file structures.
*/
falloc()
{
register struct file *fp;

1 09:28 1988

6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865 }
6866 /*
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899

unix/fio.c Page 6

register i;
if ((i = ufalloc()) < 0)
return(NULL);
for (fp = &file[0]; fp < &file[NFILE]; fp++)
if (fp->f_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 roots 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 <= 0)
goto nospace;
bno = fp->s_free[--fp->s_nfree];
if(bno == 0)
goto nospace;
} while (badblock(fp, bno, dev));
if(fp->s_nfree <= 0) {
fp->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 <= 0) {
fp->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; i<fp->s_isize; i++) {
bp = bread(dev, i+2);
ip = bp->b_addr;
for(j=0; j<256; j=+16) {

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 70

Sheet 70

Sep

7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149

1 09:28 1988

unix/alloc.c Page 5

ino++;
if(ip[j] != 0)
continue;
for(k=0; k<NINODE; k++)
if(dev == inode[k].i_dev &&
ino == inode[k].i_number)
goto cont;
fp->s_inode[fp->s_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 <= 0) {
itrunc(rp);
rp->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 <= &cfree[NCLIST-1]; cp++) {
8290
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 (bp<bp1)
8372
putc(*bp++, c);
8373
return(1);
8374
}
8375
/* ------------------------*/
8376
/* Place a character on raw TTY input queue, putting in
8377
* delimiters and waking up top half as needed.
8378
* Also echo if required.
8379
* The arguments are the character and the appropriate
8380
* tty structure.
8381
*/
8382
ttyinput(ac, atp)
8383
struct tty *atp;
8384
{
8385
register int t_flags, c;
8386
register struct tty *tp;
8387
8388
tp = atp;
8389
c = ac;
8390
t_flags = tp->t_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 && c<=Z)
c =+ a-A;
putc(c, &tp->t_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<=c && c<=z)
c =+ A - a;
}
/* turn <nl> to <cr><lf> if desired.
*/
if (c==\n && rtp->t_flags&CRMOD)
ttyoutput(\r, rtp);
if (putc(c, &rtp->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 (c<=0177)
8571
addr->tttbuf = c | (partab[c]&0200);
8572
else {
8573
timeout(ttrstrt, tp, c&0177);
8574
tp->t_state =| TIMEOUT;
8575
}
8576
}
8577
}
8578
/* ------------------------*/
8579
/* Called from devices 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 devices 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 <= PCOLWAT)
8793
wakeup(&pc11.pcout);
8794
}
8795
/* ------------------------*/
8796
8797
pcoutput(c)
8798
{
8799
pcwrite()
{
register int c;

1 09:28 1988

unix/pc.c Page 4

if (PCADDR->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<=z)
c1 =+ A-a; else
switch(c1) {
case {:
c2 = (;
goto esc;
case }:
c2 = );
goto esc;
case :
c2 = \;
goto esc;

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 88

Sheet 88

Sep

8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949

1 09:28 1988

unix/lp.c Page 3

Sep

8950
8951
8952
8953
8954
case ~:
8955
c2 = ^;
8956
8957
esc:
8958
lpcanon(c2);
8959
lp11.ccc--;
8960
c1 = -;
8961
}
8962
}
8963
8964
switch(c1) {
8965
8966
case \t:
8967
lp11.ccc = (lp11.ccc+8) & ~7;
8968
return;
8969
8970
case FORM:
8971
case \n:
8972
if((lp11.flag&EJECT) == 0 ||
8973
lp11.mcc!=0 || lp11.mlc!=0) {
8974
lp11.mcc = 0;
8975
lp11.mlc++;
8976
if(lp11.mlc >= 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())<0 || u.u_error!=0)
break;
a = UISA->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

S-ar putea să vă placă și