†Æ¾�Á! † "ÀW Àü‡NÅ,¿Äà½÷ RÀ=Í ÷ „  @÷� #ôÁåD ï‡ï ŠD Òƒ÷T÷èP÷ Æ B ¤Ñ‹ü �Áe@W 0ó‡÷ ò¹·,"€&€ ¡ 7   ý‡÷ ‚÷ Ê0ß‹pÿýÀ¬@ÀE€ÿ A‡ Z‚Àe  À  À Í À ÷‹|@ý€7x@‡€ŸÍ Ž úÎeÎE‡ " ü‡æ¾ ÛÆçÀèþÁâþÉÉ‹þÉ È-lÿöÉÉ‹þÉ ðÂeÂ-RÿôéàNÿàHÿàÉ‹þÉ Û‡÷^?‡Àsys/buf.h´È l LØš¿sys/conf.h´” зËNsys/file.h´— з!ÅWsys/filsys.h´µ з"-Ôsys/ino.h´ з$ñsys/inode.h´�l ùÛ&–csys/param.h´c™ T¤*5©sys/proc.h´Él )á/É"sys/reg.h´ з2øúsys/seg.h´l Já3#Ðsys/systm.h´Õ Ñ·5·lsys/text.h´| Ñ·9­Lsys/tty.h´  Ñ·:Ýãsys/user.h´ l rá?$ sys/run´„m ÉE„Èsys/lib1´²è ·ÛGÎ×sys/lib2´r¹Y ¡€¼m`ken/alloc.c´Âk 1åfCken/clock.c´2 l jâ%£nken/fio.c´zk :å+î¼ken/iget.c´/l „Ü4!ken/main.c´¿%=Hàken/malloc.c´qk GåF‘Úken/nami.c´h l ºÜJ�Bken/pipe.c´’ k QåQÃ6ken/prf.c´ýl AÝX5Óken/rdwri.c´Žk Zå] aken/sig.c´/l ÂÞeq»ken/slp.c´Š$m hrYsken/subr.c´u k iå…Ÿken/sys1.c´l ¬ßŒªAken/sys2.c´"l ÎßšfKken/sys3.c´è k {å£ëXken/sys4.c´=l †à©„Zken/sysent.c´Sk „å±ûµken/text.c´„ k Šå¶'+ken/trap.c´Äl Ÿà½ágetd.c¶ v’jgÍø@misc/getd.doc¶ oÐ åÕw·sys/dmr/dj11.c¶ çR “0×hsys/dmr/tty.c´ þ)R �0áu’sbrk.s´ gn ë&öy{/* * Each buffer in the pool is usually doubly linked into 2 lists: * the device with which it is currently associated (always) * and also on a list of blocks available for allocation * for other use (usually). * The latter list is kept in last-used order, and the two * lists are doubly linked to make it easy to remove * a buffer from one list when it was found by * looking through the other. * A buffer is on the available list, and is liable * to be reassigned to another disk block, if and only * if it is not marked BUSY. When a buffer is busy, the * available-list pointers can be used for other purposes. * Most drivers use the forward ptr as a link in their I/O * active queue. * A buffer header contains all the information required * to perform I/O. * Most of the routines which manipulate these things * are in bio.c. */ struct buf { int b_flags; /* see defines below */ struct buf *b_forw; /* headed by devtab of b_dev */ struct buf *b_back; /* " */ struct buf *av_forw; /* position on free list, */ struct buf *av_back; /* if not BUSY*/ int b_dev; /* major+minor device name */ int b_wcount; /* transfer count (usu. words) */ char *b_addr; /* low order core address */ char *b_xmem; /* high order core address */ char *b_blkno; /* block # on device */ char b_error; /* returned after I/O */ char *b_resid; /* words not transferred after error */ } buf[NBUF]; /* * Each block device has a devtab, which contains private state stuff * and 2 list heads: the b_forw/b_back list, which is doubly linked * and has all the buffers currently associated with that major * device; and the d_actf/d_actl list, which is private to the * device but in fact is always used for the head and tail * of the I/O queue for the device. * Various routines in bio.c look at b_forw/b_back * (notice they are the same as in the buf structure) * but the rest is private to each device driver. */ struct devtab { char d_active; /* busy flag */ char d_errcnt; /* error count (for recovery) */ struct buf *b_forw; /* first buffer for this dev */ struct buf *b_back; /* last buffer for this dev */ struct buf *d_actf; /* head of I/O queue */ struct buf *d_actl; /* 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 flags are kept in b_flags. */ #define B_WRITE 0 /* non-read pseudo-flag */ #define B_READ 01 /* read when I/O occurs */ #define B_DONE 02 /* transaction finished */ #define B_ERROR 04 /* transaction aborted */ #define B_BUSY 010 /* not on av_forw/back list */ #define B_PHYS 020 /* Physical IO potentially using UNIBUS map */ #define B_MAP 040 /* This block has the UNIBUS map allocated */ #define B_WANTED 0100 /* issue wakeup when BUSY goes off */ #define B_RELOC 0200 /* no longer used */ #define B_ASYNC 0400 /* don't wait for I/O completion */ #define B_DELWRI 01000 /* don't write till block leaves available list */ ccurs */ #define B_DONE 02 /* transaction finished */ #d/* * 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; int (*d_close)(); int (*d_strategy)(); int *d_tab; } bdevsw[]; /* * Nblkdev is the number of entries * /* * One file structure is allocated * for each open/creat/pipe call. * Main use is to hold the read/write * pointer associated with each open * file. */ struct file { char f_flag; char f_count; /* reference count */ int f_inode; /* pointer to inode structure */ char *f_offset[2]; /* read/write character pointer */ } file[NFILE]; /* flags */ #define FREAD 01 #define FWRITE 02 #define FPIPE 04 (*d_close)(); int (*d_strategy)(); int *d_tab; } bdevsw[]; /* * Nblkdev is the number of entries * /* * 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 unmount (sumount/sys3.c). * A disk block is ripped off 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 (0-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]; }; ze; /* size in blocks of entire volume */ int s_nfree; /* number of in cor/* * 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 0100000 #define IFMT 060000 #define IFDIR 040000 #define IFCHR 020000 #define IFBLK 060000 #define ILARG 010000 #define ISUID 04000 #define ISGID 02000 #define ISVTX 01000 #define IREAD 0400 #define IWRITE 0200 #define IEXEC 0100 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 0100000 #define IFMT 060000 #define IFDIR 040000 #define IFCHR 020000 #define IFBLK 060000 #define ILARG 010000 #define ISUID 04000 #define ISGID 02000 #define ISVTX 01000 #define IREAD 0400 #define IWRITE 020/* * 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 01 /* inode is locked */ #define IUPD 02 /* inode has been modified */ #define IACC 04 /* inode access time to be updated */ #define IMOUNT 010 /* inode is mounted on */ #define IWANT 020 /* some process waiting on lock */ #define ITEXT 040 /* inode is pure text prototype */ /* modes */ #define IALLOC 0100000 /* file is used */ #define IFMT 060000 /* type of file */ #define IFDIR 040000 /* directory */ #define IFCHR 020000 /* character special */ #define IFBLK 060000 /* block special, 0 is regular */ #define ILARG 010000 /* large addressing algorithm */ #define ISUID 04000 /* set user id on execution */ #define ISGID 02000 /* set group id on execution */ #define ISVTX 01000 /* save swapped text even after use */ #define IREAD 0400 /* read, write, execute permissions */ #define IWRITE 0200 #define IEXEC 0100 le is used */ #define IFMT 060000 /* type of file */ #define IFDIR 040000 /* directory */ #define IFCHR 020000 /* character special */ #define IFBLK 060000 /* block special, 0 is regular */ #define ILARG 010000 /* large addressing algorithm */ #define ISUID 04000 /* set user id on execution */ #define ISGID 02000 /* set group id on execution */ #/* * tunable variables */ #define NBUF 30 /* size of buffer cache */ #define NINODE 150 /* number of in core inodes */ #define NFILE 150 /* number of in core file structures */ #define NMOUNT 5 /* number of mountable file systems */ #define NEXEC 3 /* number of simultaneous exec's */ #define MAXMEM (64*32) /* max core per process - first # is Kw */ #define SSIZE 20 /* initial stack size (*64 bytes) */ #define SINCR 20 /* increment of stack (*64 bytes) */ #define NOFILE 15 /* max open files per process */ #define CANBSIZ 256 /* max size of typewriter line */ #define CMAPSIZ 100 /* size of core allocation area */ #define SMAPSIZ 100 /* size of swap allocation area */ #define NCALL 20 /* max simultaneous time callouts */ #define NPROC 50 /* max number of processes */ #define NTEXT 40 /* max number of pure texts */ #define NCLIST 500 /* max total clist size */ #define HZ 60 /* Ticks/second of the clock */ /* * priorities * probably should not be * altered too much */ #define PSWP -100 #define PINOD -90 #define PRIBIO -50 #define PPIPE 1 #define PWAIT 40 #define PSLEP 90 #define PUSER 100 /* * signals * dont change */ #define NSIG 20 #define SIGHUP 1 /* hangup */ #define SIGINT 2 /* interrupt (rubout) */ #define SIGQIT 3 /* quit (FS) */ #define SIGINS 4 /* illegal instruction */ #define SIGTRC 5 /* trace or breakpoint */ #define SIGIOT 6 /* iot */ #define SIGEMT 7 /* emt */ #define SIGFPT 8 /* floating exception */ #define SIGKIL 9 /* kill */ #define SIGBUS 10 /* bus error */ #define SIGSEG 11 /* segmentation violation */ #define SIGSYS 12 /* sys */ #define SIGPIPE 13 /* end of pipe */ /* * fundamental constants * cannot be changed */ #define USIZE 16 /* size of user block (*64) */ #define NULL 0 #define NODEV (-1) #define ROOTINO 1 /* i number of all roots */ #define DIRSIZ 14 /* max characters per directory */ /* * structure to access an * integer in bytes */ struct { char lobyte; char hibyte; }; /* * structure to access an integer */ struct { int integ; }; /* * Certain processor registers */ #define PS 0177776 #define KL 0177560 #define SW 0177570 * end of pipe */ /* * fundamental constants * cannot be changed */ #define USIZE 16 /* size of user block (*64) */ #define NULL 0 #define NODEV (-1) #define ROOTINO 1 /* i number of all roots */ #define DIRSIZ 14 /* max characters per directory */ /* * structure to access an * integer in bytes */ struct { char lobyte; char hibyte; }; /* * structure to access an integer */ struct { int integ; /* * 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 SSLEEP 1 /* sleeping on high priority */ #define SWAIT 2 /* sleeping on low priority */ #define SRUN 3 /* running */ #define SIDL 4 /* intermediate state in process creation */ #define SZOMB 5 /* intermediate state in process termination */ #define SSTOP 6 /* process being traced */ /* flag codes */ #define SLOAD 01 /* in core */ #define SSYS 02 /* scheduling process */ #define SLOCK 04 /* process cannot be swapped */ #define SSWAP 010 /* process is being swapped out */ #define STRC 020 /* process is being traced */ #define SWTED 040 /* another tracing flag */ ng on low priority */ #define SRUN 3 /* running */ #de/* * 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 TBIT 020 /* PS trace bit */ 4 /* process cannot be swapped */ #define SSWAP 010 /* process is being swapped out */ #define STRC 020 /* process is being traced */ #define SWTED 040 /* another tracing flag */ ng on low priority */ #define SRUN 3 /* running */ #de/* * KT-11 addresses and bits. */ #define UISD 0177600 /* first user I-space descriptor register */ #define UISA 0177640 /* first user I-space address register */ #define UDSA 0177660 /* first user D-space address register */ #define RO 02 /* access abilities */ #define WO 04 #define RW 06 #define ED 010 /* extend direction */ /* * structure used to address * a sequence of integers. */ struct { int r[]; }; int *ka6; /* 11/40 KISA6; 11/45 KDSA6 */ /* * address to access 11/70 UNIBUS map */ #define UBMAP 0170200 and bits. */ #define UISD 0177600 /* first user I-space descriptor register */ #define UISA 0177640 /* first user I-space address register */ #define UDSA 0177660 /* first user D-space address register */ #define RO 02 /* access abilities */ #define WO 04 #define RW 06 #define ED 010 /* extend direction */ /* * structure used to address * a sequence of integers. */ struct { int r[]; }; int *ka6; /* 11/40 KISA6; 11/45 KDSA6 */ /* * address to access 11/70 UNIBUS map */ #/* * Random set of variables * used by more than one * routine. */ char canonb[CANBSIZ]; /* buffer for erase and kill (#@) */ int coremap[CMAPSIZ]; /* space for core allocation */ int swapmap[SMAPSIZ]; /* 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 lbolt; /* time of day in 60th not in time */ int time[2]; /* time in sec from 1970 */ int tout[2]; /* time of day of next sleep */ /* * The callout structure is for * a routine arranging * to be called by the clock interrupt * (clock.c) with a specified argument, * in a specified amount of time. * 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. * One allocated on every mount. * Used to find the super block. */ struct mount { int m_dev; /* device mounted */ int *m_bufp; /* pointer to superblock */ int *m_inodp; /* pointer to mounted on inode */ } mount[NMOUNT]; int mpid; /* generic for unique process id's */ char runin; /* scheduling flag */ char runout; /* scheduling flag */ char runrun; /* scheduling flag */ char curpri; /* more scheduling */ int maxmem; /* actual max memory per process */ int *lks; /* pointer to clock device */ int rootdev; /* dev of root see conf.c */ int swapdev; /* dev of swap see conf.c */ int swplo; /* block number of swap space */ int nswap; /* size of swap space */ int updlock; /* lock for sync */ int rablock; /* block to be read ahead */ char regloc[]; /* locs. of saved user registers (trap.c) */ char runout; /* scheduling flag */ char runrun; /* scheduling flag */ char curpri; /* more scheduling */ int maxmem; /* actual max memory per process */ int *lks; /* pointer to clock device */ int rootdev; /* dev of root see conf.c */ int swapdev; /* dev of swap see conf.c */ int swplo/* * Text structure. * One allocated per pure * procedure on swap device. * Manipulated by text.c */ struct text { int x_daddr; /* disk address of segment */ int x_caddr; /* core address, if loaded */ int x_size; /* size (*64) */ int *x_iptr; /* inode of prototype */ char x_count; /* reference count */ char x_ccount; /* number of loaded references */ } text[NTEXT]; lks; /* pointer to clock device */ int rootdev; /* dev of root see conf.c */ int swapdev; /* dev of swap see conf.c */ int swplo/* * 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 */ }; /* * A tty structure is needed for * each UNIX character device that * is used for normal terminal IO. * The routines in tty.c handle the * common code associated with * these structures. * The definition and device dependent * code is in each driver. (kl.c dc.c dh.c) */ struct tty { struct clist t_rawq; /* input chars right off device */ struct clist t_canq; /* input chars after erase and kill */ struct clist t_outq; /* output list to device */ int t_flags; /* mode, settable by stty call */ int *t_addr; /* device address (register or startup fcn) */ char t_delct; /* number of delimiters in raw q */ char t_col; /* printing column of device */ char t_erase; /* erase character */ char t_kill; /* kill character */ char t_state; /* internal state, not visible externally */ char t_char; /* character temporary */ int t_speeds; /* output+input line speed */ int t_dev; /* device name */ }; char partab[]; /* ASCII table: parity, character class */ #define TTIPRI 10 #define TTOPRI 20 #define CERASE '#' /* default special characters */ #define CEOT 004 #define CKILL '@' #define CQUIT 034 /* FS, cntl shift L */ #define CINTR 0177 /* DEL */ /* limits */ #define TTHIWAT 50 #define TTLOWAT 30 #define TTYHOG 256 /* modes */ #define HUPCL 01 #define XTABS 02 #define LCASE 04 #define ECHO 010 #define CRMOD 020 #define RAW 040 #define ODDP 0100 #define EVENP 0200 #define NLDELAY 001400 #define TBDELAY 006000 #define CRDELAY 030000 #define VTDELAY 040000 /* Hardware bits */ #define DONE 0200 #define IENABLE 0100 /* Internal state bits */ #define TIMEOUT 01 /* Delay timeout in progress */ #define WOPEN 02 /* Waiting for open to complete */ #define ISOPEN 04 /* Device is open */ #define SSTART 010 /* Has special start routine at addr */ #define CARR_ON 020 /* Software copy of carrier-present */ #define BUSY 040 /* Output in progress */ #define ASLEEP 0100 /* Wakeup when output done */ fine TBDELAY 006000 #define CRDELAY 030000 #define VTDELAY 040000 /* Hardware bits */ #define DONE 0200 #define IENABLE 0100 /* Internal state bits */ #define TIMEOUT 01 /* Delay timeout in progress */ #define WOPEN 02 /* Waiting for op/* * The user structure. * One allocated per process. * Contains all per process data * that doesn't need to be referenced * while the process is swapped. * The user block is USIZE*64 bytes * long; resides at virtual kernel * loc 140000; contains the system * stack per user; is cross referenced * with the proc structure for the * same process. */ struct user { int u_rsav[2]; /* save r5,r6 when exchanging stacks */ int u_fsav[25]; /* save fp registers */ /* rsav and fsav must be first in structure */ char u_segflg; /* flag for IO; user or kernel space */ char u_error; /* return error code */ char u_uid; /* effective user id */ char u_gid; /* effective group id */ char u_ruid; /* real user id */ char u_rgid; /* real group id */ int u_procp; /* pointer to proc structure */ char *u_base; /* base address for IO */ char *u_count; /* bytes remaining for IO */ char *u_offset[2]; /* offset in file for IO */ int *u_cdir; /* pointer to inode of current directory */ char u_dbuf[DIRSIZ]; /* current pathname component */ char *u_dirp; /* current pointer to inode */ struct { /* current directory entry */ int u_ino; char u_name[DIRSIZ]; } u_dent; int *u_pdir; /* inode of parent directory of dirp */ int u_uisa[16]; /* prototype of segmentation addresses */ int u_uisd[16]; /* prototype of segmentation descriptors */ int u_ofile[NOFILE]; /* pointers to file structures of open files */ int u_arg[5]; /* arguments to current system call */ int u_tsize; /* text size (*64) */ int u_dsize; /* data size (*64) */ int u_ssize; /* stack size (*64) */ int u_sep; /* flag for I and D separation */ int u_qsav[2]; /* label variable for quits and interrupts */ int u_ssav[2]; /* label variable for swapping */ int u_signal[NSIG]; /* disposition of signals */ int u_utime; /* this process user time */ int u_stime; /* this process system time */ int u_cutime[2]; /* sum of childs' utimes */ int u_cstime[2]; /* sum of childs' stimes */ int *u_ar0; /* address of users saved R0 */ int u_prof[4]; /* profile arguments */ char u_intflg; /* catch intr from sys */ /* kernel stack per user * extends from u + USIZE*64 * backward not to reach here */ } u; /* u_error 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 ENT 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 #defchdir ken cc -c -O *.c ar r ../lib1 rm *.o chdir ../dmr cc -c -O *.c ar r ../lib2 rm *.o chdir ../conf as m40.s mv a.out m40.o : as m45.s : mv a.out m45.o : cc sysfix.c : mv a.out sysfix cc mkconf.c mv a.out mkconf mkconf rk tm tc done cc -c c.c as l.s ld -x a.out m40.o c.o ../lib1 ../lib2 : as data.s l.s : ld -x -r -d a.out m45.o c.o ../lib1 ../lib2 : nm -ug : sysfix a.out x : mv x a.out cmp a.out /rkunix cp a.out /rkunix mkconf rp tm tc done cc -c c.c as l.s ld -x a.out m40.o c.o ../lib1 ../lib2 : as data.s l.s : ld -x -r -d a.out m45.o c.o ../lib1 ../lib2 : nm -ug : sysfix a.out x : mv x a.out cmp a.out /rpunix cp a.out /rpunix mkconf hp tm tc done cc -c c.c as l.s ld -x a.out m40.o c.o ../lib1 ../lib2 : as data.s l.s : ld -x -r -d a.out m45.o c.o ../lib1 ../lib2 : nm -ug : sysfix a.out x : mv x a.out cmp a.out /hpunix cp a.out /hpunix rm mkconf c.c l.s a.out *.o : rm sysfix x a.out cmp a.out /rkunix cp a.out /rkunix mkconf rp tm tc done cc -c c.c as l.s ld -x a.out m40.o c.o ../lib1 ../lib2 : amÿmain.oÛ ì¶ô견w üÿ7 øÿÄôÿÄe߀ÿ ÿ ß À ß · Òÿææß –%„ ê÷%F¸ÿ Ä%>À Wt p€ðÀ 0 ‚ðÄeïÁŽÿWpWtüÿNæß Ö Î ß Îß ÎLß Îzß ÎæRÿß Ö 7HÿÎDÿæ@ÿæß –%À2ÿ®ÿߎÿ÷fÿ ÿÎÿß À%ÿÿ÷`õ ÿÎÿß À%ÿÿÎ’ß ÷òþþþ÷úþ÷•äþ÷Õßþ÷ÿÿMÒþ÷ Îþ÷ Êþ÷ ÆþÎæ¾þß Ö 7´þÿÅ®þÎæ¦þß Ö 7âþÿÅÜþ÷ ’þÀ Îß  & æ& ß ÆeÎ& æêß –%÷ ^þwZþw VþÀŽþÄŠÃÀÿ÷%(@þÄåÃåÃ% ÿ†€`#ùÀ`þÄ íĪàÿ÷%( þÄåÃåÃ%€ÿ†#Ë5³à öwèýw äýõ ÷%(Øý_ÄNß ÔÀ%_ÄNß Ô&f÷ ‚Ö €eÀ%_ÄNß Ô&f÷ `Ö &f÷ TÖ €e€eÀ%_Ä@@m@mÀeÀ-\ý_Ä ÃjŠõ%€ ÒÄe€õå€óõ  @tÀeÿÀUõ Ã%zƒ  úÄõ%€ ÒÄe€õå€óõ  @tÀeÿÀUDmÃ%zƒ  úõ Ã%Šƒ  úDmõ%€ Äå€õå€â#óõ  À€@ítÀU"Àe€ÿ#õ ÃjÂzÃ%zƒÒûʚÃ%šƒÒû÷ æý ÷• müÀÿÿw,üw (ü@Àetùÿwü ‰ ÿ /etc/initmem = %l RESTRICTED RIGHTS Use, duplication or disclosure is subject to restrictions stated in Contract with Western Electric Company, Inc. no clock9yÙXx(ˆYèèèèè8Yi8ˆÙ))H))HˆÙ©©©©¨ )™©¹9ÈII9È Ùø9I9 Y YI9Y I9I_u "_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _proc L_text �_inode € _ka6 _icode#ê_main"~mainipcsv L2_fuibyte L3B_clearse _mfree L4nL5LL6nL7hL8_printf L9 L10L11LL12z_min _fuiword L13 L14 L15’_panic _cinit _binit _iinit _iget _newproc L16ž_expand _estabur"_copyout L1¢_sched cret _sureg"¦~sureg¦uprpaL18ÊL19ÊL20ØL21èL22L23L24L25L17~estaburapnddpntnsasep L27bL28Ä_nseg"ÔL29�L30´L31ÎL32èL33úL34îL35úL36þL37L386L396L40BL41TL42HL43TL44XL45rL46’L47¼L48 L49ªL50²L51¼L26Ð~nsegÔnL52æalloc.ol Œá¶|ô8w üÿææôÿÀ�ñÿtø –%ÎæÞÿß Ö Îÿÿß ÷‹ÿÿÎôß Î&æß –%Îß 7¤ÿ÷žÿœÿ4Š˜4Š™4Š›7œ†ÿ7ž‚ÿw|ÿw xÿæ Nß äΦÿ¦Îe˜ß Ö ò‹˜õò Iò €À €`5øÿ?Nføÿ¦ß –%À éò !²Š˜Nøÿfß Ö òÎd¦Îeæß –%ß 2Š˜ŽÎe˜ß Nøÿfß Ö ß ò•šw¼þ2 Næúß Ö ÷•Ûþ ðw œþNß äô•šÎ¦ÿ&Îe˜ß Ö ô‹˜õNf&ß –%À ;ô ô4 ô%d#´Š˜Nfß Ö ÂÎd¦&Îeß –%4 Îß 4Š˜Îe˜ß À ´ apô•šwæýw âýDCÀeÀ ‡- ‚Næß Ö Àw´ý üw ¬ýÆåNß äΦÿ&Îe™ß Ö ô‹™õ*ô ÎÎÀ a5ÐòÿNòÿfß Ö  ƒÃe €ÀeÀ ú‡ô•š€w<ýò íŽß ô ÎÓ´Š™5 òÿ5 øÿKNøÿÎefß Ö Â5 öÿµ òÿ@öÿÀ €`È %5 ôÿ@ôÿtp-@ôÿtp-òÿµ ôÿõ%dôÿêÎÀ ´ ÎapòÿÐô%dÎõeöÿõ%öÿÌÎß ô%dε øÿ5#øÿ²4Š™Îe™ß ô ΞNæ ß Ö ÷•�ü_ w PüNß äô‹™ô%dÎ ÎÀ ´ ÎapÐô•šwüw üÄô L-ÎÃ%d‡Â%d †Næß Ö 4 4 Î ÄeÄ%Ú‚Î%ß w¼ûw ¸û÷ ´ûQ· ®ûÃó *Àô‹š#ô‹™ ô‹˜ô‹›Îæß Ö 4ŠšônûœôjûžÎ¦&ß –%Žß ÃeÃ%΂Ä̵ ÌÕÎ&ß Ö ß Äe Ä%€ í‚7 ûÎÿÿß w ûiinitno spacebad blockOut of inodesbad countno fsY))˜)hx ¨¸È©)©yyÙYˆh¸ÈØxèÙ Yˆx¸èØÙYÙYˆxÙèhøøÈØ YÙY¨¨¨ÙYii¨xyy¸è¨øxH X øih Ù_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _bdevsw _nblkdev _cdevsw _nchrdev _buf h_bfreeli _inode € _u "_iinit"~iinitcpbpcsv _bread _getblk L2BL3ô_panic _bcopy _brelse cret _alloc"„~alloc„bpipfpdevbnoøÿ_getfs"äL5¦L20001–_sleep L9¬L10D_badbloc"L11"_wakeup _clrbuf L4@L12ú_prdev _free"`~free`fpbpipdevbnoL14†L20003vL13L16°L17þ_bwrite ~badblocfpbnabnafpdevL100006L19LL20L18H_ialloc"P~iallocPfpbpipiøÿjöÿkôÿdevinoòÿL22tL20005dL24ÐL20011|_iget L26ÄL20018 L21ÀL20009¤L28®L20007¬_iput L30zL20017äL20015L35ZL20013L384L34hL31€L40 _ifree"¬~ifree¬fpdevinoL41à~getfsän1n2pdevL20020ìL45.L10002L47*L48L42@L49%_update"D~updateDipmpbpL50ðL20022VL53°L20024¾L57Ú_iupdat _prele _bflush iget.ol ¨á¶¨ ´ôw üÿæ ÌÕΦÿ&ß Ö µõ Ä5-(5-$̵ä̵Â2!åÂeÂ%ø‚뫧 ´ŠÌÕÎ»ß ÷•»ÿ w~ÿ ô‹Äe Ä%€ É‚„éttÌ•´ŠôÿÿÎfÎeß Ö fß Ö Ê5Žß ß ,ÉÎfÎeß Ö t€l5øÿÃeSøÿõeøÿÀeÀ ö‡Žß Ÿw ÐþDô¥ÌÕô‹ ß 24 &ß Ö Î&ß „Ö ß Š4 ôŠß w|þw xþÆåBʵLŽß ð‹›E€Àe5öÿÎföÿß Ö ¦ß Ö 5øÿÎföÿß Ö tAøÿ@lƒÃeÔ€ÀeÀ ú‡ÊµÔøýÔöýÄeʵTõeTNøÿß wÎýw ÊýÆåDô5 pÀe5[ý Uô5HN&ß Ö ÂÂe5Ê 1Àe@-%Ž&ß Ö 5øÿÀe5öÿ ý öÿNöÿ&ß Ö õåöÿ@øÿp-öÿí†ß Ž&ß Ö ÂåÂ,ȃÎß N&ß Ö = õåÀe@-Ÿ†ôE4Š 4 ÌÕwÖüw ÒüÀ6ýß  w¼üÌÕ@ÀU€4ô•ô�Úü ô�Õü ß pèw Œü@7ÚüÄZÃHÔ”Ã%Vü‚÷¬ü÷•œü÷XžüÎÄüß Î¼üß ,wLüno imtInode table overflow ™È¨¨¨8ˆ™©¨ÈØøø™¨xÈÈ©™hÈØyyÈ©™ØØøø©™™X©™™™™˜˜˜™™˜™™è™©_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _u "_inode € _bdevsw _nblkdev _cdevsw _nchrdev _buf h_bfreeli _iget"~igetipip1øÿip2pdevinocsv L2$L20001_sleep L20013L20005*L6‚L8bL20003JL13´_panic L20011jL1~L20007nL16»_printf L20008|cret L5Ž_ldiv _bread L17ê_brelse _iput",_lrem L18L20010~iput,rppL21vL22^_itrunc"2_ifree _iupdat"„_prele ~iupdat„tmrpbpøÿip1ip2iöÿpL23._getfs L25ôL20015òL27L28L29&_bwrite ~itrunc2iprpbpcpdpøÿepöÿL30&L31L20021RL33L35ðL36äL20019zL38àL40ÔL41ÂL20017¨L43¼_free _maknode"*~maknode*modeip_ialloc L46DL45@_wdir"p~wdirpipcp1cp2L20023†_writei prf.ol Óá¶à~.xw üÿCÃe 1Žß ´@µ ’Â%%óBŸµ Â%dÂ%lÂ%o Â%oÎÎ æß vÖ Â%sÄŽß ´•ûÃeÒwŠÿw †ÿNfß Ö N&ß vÖ Nfß Ö Îe0ß ´wLÿw HÿDß xÿ ß5€tÿüÄ Ãtÿ tÿvÿÄ% Î ß ´Îß ´Îß ´ ß ´ßtÿwúþw öþwðþ÷ ìþNæ~ß Ö ÷ Úþýw Ôþ@�@�&fæ‰ß Æew´þw °þD æšß (Ö Nf&æžß Æew‚þpanic: %s %s on dev %l/%l errbn%l er%o %o ©y©Èèy©y©y™É©y©y_ka6 _buf h_bfreeli _bdevsw _nblkdev _cdevsw _nchrdev _panicst _printf"~printfxaxbxccsadxfmtx1x2x3 x4 x5x6x7x8x9csv L3L20001 L1r_putchar"´L10000@L5XL10001LL10002P_printn"vL6lL7hL20003bcret ~printnvban_ldiv L10˜_lrem ~putchar´rccsL11L12ÂL14ø_panic"~panics_update L16~L17"_idle _prdev"(~prdev(devstrL20‰_deverro"L~deverroLbprbpo1o2L22šL23žrdwri.ol Þá¶ð JLw üÿÆåB÷ 0_4ÊÕ€ÀEÿŸÀ% ¦�œWp ù Ö _4Î÷ÿæBß Ö 5ôÿ5öÿÀìÿÀEþ5òÿÎÜÿæNíòÿß ’Ö €ÀEÿŸÀ%`#ξÿæ¸ÿ¦ €œ &ÎEÿß ÆeHæß ’Ö Nöÿ¦ß Ö 5ôÿ9„„@ôÿ€ 7*ÿ€€ @-öÿ Îÿfôÿ&ß –%Nôÿ&ß Ö 5øÿröÿÎæfòÿføÿß ¬ÆeNøÿß ÷‹ ÿ÷ ÿ…wÈþw ÄþÆåBÊÕ€ÀEÿŸÀ% ¦�œWp ù Ö _t÷ Ðþ_tÎ÷ÿæBß Ö ÀºþÀEþ5ôÿΪþæNíôÿß ’Ö 5öÿ€ÀEÿŸÀ%` Î¦ß Ö X„„õ%öÿÎ&ß Î&ß Ö 5øÿ föÿfôÿføÿß ¬Æe÷‹/þNøÿß ÷5ÿ*þNøÿß Nøÿß Îþæ þ¦ €œ &ÎEÿß ÆeÀ ò5 ò�æý òâý ÊÕ÷‹Ëý÷ Îý�wˆýw „ýu-†@wtý@ûw jýu-ƒ@wZý@ûw PýC@Dm÷‹rý*ÀQÀ]pýÀ5#õ Î&æ\ýß ÎæPý&ß –%÷•j7ýwüü÷`6ýÎæBß Ö ÷à(ýóõ Àà À ì÷ Ôüè”�öÀà À â•ß À öÛ¹hè(ùùXx˜©¹hè(¨x˜ø©¹©¹©¹x˜©Èù_inode € _u "_buf h_bfreeli _bdevsw _nblkdev _cdevsw _nchrdev _canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _readi"~readibpøÿbnôÿonòÿdnipnaiplbnöÿcsv L14L5>_lshift _min"’L6È_dpcmp _bmap L7ÖL8ô_breada L20000_bread _iomove"¬_brelse cret _writei"8~writei8bpøÿdnonôÿbnipnöÿaipL11lL10tL14vL15ÊL16ÎL17à_getblk L20002èL19L20.L21&_bawrite _bdwrite L23d_max"x~maxxabL25ŒL24ˆ~min’abL27¦L26¢~iomove¬bpanflag cpnotL29L30è_copyin L20004ô_copyout L32L28_dpadd L374L34 _cpass _passc slp.ool áâ¶b w üÿÃþÿÄ0õ %÷ êÿÀ ÷ âÿtÌ•t�÷ Îÿ÷‹Êÿ7ŠÄÿÎß ~÷ €÷ ´ÿÀ ÎÚß w¤ÿ÷  ÿtÌ•t�÷ Œÿ÷ Pßþÿíw ~ÿCÄÂ2ô ß ¤Äe‰~w\ÿw XÿD4 Ì•ô­Hÿ·Š@ÿ÷‹<ÿ ôµ7Š.ÿÎß ~w"ÿw ÿD�ÃEÿ×tüÿ�Àed`Ã%ÃÀ�öþÀ ·Šîþô�wæþw âþæ ·ŠÚþΜÿæß Ö ÷ ÈþÂÿÿÄÌ¥ ôµ�€ 5øÿ�ÄeÄ%Lì‚Â%ÿÿ·ŠŽþΜÿæÙ÷ €þDøÿô‹ mÎæß Ö J÷ TþÄ�ÀEøÿÀ%Ì¥.Ì¥+ÄeÄ%Lî‚Â%¤ÂÿÿÄ�ÀEøÿÀ%̥̥�€ 5øÿ�ÄeÄ%Læ‚Â%ƒDøÿ÷ ÜýôÅ æ&ß –%_4@øÿô‹ Î&æ&ß ÆeÀ ,ôm´Š DøÿÎ&æ&ß ÆeÀ Àetýÿ&æß –%ôôÕ4Š_4Îbß w8ýw 4ý÷ ¦÷žÎß Î*ýß 7Šý†7 ‚ÀÄ2ÂeÂ%L‚ÂÊ¥ òµ€œÀ ·Rƒœ÷ H·B÷ Èü×Â8÷�¾üŽß ÷ ²üòµòÅÎÞß Àw”üw �üÆå5 ôÿ7 ‚ü· ~üûÄÌ‹õ ôÿ5ôÿô-fü ðÄeÄ%Lð‚DôÿÎmß Ã‚üõòÿÌ•ô•ôœôôô"ü ô 4ŠÃªÄ´ŠÃ%Èù‚@òÿ´Š´Š À4ü°ŠÎß Dôÿ7üCòÿÂõøÿ´Žæß Ö 5öÿË•tøÿÎÞß  & &ß –%ôÕË•÷Æû w„ûtöÿ€ À ôNöÿµ öÿføÿµ øÿß Ö ðw ZûÆåÄŽû5öÿtu-öÿ ÎNmföÿNíæß –%?Îß Næß Ö ÎÞß Nöÿæ&ß –%ôÕ÷ ¬ý´5 øÿ Ž‚ æNmøÿß Ö µ øÿu-öÿøÿòÎföÿæß –%ß ÷ ¢úwžúswap errorno procsi ‰©¹ùùø‰)©¹i)i)  )i))iùø© ¹HH©¹ÈøøX8)i¸È))È9)iééé8 é ¸ HH¸È )¨i H¸HH¸È¨HÈ9)_u "_proc L_text �_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _file _inode € _buf h_bfreeli _sleep"~sleepchanrpspricsv L2\_issig L3P_spl6 _spl0 L4D_wakeup"~_swtch"ÈL5x_aretu L1Xcret ~wakeup~chancipL9ŽL10š_setrun"¤~setrun¤rppL12ÀL11Ú_setpri"Þ~setpriÞuppppL15L16_sched"~schedp1øÿrpanL184L19"L20003.L20001@L22^L24|L25˜_malloc L27<L20005°L30ÊL31 L20007âL34 L10001ü_xswap L36pL37l_swap L38¼_mfree L39b_panic ~swtchÈL41vrpipvnL42Ø_savu _retu L43èL46üL47 L44(L50:_idle _sureg L51d_newproc"l~newproclupòÿnpôÿriprppa1øÿa2öÿL53~L20009zL20011ˆL58–L59¶L60mL20013îL61öL64L65|L66rL67‚_copyseg _expand"¢~expand¢newsizeiøÿnöÿpa1a2L70àL69^L71L72:L20015&subr.ol üá¶Œ æ°w üÿÆå@5öÿõ5€÷•S@ð5/õ5øÿLNöÿß C5 ôÿ@ôÿÀ @m@ôÿÀ @m0 µ ôÿõ%ôÿì@0ß @ðU@tøÿ5ôÿõ5øõôÿ@ôÿÀ @mBýÕNöÿß 0 w2ÿ@À @mNöÿß ß @À @m°ýÕ7 ôþõ%@À @m7Üþ€Ñ@ôÿÀ @m0Žföÿß Ö õ%ôÿ4@tøÿÀEÿÀeùÿ5ôÿÀ À`Nöÿß 5øÿß ¡@ôÿÀ À`AøÿHß ß Žföÿß Ö 5øÿDøÿ@ÀEÿ5ôÿÀ À`Nöÿß 5øÿ@ôÿÀ À`ˆNøÿß ß ß 7 úýõ%ÿôÿ‹@ôÿÀ À`7äýƒw Þý÷‹þ�þ÷ þ· þ· þ· þý÷ üýÀÿÿw²ý@�ææýß Ö À æ÷•jÏýî îw Žý÷ ÊýÀÿÿÄŸ¼ý÷ ºý· ºý· ²ý· ªýÀEÿwbý÷‹”ýíΖýß é÷•j�ýàw Dý÷•uýw:ýw 6ýw2ýw .ýDCB‚~wý¹Y(y(ùù¸ø(ø¸((øùù¹YYYYYYYyYÈY¹YYYYYYyYYhY¹Yy¹y¹y_bdevsw _nblkdev _cdevsw _nchrdev _inode € _u "_buf h_bfreeli _canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _bmap"~bmapipbnbpnbdöÿiôÿbapnbpøÿcsv L2"L20005ÈL9ŒL4Î_alloc L20004J_bdwrite L12¦L13:L14(L1Êcret L10L11$L15H_bread L16¼L17žL18†_brelse L19´L20üL21_passc"~passccL24NL25.L27<L10000jL20006FL23J_subyte _cpass"n~cpassncL29žL20009xL28šL20008~L31‚L33�_fubyte _nodev"¸~nodev¸_nulldev"Æ~nulldevÆ_bcopy"Î~bcopyÎcounttofromabcL39Þtext.ol =â¶D l<äw üÿDõ 5Àetýÿæß Ö Îlß ß <ôÕ f&æß ÆeÀ Î~ß õ  fæß –%ôôÅ4Š÷‹pÿ7ŠjÿÎß w^ÿw ZÿÀ’ÿ$0 ß <ôŠô‹ó54 Àetýÿ&æß –%ËÅ Îß wÿw ÿ÷ Æÿ_8 Äà Äe Ä%�ƒô õt-ô´ŠÀÿ0aÄÎ‰ß ô•4Š tÂlÿÂe?—túÿÂEü´€Àetýÿæß Ö Î•ß ŽÎeß  & ¦& ß Æe÷ÿ�þ÷Žþ7 „þNß ÃvþóÕ ¦æÎe&ß ÆeóÅ3CËÕ ³ŠÎß ô‹ Îß ÎÞß  ææþß –%ÀþðÕ÷ Ìý´Š wÄýw ÀýDô‹ ôŠ ô‹ &æß –%w”ýout of swap spaceswap errorout of textout of swap spaceI(h˜¸˜øÙÙØ)I™(øˆ)I™¸¸™˜™(h˜˜¨™™™™¸™¸˜˜Ø˜Ø™™é)Iø)_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _u "_proc L_text �_inode € _xswap"~xswapffosrpapcsv L2_malloc L38L4l_panic _xccdec"<_swap L5fL6~L7~_mfree L1ž_wakeup cret _xfree"¢~xfree¢ipxpL9ø_iput _xalloc"ü~xallocüiprpxptsL138L14L20001L16L15>L21L22JL23‰L24�L25•_expand _estabur _readi L264_savu _swtch ~xccdec<rpxpL27htrap.ol Gâ¶D VPw üÿ÷ øÿ@ÀEÿÀ%ðõU@Àe 7ð@Àå ‚À x&ÎÂÿæJß Ö NÎeæTß Ö Næ^ß Ö Îlß Ä æÄÿß Ö ÷ ~ÿÀ ÷ vÿήÿß wjÿNÎeþÿß À% ð÷ >èÄßÄÜÄÙÄÖ7ŠmÿõENÎeþÿß ÂEÀÿ—tÂeÂ%)Nß õeÎß ÀE?À%‰Ä?ÂEÀÿ—tÂe „"ÃeÎß Á 1È„ ó Nß Á 1Èõe„ „"ò÷bÿîþŽß è÷‹¬ÿ÷•»þ÷¥dµþ÷‹¯þ_~õUÀ�Ÿþ5 _~Ä _rÎæŒþß Ö _’Ä_rCÎLÿß À Îß À _~Ä _rw þ÷•.ÿÎÚß ý 7Šÿwúýw öý÷•d'þwìýw èýwäýþ÷øùúý¨:::::::n–´º:ÀÆ:ºÂka6 = %o aps = %o trap type %o trapIY™¹ˆˆˆÈ™è )™8Yh™™hÈÈh˜È˜˜h˜™™™™™™™™è™(HI™˜x™YI™YIY_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc#_u "_proc L_ka6 _sysent _trap"L10002&L29¨L5:L10nL11–L13´L14ºL15ÀL16ÆL30ºL31Â~trappcsppsaidevcallpnps r1r0 csv _savfp L2L6J_printf L7TL8^L9l_panic L3r_psignal L12~_issig L33Š_psig _setpri L1’cret _fuiword L10000®L17B_fuword L18L19(L22bL23^L20001F_trap1"èL26|L27 _backup L32à_grow ~trap1èf_savu _nosys"~nosys_nullsys"~nullsyssig.ol ëá¶Ü*Pw üÿÄt-N&ß *Ö ÄeÄ%Lñ‚wÖÿw Òÿõ%Dô¥ t�Ì¥dÌ•dÌ¥ß wžÿw šÿÃÒÿÄœ óµ ÷ ÄœÄ  wrÿÀ ð5â÷ôw `ÿß Ë•÷ Pÿóµ÷ À Ãxÿó% Äô, åÄeÄ%L÷‚÷ ÿwÿw ÿÂJÿ„œ2ŠÀ â57Š/ÿÄ%Ä%À 0 âÀöÿúÿÄeüÿß jÀäÿ&Îeß Ö ÀÐÿ&ß Ö ÀÀÿ0úÿÀ¸ÿðEÀ®ÿðÀå ‚À x7Dÿ÷ À Äe€À‚ÿtQ7*ÿ÷ ^þwZþw Vþ7Љþ÷8¢þÎæß Ö  ÷‹mþI릧 C΀æß Ö À 5ó5`1÷­FþBþ-Îß 7 @þ7 >þ÷2þ÷.þ÷•þÎß ÀþÄeðÿ & && ß Æe7 þt7øý7ŠêýÎß Îß ÷‹Ûý wœýÀûw ’ýÀdþ t@-†Î@@ &ß Ö Ãí@þÃeà Î6þæ0þÎ`æ(þæ"þß ÆeÀ  w>ýÀvýÎ`ß ÀhýÁ`ý@lÂðýÄ &Îàß Ö Â Â öÂÄ ß Â Â ù÷`ÄýÀÓw äü÷ ¬ýÀýðÕRÄÌ¥ ô-Œý Àøü0- ÄeÄ%Lî‚÷•Ûü:÷ žüÎÿÿæß Ö õ7 †ü÷˜ý†üÀFýÀE7xü÷<ýpüôÅ ß Îÿÿæß Ö ÷ PüöÿNü\ý÷ Dü÷•qü7 6üÎß w*üw &üÀ^üð-ü  wüÄü7 üÎß Àå ƒ_ À x(Îîûß À%ÿÿ_ ÎÜûß 7ÖûÚÎÎûß À%ÿÿeÎÀûß ñĶû]Ä%Z€ À 7¤ûÁ æšûß Ö À KÎŽûæˆûß Ö ± æzûß Ö À ;Înûæhûß ïÃ^ûƒ à ÃeÃ%‚Ã%6 ‚ „ Ä% "�À ÀmFüÀ õÀ>üÀeÀ ÷Uð û÷EàûËû_æÀDûð� ûÀ_è÷ öú÷ÿÿòú_怀€€€€�€€€2Jd„¢ôcore)¨¨i)èi)™i˜)Øé™¨¨9i)™˜™˜™™ø™ø™™™™™™9i)™™hx™¨¸™™Ø™™˜™™™è™ø™™™è™i)™˜™™™™™øi™È™™™ø(™)™™¨™™¨™ÉÈÈəəəÉèÈÈÉəəÉÈØi)™ÉiÉÉÈØÉ É ÉÉ8 ÉH ɘÉÉX ÉÉX ÉøÉÉøÉ˜˜˜ˆ™™ÉÉÉ™É9É_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _u "_proc L_inode € _ipc _signal"~signaltppsigcsv L20001L4_psignal"*cret ~psignal*rppsigL6^L7HL8R_setrun _issig"b~issigbnpL20004„L12Ž_stop"œL10ŠL20003ˆ~stopœcpppL16ÀL20006¢_wakeup _swtch L15æ_procxmt"ÖL17âL20008Ð_exit _psig"êL10001L35€L25�~psigêrpnpL23nL24_grow"j_suword L22¢_core"¦~core¦ipsL388_schar _namei L39ØL20012^_maknode _access L42R_itrunc _writei _estabur _iput L10002dL37`~growjsispaiL20020¼_ldiv L46ÂL43¾_expand L47øL20017è_copyseg L50 L20019_clearse _ptrace"~ptracepL54.L53ÒL200222L57LL59^L60t_sleep L61®L20024 L63ÆL10007(L68L702L71JL72dL73„L74¢L80ôL81~procxmtÖipL65ìL20025æL64èL69 _fuibyte _fuiword L20028,_fubyte _fuword _suiword L20029€L10005ºL75ÔL76ÀL20027¾L79ìsysent.ol 4â¶ (8HXhxˆ˜¨¸ÈØèø(8HXhxˆ˜¨¸ÈØÈèøÈ(8HÈÈXhxˆÈ˜¨¸ÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈ_sysent#_nullsys _rexit _fork _read _write _open _close _wait _creat _link _unlink _exec _chdir _gtime _mknod _chmod _chown _sbreak _stat _seek _getpid _smount _sumount _setuid _getuid _stime _ptrace _nosys _fstat _stty _gtty _nice _sslep _sync _kill _getswit _dup _pipe _times _profil _setgid _getgid _ssig clock.ol wâ¶P ,w üÿÿMöÿ÷ òÿ÷ òÿ2Ãó ÃeË ùË õ5à#÷ Êÿ÷ ÆÿÄ Ì &ü Ö Äeô ôà 3ÄeÃe3ô@ÀEÿÀ%ð · €÷ � Îfß Ö · h”ÿ²Šò‹òŠ· Fÿ÷%<@ÿ_šõ5àf÷å<,ÿ· *ÿ· "ÿ÷ ÿ÷-ÿÿ÷-ÿÿÎß ÷5ÿ·ŠúþÎß ÂÊ‹ò¥²Š€œÀEÿÀ% À �œàr�2Šò¥dŽß ÂeÂ%LÛ‚÷‹ þ7ŠšþÎß @ÀEÿÀ%ð@Àe 7�ÿ÷ vþÀ ÷ nþΦþß wbþw ^þæ BõþÿøÿÄ÷ JþŒ ãÄeô øŒàÃeó û óó óÃå!ôƒŒtt_øÿþÿwöýy‰™˜Ù™˜˜™™˜X™™iiiyy™‰y‰yˆ¸yéh¸¨(¨ÉÉȸ™Ii™(yy˜y_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _u "_proc L_clock"~clockpcppsppsdevnps r1r0 p1p2csv _display L2xL3$L20001L4(_spl5 L6TL20003BL7ZL8pL20005`L10 L12¤_incupc L13¶L1šL15Þ_spl1 L16ú_wakeup L17L20007L20RL22"L23@L24D_setpri L26n_issig L28’_psig cret _timeout"ž~timeoutžargsøÿtfuntimp1p2_spl7 L30ÂL20009¸L31ÈL32ÒL20011ÎL34îL20013Úfio.ool œá¶ ‚"¼w üÿC Ã%ÀÀ ªwàÿ÷•  ùw ÒÿD̵óE€ÎÎeß ÎÎeß ô¥ “ÎEýÿ&ß xÖ ôŠwˆÿw „ÿD�ô¥ÀEÿŸÁ‚7æ þyfæ�Wp ù –%ß w<ÿfæ€tø ñw &ÿD�ÀEÿŸÁŽ7œ þyÂ-þþfæ�Wp ù fæ€tø –%Â-Òþó÷•ÿwÆþw ÂþDCÃ%€ß ð‹›÷•×þ%÷•Ïþ!̵ ù÷‹Äþ Ã%@ô5I 7­ ªþ×týÿ7­ Ÿþ×týÿô0ï÷• ‹þÀwLþw Hþ æß Ö   7­ dþú÷ À öß wþw þ÷‹FþÀwþ÷•5þ ùw öý À ð ª?üþwàý„ Ä%ò÷• þÀÿÿôw Èý÷ Êÿ ÀÀ 0ª´Š4 4 w¢ýÄô‹îÄeÄ% ø‚Îšß ÷•·ýß `¨Äº `þ*6no file Éù ÉhhùÉHhù(ÉYH(9 ùÉè ùɨ¸ hùÉ ù É ù ÉùH _u "_file _bdevsw _nblkdev _cdevsw _nchrdev _inode € _getf"~getffprffcsv L2 L1cret _closef"*~closef*fpiprfpL5V_wakeup L6p_closei"xL10001‚L10002†L11¨L12ÄL8º~closeixiprwmajdevripL10003 L20000¸_iput _openi"ÖL10005ŽL10006’L16þL18*L136~openiÖiprwmajdevripL10007öL170L20001&L20003_access":~access:modeipmaipL20p_getfs L21jL20009¬L20006bL23ˆL10008„L24¦L19°L25 _owner"´~owner´ip_uchar _namei L29ÎL20014äL20011ÊL28æ_suser"ê~suserêL33üL32ø_ufalloc"~ufallociL20016 L37 L34_falloc"4~falloc4fpiL40^L20021@L39ZL20018DL20020bL45š_printf malloc.ol ¹á¶0Ühw üÿCK-‚ÄsmKíË ÃeóþÿóüÿøwÈÿÃeË å øw ¸ÿBDÌ Äe´ ù†D-†þÿmüÿ€ tmüÿ€@m-*4cüÿÌ &Äe4þÿ4üÿö€@m-Ì tíLmõ  ´ÂLÄeõów$ÿiÙiÙ_malloc"~mallocbpmpsizeacsv L2<L20001 L48L62L9"L14cret _mfree"D~mfreeDbpmpsizeataaL11ZL20003RL12`L14œL10ØL16ˆL19¸L24¾nami.ool ÃᶸhØw üÿÆåÄ:ý Ã%/Ääÿ&ß Ö ý Ã%/úà õ  ÷•ïÿ÷•çÿß _÷‹×ÿ÷à _ÀEÿŸÀ%@éÎ@&ß Ö À äÂH à ÷‹¡ÿ Â%VƒÒ�ý Ã%/ðŠÂ%Vü‚ý Ã%/ú÷‹oÿÃ7 vÿ7 pÿ÷•^ÿ5 øÿÎ& ß Ö 7Rÿ5 öÿ÷ Jÿ$õ öÿNöÿß õ%šà ˜Î€&ß Ö À —7Bÿõ øÿ@øÿÀeðÿ7 ÿŽÌÕ‹÷5ÿþþõ öÿNöÿß Îææþß Ö &ß Ö &ß Ö 5öÿÎæX@öÿ&À²þÀEþ`ß –%÷e þ÷ ˜þ÷ ¬þõ øÿŸõŒþøÿ›ÂHÀZÀåH€`ˆ¢’‚ Â%Võ‚õ öÿNöÿß õ%à ΀&ß Ö À _Pwöý5öÿß Î>þföÿß Ö _\_Vw ÌýÀŸþÀEÿ· þw¼ýw ¸ýÎ þ· þß Ä%ÿÿ÷•jÕýw˜ýiYˆø8¸ø8ø¸8HXø8©øˆi©i©_inode € _u "_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _buf h_bfreeli _namei"~nameiflagdpcpeoøÿbpöÿfuncccsv L2_iget L32L20001,L7\L20010BL6PL20014J_iput L20015VL1L20003_access L10¦L20005ŽL13°L12 L20007®L15¾L20009¸_ldiv L17òL18@L19_brelse L21:L23~L24V_bmap _bread _bcopy L25¼L20012ÀL30äL31 cret _schar"0~schar0_uchar"D~ucharDc_fubyte L35bpipe.ool Ëá¶´ø´w üÿæ Îöÿß #÷ êÿ(õøøÿ÷ ÜÿÀêðæüÿøÿÞÊ•2Ë•3ô•Ì•ô€w¤ÿ3Š@øÿÀ 0 ªß ów ŠÿD%ô 4 3 ó5€óE€ÎÎeß Îß Øó¥ óUÎæÎeß Ö Îß °ô, Ô7 fÿ7bÿÎß ôXÿÎß Øwÿw ÿDÂ8ÿÎß ° Îß Ø7 $ÿ Îß Ø÷• ÿÎ æ ÿß Ö wÄþó¥íó% óU€Îß ØÎæÎeß Ö Ï7 Ôþ÷ ÐþÎÎíÈþ¦ß Ö 7¸þàÎß Îß Øó5µóEÎÎeß ¬w LþDÌÕÎ&ß Ö ÌµõÌÕw(þw $þDÌÅ̵ÌÅß wþ))8Y™Y™™™‰˜˜)(X™™x™‰)™™™™(‰X™™™H™X()X‰)(‰_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _u "_inode € _file _pipe"~pipeiprfwfrøÿcsv _ialloc L1X_falloc L20001jL20003\cret _iput _readp"r~readprfpiprpL5ÊL20005€L7¦_wakeup _prele"ØL4ô_sleep _plock"°_readi _writep"ø~writepøfpiprpcL10L11<L98L20007_psignal L13j_min _writei ~plock°iprpL16ÊL20009º~preleØiprpL18ôsys1.ool â¶àÆ ,w üÿÆå æß Ö  _XÎÿÿæß Ö ÷%Ðÿõ· ÊÿÎÿÿß 5òÿÎ@æß Ö À _6ó5`_6@òÿ5 öÿ5 ôÿ$µ öÿÀ%ÿÿ_6÷eBNøÿµ øÿß Ä%ÿÿ_6‘µ ôÿõ%þôÿ÷•ƒÿ_6Ä æÎ ß 5øÿÕõ5ôÿе ôÿ÷È`ÿ÷\ÿ7 \ÿ7 Vÿ÷•DÿÎß 7Š:ÿ÷‹7ÿ_65 ìÿ÷%¸ÿO÷m´ÿ´ÿ7 ®ÿÀªÿÀe?túÿÀEü5ðÿÀ˜ÿÀm–ÿÀe?túÿÀEü5îÿNìÿæfîÿfðÿß ÆeÀ _67 ²ÿ÷ �þÎß Îß DîÿÄe$ß %µ ìÿ÷ 4ÿÂ˵ ¿ó¥»÷•‹þ_6÷% ÿë÷% ÿé÷•qþ_6Ànþaß Ä Ä%õ & fîÿ& ß Æe7 HþÀÐþÀe7Bþ÷Æþ8þÎß wðÿ¾þwîÿºþ÷¶þwìÿ²þήþæ¨þæ¢þæœþß Æe@òÿ@ôÿ AöÿÁ @àÀeüÿ5øÿÀ¶þpøÿúÿNöÿføÿß Ö @ôÿ õeøÿføÿß Ö €’&„ ß Ö Ò‹÷@öÿõ öÿÀ èÎÿÿføÿÎeß Ö Àxýðµó5 ÷‹`ý÷œ Xýðœ ó5÷œ EýÄÃâË5 ÃeÃ% ÷‚€”À Àmþý Â%ø‚Àòý0 à Ã%6ü‚Îß Nòÿß ÷%¶üÎß ÷ ¨üw¤üw  üÀ²ýt7\ý÷ wŒüw ˆüÀÀüðÅÄâÔÄ% û‚Ī Îß ÄeÄ%Èõ‚Θüß ÷ JüÎæß Ö ÎÆß Îæ*üß Ö Î¦æß –%Žß ÄBü&æß –%ô̕´, Îß Žß ´, ò Ê¥Žß ÂeÂ%Lî‚÷ ¦ûÂeÂ%LÚ‚ô Ôw �û ÂÀÂû°, n„ Ê¥L¿ †ü„æfûß Ö ææß –% Š2 2 2Š2 2ŠÂ·l@üŽæß Ö Ž æß Ö ·lüŽæß Ö Ž æß Ö Àü°ÈüÿÎß 1Ê¥òµ òÕ ¿ ÚûÀÖû�œWtÁUpüÿòÅ0Žß ÂeÂ%L‡‚Ä Î(æÈúß Ö _r÷• ³úwxúw túĬúÃË‹ ÃeÃ%Lù‚÷• �ú÷ RúÀ ? ^û7 Vû7 Tû7 Hû7 Fû7 Dû7 :û ÿ >ûÀÁ6û1`wúw úæ ÃÖúÃe?×túÿÃEü÷ ÖúÎÊúß tàà  ÂÂí¶úÀ´úÀe`άúæ¦úæ úŽ`æ˜úß ÆeÀ ·`Šú ÀêùÄ`ÄízúõøÿÃrú&Žàß Ö „ Àà À õNøÿß wxùÎß ÀªùÄ`Ã:úÄ &Žàß Ö Àà À õ€ À äÄ ß ÷out of swap©¸ÈXYY(™x™™˜˜™™™™™¸™™™™™™™™™è™ù™™™™™™hè™™™™™¸™™™™™™™™è™xx¸x™™™™˜˜ˆ™ˆ™˜˜(8YXXYi©™™i©™˜˜˜˜™(ù((X9˜hx™ˆ¨¨XX¨è¨ù¨©¨™™9˜(ˆ™˜¨˜¨™˜¨˜¨™8™™è¨™™i©™¨¨™Y™™™™™™™™™i©™™™ø™™™™™™è™™™™X i™™X h_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _u "_proc L_buf h_bfreeli _inode € _exec"~execapøÿnaöÿncôÿbpòÿdsîÿipcptsðÿcsepìÿcsv _uchar _namei L2*L1XL20001_sleep _getblk _access L46L5¼L20015tL7ˆ_fubyte L9¸_fuword L10Ø_readi L11°L16_estabur _xfree _expand _xalloc L17ØL20003ŽL12’L20005Ê_clearse _suword L19¢L20007~L23�_subyte L24ôL25æL20009úL30L20011L20013,_iput _brelse L36T_wakeup cret _rexit"\~rexit\_exit"t~exittapqL20017†L20019”L43 _closef _malloc L45ÐL46Æ_panic _bcopy _bwrite _mfree L47L20023L50ZL200212L54L_setrun _swtch _wait"l~waitlbpfpL58rL20025vL61^L63"_bread _dpadd L57„L65RL66~_fork"ˆ~forkˆp1p2L20027”L71ªL72Ø_newproc L73ÒL67ä_sbreak"è~sbreakèadiøÿnL75_nseg L76L74„L77ˆL78tL20029f_copyseg L80¬L20031žL82´sys2.ool â¶¼. <w üÿÎß wðÿw ìÿÎß wàÿw ÜÿCÎêß >̰÷• ùÿ8÷„øÿ÷€ôÿ7Šæÿ̵ Ã%ß ß 7Òÿ7ÊÿÃ%ß ß Î6Îí¨ÿ&Îeß Ö À"Àí”ÿ?fwLÿw Hÿ æß Ö  · þÿ æøÿ&ß $–%w"ÿw ÿÎæß Ö ÷‹?ÿÎÌÿÎEòß  ÎÎæ&ß $–%wÜþw Øþæ CBõ%Â5Îæß Ö Â5΀æß Ö ÀÀEÿŸÀ%@÷•Åþ÷‹Áþ'õ Îß Îß ÷ rþ€ÀEüÿ �ôõtÿøÿŽÎEýÿæß Ö ÷‹�þ @øÿÀ 0 ªôŠÎß w0þw ,þÎ>ÿß À2ÿÀ 0 ªß w þw þÆåÎÿß D̵÷•#þ=ðþÃ%À¤þt 5øÿÀ˜þtùÿ5öÿÃ%õEþöÿ õ~þøÿ5 öÿà õ øÿõÿÿöÿÀ ‚À x.5möÿfÎeöÿß Ö tøÿtöÿwlýœ ÀEÿ5`öÿ åw Ný æß Ö Aô¥÷•gý6ÀEÿŸÀ%@÷ ýÀ +ÌÅ÷ÚýdýÎæß Ö ÷•-ýÎß ÷‹#ýÀNý0-ß ÷• ýß ´ŠÌÕß w¸üw ´ü÷ °üÀ Îæß Ö ÷•Ëü ÷‹Åü ÎRýß ôHýß wpüw lüÆå÷ düõ`üöÿõ\üøÿÎjýfÎeöÿß Ö ÎFüæ@üføÿföÿß ÆeÀ ÷ (üw$üÎ"üæüæüæüß ÆeÀ Nøÿföÿæþûæøûß ÆeÀ wöÿæûwøÿâûÎZæß Ä„n”„né é é™x™™™™™™Èè™™(™™8™™™ éxˆ™™ éxˆ™™ éÈÈ™™ø™(™˜H é™x™˜˜ é™x™™™™™8 éxˆ™ ™™xˆ™H™™H™8H é xˆ™™™™H éÙyy™8yyø yy‰‰ø‰‰ø‰‰ˆH_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _u "_file _inode € _read"~readcsv _rdwr" cret _write"~write~rdwr fpmodem_getf L3°L4@L5lL6d_readp L8¤_writep L9ˆ_readi L10�_writei _dpadd _open"´~open´ip_uchar _namei L11Ú_open1"$_creat"Þ~creatÞipL13L12 _maknode L20003~open1$ipmodefpiøÿmtrfripL16rL17L_access L20ÆL21„_itrunc _prele _falloc _openi L15Ì_iput _close"Ð~closeÐfpL22ð_closef _seek"ôL10001.L29„L32nL33”~seekôfpnöÿtL23�L24L25FL27`L20007x_link"®~link®ipxpL36DL37ÒL38>L10002è_suser L39L400_wdir _mknod"H~mknodHipL42nL44†L41Œ_sslep"�~sslep�döÿ_spl7 L20008¶_dpcmp L20010Ü_spl0 L10003L48 _sleep sys3.ool #â¶$ øw üÿÎß Î´&ß LÖ wÞÿw Úÿ æß Ö  Î�&ß LÖ ß w´ÿw °ÿÎfß Ö Î@&Îeß Ö @&ß Ö Î@&Îeß Ö —tÂlÂe@Àe5 Nõefß Ö õe„ Ä%ï Žfß Ö õe„ Ä%óÎß wÿw üþÎß  ÷ ìþÀ 𪳊wØþw Ôþæ ÷ ”5øÿ÷‹ýþ"÷Šÿÿ æß Ö ô¥ ô5   Ãó  õ"øÿ ÷•½þß w|þ ÂÃeÃ%ê‚ î÷ 0ÿ& æføÿ@�ùÿtø –%÷‹{þÛÎføÿß Ö ÷‹eþÎß Ï2JøÿÎÿÿß 2΀&æß –%€2Š™2Š˜À²þÀEþÿ2�›Îß ÌÕß ¦w Èýæ ÷ Âý÷ „5øÿ÷‹íý;Ãó õ"øÿ ÃeÃ%õ‚÷•Ëý*Äô 5-øÿ÷•±ýÄe Ä%€ ð‚& føÿ@�ùÿtø –%ÄÌÅß Ä3 ß w:ýw 6ý æß Ö ÀÀEÿŸÀ%`÷•IýÄÀœÀ-ý÷•5ýÎß wòüY¹h¹™YØè¹™Yxxˆ˜¨ÈÈè™Y¹hI¸™Y¹¹¹Øè¨¹™¨¹è¹˜¹èXh¹èxYÙ¹¨¨¹È¹Èèè™YØè¹ù¹™_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _buf h_bfreeli _u "_inode € _file _bdevsw _nblkdev _cdevsw _nchrdev _fstat"~fstatfpcsv _getf L1_stat1"Lcret _stat""~stat"ip_uchar _namei L2H_iput ~stat1Lipubbpcpi_iupdat _ldiv _bread _lrem L20001¸_suword L20003Ü_brelse _dup"~dupfpiL10$_ufalloc _smount"(~smount(ipmpdøÿsmp_getmdev"ÆL11€L12tL20005hL16„L15ŠL20zL10000¢L10001¦L19Ü_getblk _bcopy _prele _sumount"4~sumount4ipmpdøÿ_update L21ÂL20007PL24\L25nL20009rL28ˆ~getmdevÆipdL30 L31îL32sys4.ool .â¶œ Z¸w üÿÿxÿ wòÿw îÿÿêÿþÀúðâÿüÿwÚÿw Öÿ÷ ÒÿÀ ÷àÈÿÀÚ7üÿÀÿÎß w²ÿw ®ÿÄŸÀ7¡àÿ÷  ÿÀ 7‘ÐÿÀÐÿ0‘7‘Æÿwˆÿw „ÿÿ�ºÿ”À�ð�®ÿwpÿw lÿÄŸ~7¡Ÿÿ÷ ^ÿÀ 7‘�ÿ7‘�ÿwNÿw Jÿÿ��ÿZÀVð�uÿw6ÿw 2ÿÀjÿ? >w$ÿw ÿ÷ ÿwÿw ÿÄ&Ä%ÄÄ ÷ þþÀ  À0ÿ0‘wìþw èþÎæß Ö 3Îß Î$ÿæß Ö ÎZß ÀEÿŸÀ%@÷ ¤þÀ ÷åÞþ÷XÒþ÷Îþ7 âþÎß ôŠÌÕÎß ß wlþw hþ æß Ö ÀEÿŸÀ%@÷•{þß Î@&ß Ö À ôÎnþß 7fþß wþw þ÷ þôEÿ÷‹8þ÷EÂþÀ¾þÀEð4PÌÕß wÞýw Úý÷ ÖýÀ ÷ Îý ô��þ ô�‹þ ÌÕß w°ýw ¬ýÄpþÄ%Ä% ÷•ËýÀ ?âžþÀ ðJþâÀ¶ýœ!Àªý0Šwfýw býæ 5 øÿÂnþÃ�ýÄÄ  ´  ô,Ä%†÷‹dý7­\ýµ øÿÎâý&ß Ö ÄeÄ%LÜ‚õ øÿ÷•3ýwøüw ôüÄ æ²ýß Ö ÷e¦ýÄ%ô‚wÔüw ÐüÀ”ýÀE7Üý÷ŠýØý÷†ýÔýÀ‚ý€ ÀE€7Èýw¦üunlink -- igeté ùé™ ™ùéI ™ ™¨hùé I ùé ùé I ùé ùé ùé™ùé I ùé8Hh x¨I  Øèèùé8H èX è hùé™ èùéI™ èùé   ùé ¸¸ ¸ ùé x ùé ù_u "_inode € _canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _proc L_getswit"~getswitcsv cret _gtime"~gtime_stime"&~stime&_suser L3J_wakeup _setuid"N~setuidNuidL10000dL5t_getuid"x~getuidx_setgid"�~setgid�gidL10001¦L8®_getgid"²~getgid²_getpid"Ê~getpidÊ_sync"Ü~syncÜ_update _nice"è~niceènL14úL15_unlink"~unlinkippp_uchar _namei L16�_prele _iget L17JL18Z_panic L10002`L19„_writei _iput _chdir"”~chdir”ipL20æL21ÄL22¼_access _chmod"ê~chmodêip_owner L23L24_chown""~chown"ipL25L_ssig"P~ssigPaL10003fL27nL26–_kill"š~killšaføÿpqL20001°L32îL10004¾L10005ÐL10006Þ_psignal L29_times"~timespL20003_suword _profil",~profil,ir"”~chdir”ipL20æL21ÄL22¼_access _chmod"ê~chmodêip_owner L23L24_chown""~chown"ipL25L_ssig"P~ssigPaL10003fL27nL26–_kill"š~killšaføÿpqmÿbio.ol ã¶4ˆ w üÿNfß "Ö Ì5wàÿÌUôÿ &@�tø Ö ß ìw ºÿB N¦ß èÖ À N¦ß "Ö Ì5 ÌUôÿ &@�tø Ö õ #N¦ß èÖ À N¦ß "Ö Ë5Îß ˆ ËUóÿ æ@�tø Ö Ä N¦ß Ö wÿß ùw ÿDÌEôÿ &� tø Ö Ã5ß ß ˆÃ5ß wÄþw ÀþD� tÃ%Ã%ß rÌUß ˆwŽþw ŠþDÌUß ôwxþw tþDÌ5@ß ÷5@^þ÷E@VþÎß Ì5ô•ÿÿ ÃÂþÿ÷ 6þÌEHÀ0ô ôŸþÿwþw þD@�tƒ s-3! Àwêýà ò øw Úý@�À-ÒýÎ4ß Ã÷ ¾ý÷%¾ý<÷U@°ýÎÎÿæß Ö ÷ žýõ é@�tÎ;ß ÄÄ Üt-t- ÷ fýÌ5ÌU@ÎÎÿ&Ö÷ Pýß LwDýà÷ :ýÄ<ýß LÌ5ÌUß ôÀ̈00ôôÀ03t tÌw ÞüD÷ ÖüÎÎÿ&ß Ö Ì5÷÷ ¾üß w´üw °üDÃþÿ÷ ¤ü00ÌUßþÿw„üw €üDÌ5 ß pÌUÌ5ß ˆÌE@ß wPüw Lü@à Â~w8üw 4üæ À72ü7,ü7&ü7 ü �WpDÄeôÿÿ �WpÁetôôôûÀîû07æûÌß ˆ‚ Â%Û õøÿ @øÿóó‚ õeøÿý øÿð·¤ûw ûw œûDCLää @ tÁÁEüÿWt@PÂUAË5ÂUÂU¤wVûw RûDC÷%FDûý Lää ÂÂEüÿ—tÂUAË5ÂU8ÂU0¤w ûw û÷%Fû5÷ úú ÷U@òúΜÿæß Ö ÷5Þúò÷UÖú÷ ÒúBÊU ƒÄÀ ð‚ðÄeÄ% ÷ƒ À ð‚ðÄeÄ%0÷òw�úw ŒúýE ÷5@€úÎß 7 rúwnúw júÄ÷ búÌU@Μÿ&ß Ö Ì5õ@ ÀU ÷<úDú@t 78úw8ú@t7(ú@töÿÀEÀÿ7úæÀútøÿtø Ö ÷ ðùΜÿ&ß Ö Ì5÷Ì5@ß ÷ ÌùÌEHÀEûÿw¾ùw ºùõ%ÿÿ5- ÌUß Lß ô÷ ”ùÄ–ùÌ5èÄ%ø÷ zùwvùw rùæ DæùÃ5_ ÷5˜ù_ ÀÀmŒùÀ ‡_ ÀúÀeÀE5øÿ÷ ú5 øÿ—túÿÂEüB-øÿ_ ÀÀmPùtúÿÀEüAøÿÁmÔù@ ‚ÀÀíÊù€ _ ÷ èøÌU@ÎÎÿ&ß Ö Ì5õ@ ÀU t ÀÀEÀÿ4÷ ŠùÀ°ÿÀ ÿ�WtùÿÁ @`�ÁE€ÿ@`Àt4`ÀtöÿÀEÀÿ4Î÷ÿæBß Ö 4À¢ø€ ÀE€ 4 4ŠÀŠøðÕ&ý Ö ÷ <øÎÎÿ&ß Ö Ì5÷À`øðÅÌ5@ß ÷ øÌEH À 7>øß ÷•j'øwì÷w è÷DÌ57�ø÷•øwÌ÷blkdevdevtab¹ù8¹88ù¹8ù¹8HXù¹ù¹¨))(¨(Ù(ù¹8ù¹Iø(Ù())(HY8øÙYùY)¹ÙHYù¹Ùù¹¨ù¹ù¹())))(()))8Iù¹ù¹¹ù¹¹Ùi h Hi i Yù¹i h ¨i ù¹8ÙH©999998©8ÙH¨Yù¹Ù)(Yù¹     ÙH Ø ÙH ¨Y  ù¹ ù_u "_buf h_bfreeli _bdevsw _nblkdev _cdevsw _nchrdev _canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _proc L_ka6 _buffers _swbuf _tmtab _httab _bread"~breaddevrbpblknocsv _getblk""L2 L20000cret _iowait"_breada"B~breadaBadevrabpdevrbpblknorablkno_incore"èL4ŠL6ÖL7¼_brelse"ˆL9êL3æ_bwrite"ô~bwriteôbpflagrbpL11,L108_geterro"_bdwrite"<~bdwrite<bpdprbpL10000\L15d_bawrite"rL14n~bawriterbprbp~brelseˆbpbackprbpspsL19œ_wakeup L20²L21¾_spl6 ~incoreèadevbpdpdevblknoL23L20002L25L22~getblk"bpdpdevblknoL30bL294_panic L20004:L32>L39ÂL20007X_sleep _spl0 L33~L34;L35‚L37¼L38¬_notavai"LL20008¶L40â~iowaitbprbpL428L20010,~notavaiLbprbpsps_iodone"|~iodone|bprbpL46�_mapfree"pL47¢L45¬_clrbuf"°~clrbuf°bpcpL52À_binit"È~binitÈbpdpibdpøÿL20012äL57RL200148L60J_devstar"`~devstar`bpdpdevblkdevlochbcom comrbpL62 L63¤_rhstart"ª~rhstartªbpabae dpdevblkdevloccomrbpL65ÄL66ìL67ð_maplock _mapallo"ö~mapalloöbpabpiaL68lL69L20016L20018>L74`L20020T~mapfreepbpL78Š_swap"’~swap’countfpcoreaddrrdflg blknoL80°L20022 L82L20024L840_bflush"B~bflushBbpdevL86hL20026HL10001XL89xL87|L20028r_physio"Š~physioŠstratbpbasenbrw abptsøÿdevL92 L93ÖL10002L94*L20030L10003VL10004Z_lshift L96ÒL20032ÆL98îL91~geterrobpabpL990tty.ol Åã¶Ð(š< w üÿÆåCÃeôÿÎß €÷‹ÄªÎ&ß Ö ÎÄe&ß Ö ÎÄe&ß Ö w¸ÿw ´ÿÄxß 7nÄeß 7bÄeß 7V ß €w€ÿw |ÿÎŽß ÀÀEÿŸÀ% ÷•�ÿ fæÁœWp ù –%w<ÿw 8ÿD÷ 0ÿ ôÕ@Î&Îe ß Ö ô òß <÷ ÿwÿw ÿÄÃeÃEËìþ÷èþÃeÃ%÷† „ Âe Ê û7ÈþwÄþw ÀþDÎeß À ùÎe ß À ùß Îe ß Ãþÿ÷ ˆþß À û4Šßþÿwrþw nþæ C÷ dþ óµ wTþÎ æß Ö ó‹ð÷ >þÄ6Ž•&ß Ö @ó5 'ô¥\ÿÿÀœ€ Ä% †Ä Àœ€ áÂ%ò‹(€œ(€ ó5ô¥\þÿ‚œ(Ä ”�Ä% ƒÎß Â%ÿÉóŠ5øÿÄÂÂeD-øÿ¶‚À£w šýBC„ÃE€ÿÃ% Ä5à Ä5 Ã%Ã%Ã%ÎÎ¦ß Ö Žß <4Ê%ùÄ5Ã%AÃ%ZÃe Žæß Ö Ä5 Ã% Ã% Žß Žæÿß Ö À ²ŠÄ5Žæß $Ö Žß ØwÜüw Øüæ CDÄE€ÿÄ%ó5 _„Ä% ó5 Îæ ß $Ö óµö_„ó5¶ҋ €”!ûÎæ\ß $Ö „œþÿÄ%aÄ%zÄeàÿÄ% ó5Îæ ß $Ö ÎÎe &ß Ö À ZÂÂe�5øÿ ÀEÀÿ B‚À x¨Ê‹=ÊŠ;ÀtøÿÀEüÿ5øÿÀ%ʋ΀’tüÿ&Îeß Ö õ%øÿÄ ŠÀtöÿÀEüÿ5øÿÀ% À�’ÁUøÿ@àÄ% ÊÕŠŠÄ ÎÎe &ÎU€ß Ö wxûó5@ïÄìÀtôÿÀEüÿ5øÿÀ%ÄÃõ%øÿ¿Ä ¼w <ûDôÅß Øw(ûw $ûB„òµŽÌ &ô5€"òµŽÎe ß Ã%ÀœÀEÿÀP4 ÎÎE€ÿ¦æÀß –%òÕw¾úw ºúDôµô ß ŽÀ ô  Îeß ß À ów€úw |úDôµ#÷ júß ØôÕ@Î&Îe ß Ö ô%2 î÷ @úæß $Ö ÷ 2úàß Øw$úw úDC �3�3Àwúùß ÄÃÈôô’ôœô í|#`{}@~ABCDEFGHIJKLMNOPQRSTUVWXYZlnðø<ˆ–({)}!|^~'`©™™ØØØé©™(™(™(™é©™x™é©é9é©8II8é©((HHé(é©éé9H(©˜HHHé©H¨¸ Hé©é©(¨¨ é©( é©é9É é©é˜_canonb _coremap È_swapmap È_rootdir _cputype _execnt _lbolt _time _tout _callout x_mount _mpid _runin _runout _runrun _curpri _maxmem _lks _rootdev _swapdev _swplo _nswap _updlock _rablock _regloc _u "_partab _proc L_inode € _file _bdevsw _nblkdev _cdevsw _nchrdev _maptab#(_cfree _cfreeli _gtty"~gttyupvpvôÿcsv _sgtty"€L1D_suword cret _stty"H~sttyHup_fuword ~sgtty€fpvip_getf L3ÀL4ª_wflusht"Ä~wflushtÄtpatp_spl5 L6èL20001Ò_sleep _flushtt"<_spl0 _cinit"ü~cinitücpccpcdpL9L20003L120L20005*~flushtt<tpatpspsL16D_getc L18R_wakeup L20x_canon"Ž~canonŽbpatpbp1øÿtpcL23¸L20007žL25¬L22¨L26ÂL274L20009È_putc L37VL29ÖL30,L31L32øL10000L36*L28H_ttyinpu"b~ttyinpubacatpct_flagstpL40†L41¸L10001˜L10002¤L10003¨_signal L20011°L39 L43ÔL10004ðL44 _ttyoutp"$_ttstart"ØL10007¨L61lL59nL63ðL65øL70<L73ˆL75–~ttyoutp$actpcrtpcolpctypeøÿL10005HL47„L48nL51VL52¤L53¶L54zL55”L58¾L66,L688_max L71hL76²_ttrstrt"À~ttrstrtÀatptp~ttstartØatpaddrctpL82òL81>L84&_timeout _ttread"B~ttreadBatptpL86|L88b_passc _ttwrite"€~ttwrite€atptpcL91ÊL90ØL20015’L93´L20013˜_cpass _ttystty"Ü~ttysttyÜatpavtpvL96L95dc.o.ol ã¶p4@xw üÿõ¥÷•%FD�uÄeC�×tÃeøôôÕËUAôµô•#ô•@ËIóIô•ôÈË5 ôÕÎ &ß Ö ôµöôÅÀ¬ÿð 0tw\ÿw XÿD�uÄe4Šô5üEß w0ÿw ,ÿ@�tÎeß wÿw ÿ@�tÎeß wüþw øþD�uÄeß ô ô% Îe ß wÊþw ÆþD�uÄeÂ5ôµüEôµÎ&ß Ö ß ôÅ(Â5€ôµôµÂ5ôÕß ÂEßÿ ô5@ ô5€æß Ö w$þw þD�uÄeN&ß Ö À �ÀEðÿÀ 4üüE�ÀEðÿÀ TðwÌýAIQYAIQY IxhIy xØy xy xXy x¨Øy xxˆØøy xhy_bdevsw _nblkdev _cdevsw _nchrdev _u "_partab _proc L_dc11 À_dcrstab#4_dctstab#T_dcopen"~dcopenflagaddrdevrtpcsv L2L1 L3dL5~L20001r_sleep cret _dcclose"¤~dcclose¤tpdevL9Æ_wflusht _dcread"Ð~dcreadÐdev_ttread _dcwrite"ê~dcwriteêdev_ttwrite _dcxint"~dcxinttpdev_ttstart L10000(L122_wakeup _dcrint"6~dcrint6tpcdevcsrL15ˆL16€L17z_signal _flushtt L14ØL10001–L18²L19ªL10003ÂL10002Î_ttyinpu _dcsgtty"Ü~dcsgttyÜavtprdev_ttystty L210L22L23dn.o.ol :ã¶xܰw üÿC�ÄÄ Äe€úôµ�÷•ßÕ€úÌ•EwÒÿw Îÿ@�À ðÅûÿ€úw¾ÿw ºÿD�Ä Äe€úÎæ€úß Ö Ìµ€öÌÅ€ôµÀ÷•¿ÿw„ÿ̵ û ÷ ¸ÿë̵è÷ lÿäÃ%-Îæß Ö Îæß Ö ×ÀÀeÐÿ4�ÌÕÊw 0ÿ΀úß w$ÿ¹Ié¹é¹˜IéIÙø˜ø˜¹8é_bdevsw _nblkdev _cdevsw _nchrdev _u "_dnopen"~dnopenflagdprdevdevcsv L2 L1*cret _dnclose".~dnclose.dev_dnwrite"B~dnwriteBdpcdevL8`L20001R_sleep L10jL11|L5x_cpass L12¼_lbolt _dnint"Ì~dnintÌdev_wakeup dp.o.ol Cã¶Ì¨lw üÿ÷ ÷-.øÿ÷•%÷èÿ7Šâÿ÷ ØÿÎÿÿß 7Êÿ7Æÿ÷•<ÅÿÎ<& æÜß –%ß•ûùßBøùßaüùw˜ÿw ”ÿ øù üù7Š�ÿ7 Œÿ÷ €ÿÎzÿß 7 rÿwnÿw jÿÀfÿÃ÷ Xÿ÷¥Yÿ÷ Lÿ Îæß Ö ÷ 8ÿ÷ ‚À  !è†Îæáæ`ÿ÷ ÿ–%&& æÿß Æewÿw ÿ÷ >ÿ#÷ FÀ ÷•ôþÀêþ7äþ÷%ÿ†÷ÿ÷ÿÒþ æÿ& æÂþß Æe÷ Rw²þw ®þß5üù÷ ¢þ÷•ÑþÀß5üù ÷ ˆþ w‚þ÷ ~þ÷‹€þòÎæß Ö ÷ fþÛw `þ÷• aþ÷ ZþÄŸRþ· NþÄE€ÿ�@ ÀEÿQ�þùÀ2þ7.þ7Š.þw$þw þ÷‹#þ÷Šþ÷ †÷•þÎ<& æÜß –%wöýw òýÄ—úùÄE€ÿ÷‹ìýß5øùÄU€ÀÔýÀeÀ-Êý†?‘Äý· Àýwºýw ¶ýÄüùßE€àüùÄ5À÷  Ä5€÷¥šý÷ *ÿwŠýw †ýßEøù÷¥€ý ÷• yý7ŠtýÀjý7fýÎß wXýÉyIyIIyyyyyy(9Éyyyyxy9Éyxéy x( IIyX9ÉIyyyIIIyIyX9ÉyI 9éyx( Éyyyyhyyy9Éyyy(9Éyyyyy9Éy9Éyyyyyxˆ9_bdevsw _nblkdev _cdevsw _nchrdev _u "_buf h_bfreeli _dp11 _dpopen"~dpopenflagdevcsv L2L1dL3R_getblk _dptimeo"Ü_timeout cret _dpclose"h~dpclosehL4Ž_brelse _dpread"’~dpread’bpeppL7ÈL20001¤_spl6 L9¶_spl0 L6ö_sleep _dpwait"N_min _iomove _dpwrite"ú~dpwriteúbpL10JL11,_dpstart"œ~dpwaitNL13RL10000`L15~L12zL20003lL16ˆ~dpstartœcL18Ê_partab L17Ø~dptimeoÜL20L21ö_dpturna"v_dprint" ~dprint cL22BL24(_dpxint"F~dpxintFdpstatL27`L26r~dpturnavL31œ_wakeup kl.ooY x¶|`¬w üÿõ¥÷•%8C�×tÃeÀð ðsD�uÄepÿõ‹ÄeÈýõ¥ÄeHþ3óµ ó•óó•#ó•@ÌUCôU@wxÿw tÿD�uÄeß 4ŠwZÿw Vÿ@�tÎeß w@ÿw <ÿ@�tÎeß w&ÿw "ÿD�uÄeß ô ô% Îe ß wôþw ðþB�—tÂeƒÄËUÄ53Ž&ß Ö wÀþw ¼þD�uÄeN&ß Ö w þéIxIYéx¨YéxèYéx(Yéxx¨Yéx(YéxˆY_bdevsw _nblkdev _cdevsw _nchrdev _u "_partab _proc L_kl11  _klopen"~klopenflagaddrtpdevcsv L2L1„L34L4JL5VL6zcret _klclose"ˆ~klcloseˆtpdev_wflusht _klread"¦~klread¦dev_ttread _klwrite"À~klwriteÀdev_ttwrite _klxint"Ú~klxintÚtpdev_ttstart L10000þL10_wakeup _klrint" ~klrint addrtpcdevL132_ttyinpu _klsgtty"@~klsgtty@tpvdev_ttystty mem.ol vã¶dFÈw üÿÆåõ¥AÎúÿæBß Ö Â ÂEÀÿõ ÿøÿõ€ÿöÿ÷ Èÿß ÿ߀ÿõ¥ÀtùÿÀEøÿÀ Àm¦ÿôÿÁÁE€ÿ@` ÿŽß _øÿ ÿ_öÿ€ÿ÷ ~ÿ÷‹±ÿß À ¿wjÿw fÿÆåõ¥Ä–ÿ7 ’ÿ7aŒÿæBß Ö w>ÿÎúÿæBß Ö ÂnÿÂEÀÿ÷ "ÿî÷‹Qÿëõ ÿøÿõ€ÿöÿ÷ ÿß ÿ߀ÿõ¥ÀtùÿÀEøÿÀ ÀmæþôÿÁÁE€ÿ@` ÿ¦ß Ö _øÿ ÿ_öÿ€ÿ÷ ¼þ¾é )YHY hyé y 9 )YXY_u "_bdevsw _nblkdev _cdevsw _nchrdev _ka6 _mmread"~mmreadbnoncaøÿdöÿdevcsv L1’L4_lshift _spl7 L5j_fuibyte _spl0 _passc cret _mmwrite"–~mmwrite–bnoncaøÿdöÿdevL8Â_dpadd L6¾_cpass L10*_suibyte pc.ol ƒã¶ÔÐ$w üÿõ ÷ òÿ÷•!÷âÿ÷%ÜÿßAhÿÎæß Ö ñßU@lÿ÷ vw¶ÿw ²ÿõ ÷ ¨ÿÎß À ú hÿ7 ”ÿ÷ �ÿ÷ Fw†ÿw ‚ÿ÷ ~ÿ÷%vÿß5€ˆhÿßUAhÿÎæß Ö Îß èß À õ÷ >ÿw:ÿw 6ÿß t÷ *ÿùw"ÿw ÿß5€lÿÎß nÿwÿw þþ÷%øþß5€hÿ!÷èþ÷%âþß5€hÿ÷ÒþÎæjÿß Ö ÷%ú¾þßUAhÿÎß w¨þw ¤þ÷ ~ÿ÷%2¢þÎß wŒþw ˆþß5€lÿ÷•±þ÷%dzþÎ(æß Ö Îfß Ö ÷ Pþ÷ *ÿ÷ HþwDþw @þÄd ß tw0þ©YIYYø)©‰X¨Y¹)©‰YXX¨H¹)©¹)©X¨)©YYYYXhYXx)©YXx)©IYXXh‰¹)©)_bdevsw _nblkdev _cdevsw _nchrdev _u "_pc11 _pcopen"~pcopenflagdevcsv L2<L3L1FL4_lbolt _sleep _pcleade"¼cret _pcclose"J~pccloseJflagdevL8r_spl4 L9X_getc _spl0 L7v_pcread"z~pcreadzcL16¨L20001„L18¾L19š_passc _pcwrite"Æ~pcwriteÆcL21ÒL20003Ì_pcoutpu"t_cpass _pcstart"Þ~pcstartÞcL23ú_pcrint"þ~pcrintþL26L25TL280L29L_putc _wakeup _pcpint"X~pcpintXL31p~pcoutputcL34ˆL33¸L35ž~pcleade¼iL39Ärf.ol Šã¶t*w üÿDÌ5ß � € t -‡ÌUß 4 ÷ Èÿ÷ Êÿ7ÄÿÀÀÿ07¸ÿ÷‹¬ÿ÷ ÷ ¢ÿwžÿw šÿÄœÿ·Š�ÿ�8ÿ t&æ6ÿ&ß Æewjÿw fÿ÷‹bÿ$Äbÿ7ŠXÿß 0ÿÎ8ÿæ0ÿ&ß –%ß0ÿ·Š9ÿ÷¥ 3ÿ ÌU7Š)ÿ7(ÿß ÷ zÿwÿw ÿÎfææß Æewôþw ðþ fææß ÆewÖþÙø9yyyyy‰™ÙyyØ™Ùyyy8yyyy™Ùˆˆ™Ùˆˆ™_buf h_bfreeli _bdevsw _nblkdev _cdevsw _nchrdev _u "_rftab _rrfbuf _rfstrat"~rfstratbpabpcsv L2_mapallo L30_iodone L1^_spl5 L4DL5LL6Z_rfstart"b_spl0 cret ~rfstartbbpL7’_devstar _rfintr"–~rfintr–bpL8èL9Ô_deverro L20000ä_rfread"ì~rfreadìdev_physio _rfwrite" ~rfwrite devrk.ol ’ã¶4ªÐw üÿæ DÌ5ß � Àeùÿ5øÿõøÿAøÿWp-‡ÌUß 4 ÷ ´ÿ÷ ¶ÿ7°ÿÀ¬ÿ07¤ÿ÷‹˜ÿ÷ t÷ ŽÿwŠÿw †ÿÆåD� Àeùÿ5öÿ� 5øÿNöÿæß Ö 5øÿNöÿæß Ö ÁÀ r fÁÀ r t€UAøÿWt @Pwÿw ÿÄÿ·Šÿ &÷ ~ÿÖ &æ ÿ&ß Æewòþw îþ÷‹êþ(Äêþ7Šàþß ÿÎÿæÿ&ß –%ßÿß5€ÿü·Š¹þ÷¥ ³þ ÌU7Š©þ7¨þß ÷ zÿw”þw �þÎfææß Æewtþw pþ fææß ÆewVþ (XyyyyyyÉÙ xˆÙ yyÈÙ yyy(yyyyXÙ ˆˆÙ ˆˆÙ_buf h_bfreeli _bdevsw _nblkdev _cdevsw _nchrdev _u "_rktab _rrkbuf _rkstrat"~rkstratbpqcqldøÿabpcsv L2_mapallo L3*L4D_iodone L1r_spl5 L5XL6`L7n_rkstart"â_spl0 cret _rkaddr"v~rkaddrvbpbdøÿmöÿpL9žL10¼_lrem _ldiv ~rkstartâbpL11 _devstar _rkintr"~rkintrbpL12hL13T_deverro L14<L20000d_rkread"l~rkreadldev_physio _rkwrite"Œ~rkwriteŒdevtc.ol ªã¶ôòôw üÿNß @ÀEøÿ0Šwäÿw àÿDÌ5ß ô%Bƒ ÀEøÿð‹ÌUß 4 ÷ ¦ÿ÷ ¨ÿ7¢ÿÀžÿ07–ÿ÷‹Šÿ÷ ÷ €ÿw|ÿw xÿ 7vÿË•ÌUß ÃâþÄ^ÿ' ÀEøÿð‹éÀœÀEøÿ� @ Ë•÷•/ÿ÷•(ÿ� —tÂUCß5€àþÂU÷• ÿ‹wÿw ÿÃâþÂàþÄúþË5€6Ê5„ ¦&ß –%Ê5 ÀEøÿ°Š7ŠÇþËE€÷Š¿þ ÌU7Š´þ7´þ!÷ ,ÿ!Ë5÷•šþËE÷•ŽþËUË•Cw‚þÂèþÀ�zþÀå õ‚À xòß•âþß ë -ᇠ-Ø‚"" ÀEüÿtÌ5ÁÁ @PÀUA �÷•þË€Àe-¾‡·¤äHÉØˆéÉHˆx™yyyyyééÉyxyˆyyyéÉyHˆyyyyyyéyxy_bdevsw _nblkdev _cdevsw _nchrdev _buf h_bfreeli _u "_tctab _tcper _tcclose"~tcclosedevcsv _bflush cret _tcstrat"~tcstratbpabpL30_mapallo L10000FL4R_iodone L2€_spl6 L5fL6nL7|_tcstart"„_spl0 ~tcstart„bpcomtccmpL9 L20001ŠL11–L8øL12ÌL13ö_tcintr"üL10004òL29¤L30äL19H~tcintrübptccmptcdtpL15~L16$_deverro L17:L18ZL27–L28œL23lL21`L22vL14zL10001ÐL10002Ôtm.ol ´ã¶�  hw üÿD�ô‹÷•# ´ŠÀ 0 À ðÿÿwÐÿw ÌÿD�4Šõ Î&ß ^Ö Î&ß ^Ö w¢ÿw žÿÎæß Ö ÷‹Šÿöß5€Rõò@t@]ÀU`Rõwhÿw dÿD� à Ãe -‡ - ƒÌUß ß !Ì5öÌ5€ 4 ÷ ÿ÷ ÿ7ÿÀÿ07 ÿ÷‹þþ÷ ÷ ôþwðþw ìþæ ÌU7äþß ÄÚþW� 5øÿÀ @øÿð‹éß5€RõåtÁEüÿWt@PÃU@`-÷•Žþ-ƒÃU €í ô ÃUÃU €àTõßRõ÷•Vþ À TõVõÌ5À÷‹7þÀ ÀÀPRõw þw þÄþJ� ß Rõ(ß5Zõüß5€ÄPõ÷¥öý ·Šñý÷¥ ëýÀÀ ° 7ŠÜý*Ä%ß5@Põó•ÿÿÌU÷•¼ý÷¥¶ý7бýÀÀ ° 7¨ý7Šžýß ôTõÀÀ 0÷ ’þw~ýw zýNß ÞÎfææ˜ß ÆeÀlý 7�ýwLýw HýNß Þ fææ˜ß Æe7 fýw"ýw ýD�Î÷ÿæBß Ö À ðƒ À ðwôü˜i˜¨¸I˜I(yI¸ÈØ yyyyyYIyØy¨˜yyyIyyyy¨yˆ˜yyy¨yyبIˆX‰iIˆXiIhب¸I_buf h_bfreeli _bdevsw _nblkdev _cdevsw _nchrdev _u "_tmtab _rtmbuf _t_openf _t_blkno _t_nxrec _tmopen"~tmopenflagdminordevcsv L2L1,cret _tmclose"0~tmclose0flagdminordevL5N_tcomman"^~tcomman^unitcomL7rL10000d_lbolt _sleep _tmstrat"˜~tmstrat˜bpabppL10ÐL11ÊL20002ÂL20004¼_clrbuf _iodone L9 L13Þ_spl5 L14òL15úL16_tmstart"_spl0 ~tmstartbpunitøÿcomblknoL18(L10001L17ÜL20¤L21„L20006šL23�L22žL10002ÆL10003ÖL10004Ò_tmintr"à~tmintràbpunitL25~L26DL27ôL29&L31:L34zL33p_tmread"‚~tmread‚dev_tmphys"Þ_physio _tmwrite"´~tmwrite´dev~tmphysÞunitadev_lshift partab.ol {ãÿ€ ����‚…†���������€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€�_partab#rp.ob.ol ›ã¶Ø2 $w üÿDÌ5ß � ÃEøÿ×tÃe2ô¥@ ô"‚ÌUß L4 ôÎ æß Ö Î æß Ö ÁÀ rWt�PtÁÀ r4`÷ vÿÃxÿ7rÿÂ3-‡´, ‚3-‚´,‡ƒë´3÷‹4ÿ÷ ÷ *ÿw&ÿw "ÿÄ$ÿ·ŠÿÔý� týÿ&æÒý&ß Æewòþw îþ÷‹êþ:Äêþ7Šàþß Ìý&ÎÈýæÊý&ß –%ß5Èý ß• Ìý ß5ÈýÅ~ßÌý ß5€ÌýÅ~·Š›þ÷¥ •þ ÌU7Š‹þ7ŠþôÎýß ÷ Nÿwpþw lþNß æÀ Îfææß ÆewDþw @þNß æÀ  fææß Æewþw þÎ÷ÿæBß Ö Îæ>þÎeÿß Ö `@�ÀEøÿt0!2ƒ÷•þ wÔýÀû˜ž˜žËð#ð#hÿÿÿÿNð<ð_iodone L1Ö_lrem _ldiv _spl5 L6–L5ÈL7ÀL10001¬L8¼L9Ò_rpstart"Ú_spl0 cret ~rpstartÚbpL10 _devstar _rpintr"~rpintrbpctrL11ŒL12r_deverro L13PL14FL16XL17bL20000ˆ_rpread"�~rpread�dev_rpphys"æL19¸_physio _rpwrite"¼~rpwrite¼devL21â~rpphysæcdev_lshift L24,L23(lp.o.ol oã¶4œw üÿ÷5üÿß Lÿ÷• ÷UæÿßU@LÿÎ ß ^wÎÿw ÊÿÎ ß ^7 Äÿwºÿw ¶ÿß ^÷ ªÿùw¢ÿw žÿD÷5šÿÄ%aÄ%z ÄeàÿÁ7œ þy Á7p þy Ã( Ã)Ã'Ã!Ã^Îß ^÷ BÿÄ-ØÀ8ÿÀeÀE7,ÿwÿ÷5ÿ÷ ÿ÷ ÿ7 ÿ· ÿ÷%<ÿ÷5úþÄ ß ÈÄ% 7 êþ7 äþ÷5ÚþØ÷ÖþÔ÷ ÐþÑ÷ ÊþÎ÷-ÂþÂþÎ ß È7 ²þ÷%P®þÎ ß È· œþ÷-˜þ˜þöß È· Šþ· ˆþ­w xþÎß Nÿß5€LÿôwZþw Vþ÷ Öÿ÷%2Lþ÷ FþÎß w8þw 4þ÷%d.þÎ æß Ö Îfß Ö ÷ þ÷ Œÿ÷ þwþ`{|}~®¢´¨º~ 6Îââ"~B©YIYù©Yù©™ù©YYYYùYYYYYYYYYYYYYYYYYYYYYY©Xèù©YYXXù©YX˜X¨¹Éù_bdevsw _nblkdev _cdevsw _nchrdev _u "_lp11 _lpopen"~lpopenflagdevcsv L10000L2L1._lpcanon"^cret _lpclose"2~lpclose2flagdev_lpwrite"F~lpwriteFcL5RL20001L_cpass L10002L10003 L16®L13¢L17´L15¨L18ºL8~L10007L10008$L296L21ÎL23âL27"L31~L32B~lpcanon^cc1c2L9�L10009ˆL10004šL14¾L7ÞL10005öL25_lpoutpu"ÈL33VL35lL20003`_lpstart"„~lpstart„cL38šL20005Š_getc L37¢_lpint"¦~lpint¦cL10010¼L40Ä_wakeup ~lpoutpuÈcL43â_sleep _putc _spl4 _spl0 dhdm.ol /ã¶�ô˜w üÿD�uÄe@�@ñßBñß5@BñôÕß`@ñ÷ ÊÿÎ &ß Ö ôµö÷ °ÿw¬ÿw ¨ÿD�uÄeô5 @�@ñßBñß`@ñw|ÿw xÿß5€@ñ0Ä@ñÄEðÿuÄeÀ\ÿtÀe!†ß ß5@Bñôµ Î&ß Ö  Bñß ôÅôÕß`@ñw ÿ¹XÙ)¹X)¹XiXØ)_partab _bdevsw _nblkdev _cdevsw _nchrdev _dh11 _ndh11 _dmopen"~dmopentpdevcsv L2,_spl5 L3DL200018_sleep _spl0 cret _dmclose"T~dmcloseTtpdevL5€_dmint"„~dmint„tpL7ðL9ê_wakeup L10äL11Ü_signal _flushtt dh.ool )ã¶Ì "tw üÿõ¥÷•%6D�uÄeô8tßU@0àôÕ ôµô•#ô•@ôôÈß hNß ôÅôÕÀÆÿð 0w|ÿw xÿD�uÄeNß ôÅçÿß wTÿw Pÿ@�tÎeß w:ÿw 6ÿ@�tÎeß w ÿw ÿ'ß #ÄuøÿÄEðÿuÄeÄ%ƒôµìÃ5éÃ5 ô5  Ãæß Ö ÃàÚwÂþw ¾þD�uÄeN&ß Ö À ß hw˜þw ”þD÷ Œþ�ÀU@0�àô‹ôUß +�t �Wt@Pô¥ÃU@ô5€ ô5@ÃUÃUÃU2ô¥ÃUßà÷ þwþw þÀà@ ÁþA @@ßE€àÃÄÂ0 ÷@äýÂ@ôÅ ß 8à Äe  ðwÈýw ÄýÆåõþÿøÿ÷ ¶ýBòµ!a„œN€œtÀe5öÿ Ã%øÿ ŽÎe ß Ä%€/2‘ò% òµ@òÅ@ŽÎe ß Ã !€œÀU@0�à@öÿÀ`àßàÀ�œtQà7Q"ýòÕ =‘öÿµ öÿà ¾„œ2ŠÎE€ÿÎe¦æß –%òÕ_øÿþÿwÞü IxhIy xÈØy xy xXy Èxxy xxy ÙÈYy ©x©y Ùˆ˜È©Øèy_bdevsw _nblkdev _cdevsw _nchrdev _u "_partab _proc L_dh11 _dh_clis €_ndh11#"_dhsar _dhopen"~dhopenflagtpdevcsv L2L1€_dhstart"8L3^_dhparam"h_dmopen cret _dhclose"„~dhclose„tpdev_dmclose _wflusht _dhread"¬~dhread¬dev_ttread _dhwrite"Æ~dhwriteÆdev_ttwrite _dhrint"à~dhrintàtpcL94L10000æ_wakeup L20002îL12*L13&_ttyinpu _dhsgtty">~dhsgtty>avtprdev_ttystty L15d~dhparamhtpatplpr_spl5 L17–L16ìL18¸L19ØL20ÔL21ÎL24ä_spl0 _dhxint"ð~dhxintðtpttybitbarL260L20004L29*~dhstart8cpöÿtpcnchatpspsøÿL31L20013øL33nL34Œ_getc L35æL36¬L37ò_ttrstrt _timeout dhfdm.ol 4ã¶"´w üÿD�uÄeôÕwæÿw âÿwÞÿ©X¹©¹_partab _bdevsw _nblkdev _cdevsw _nchrdev _dh11 _dmopen"~dmopentpdevcsv cret _dmclose"~dmclosedevsys.ool ¢ã¶ª¤w üÿ÷ ˆ f&�Wp ù –%wÚÿw Öÿ÷ b &�Wp ù Ö w¸ÿw ´ÿ÷ @ &�Wp ù Ö w–ÿw ’ÿ÷  f&�Wp ù –%wpÿw lÿÀ¤ÿ÷•“ÿwVÿÉ(ùÉ(ùÉ(ùÉ(ùÉIIù_bdevsw _nblkdev _cdevsw _nchrdev _u "_partab _proc L_syopen"~syopenflagtpdevcsv _syttyp"�L1"cret _syread"&~syread&tpdevL3D_sywrite"H~sywriteHtpdevL5f_sysgtty"j~sysgttyjflagtpdevL7Œ~syttyp�tpL10¤hp.ool Mã¶P $w üÿ÷‹øÿ·Šòÿß Èýß ÀýßÀýßÚýwÖÿw ÒÿD� ÃEøÿ×tÃePô¥@ ô"‚ÌUß L4 ôÎæß Ö Îæß Ö ÁÀ rWt�PtÁÀ r4`÷ XÿÃZÿ7TÿÂ3-‡´, ‚3-‚´,‡ƒë´3÷‹ÿ÷ ÷ ÿwÿw ÿÄÿ·Šúþ� týÿÈýÜýÎèý&æÆý&ß ÆewÎþw Êþ÷‹Æþ7ÄÆþ7мþß5@Àý" æÈý&ß –%ß5pÌý ß ÈýßÀý ß5 ÊýÅ~ß Àý·Š}þ÷¥ wþ ÌU7Šmþ7lþôÂýß ÷ NÿwRþw NþNß À Îfææ*ß Æew&þw "þNß À  fææ*ß Æewüýw øýÎ÷ÿæBß Ö Îæ þÎeÿß Ö `@�ÀEøÿt0!Pƒ÷•óý w¶ýÀûŽ%ÿÿ,ÿÿɤQf˜ž˜žd˜žÈ˜ž,Ù©©ùÙˆ¨¸É‰‰‰IùÙ‰‰ˆùÙ‰‰‰ø‰‰‰‰ˆùÙ˜ˆùÙ˜ˆùÙhi¸iù_buf h_bfreeli _bdevsw _nblkdev _cdevsw _nchrdev _u "_hp_size#P_hptab _hpbuf _hp_open _hpopen"~hpopencsv L1&cret _hpstrat"*~hpstrat*bpabpp1p2L10000PL4\_iodone L3ô_lrem _ldiv _spl5 L7´L6æL8ÞL10001ÊL9ÚL10ð_hpstart"ø_spl0 ~hpstartøbpL11._rhstart _hpintr"2~hpintr2bpctrL12ªL13�_deverro L14zL15pL20000¦_hpread"®~hpread®dev_hpphys"L18Ö_physio _hpwrite"Ú~hpwriteÚdevL20~hpphyscdev_lshift L23JL22Fht.ool _ã¶ ¦¤w üÿD�ÄEÀÿÄ%ô‹÷•´ŠÀ 0 À ðÿÿ fß ŠÖ wºÿw ¶ÿD�ÄEÀÿ4Šõ Îfß ŠÖ Îfß ŠÖ Îfß ŠÖ wvÿw rÿD�Îæß Ö ÷‹Zÿöß5€ õòtýÿÀEøÿ(õÎæß Ö ß5€*õõÄ%@ÀEøÿÀUÀÀEøÿÀUÀ:õÎæß Ö À*õÀEÿÏÀ%ò@ÀU õwÜþw ØþD� ÃEÀÿà Ãe -‡ - ƒÌUß ß !Ì5öÌ5€ 4 ÷ Šþ÷ Œþ7†þÀ‚þ07zþ÷‹nþ÷ ÷ dþw`þw \þÄ^þa� ÀtýÿÀEøÿ(õÃ%@ÀÀEøÿÀUÀÀÀEøÿÀUÀ:õÃEÀÿÀÀ ó‹ß5€ õ ÌU7þß Î-÷•ìý- ƒ€í&õßY õ ô ßG õ€à&õß[ õ÷•®ýÎ<õ À &æ&õ&ß Æew�ýw ŒýÄŽýO� ÃEÀÿß5@ õ*ß5*õ Ä%ó‹ó•ÿÿß @ õß5€*õ÷¥Hý ·ŠCý÷¥ =ýÀÀ ° 7Š.ý ÌU÷•"ý÷¥ý7ŠýÀÀ ° 7ý7Šýß ô&õÀÀ 0÷ ˆþwäüw àüNß xÎfææ$ß ÆeÀÒü 7öüw²üw ®üNß x fææ$ß Æe7 Ìüwˆüw „üD�Î÷ÿæBß Ö À ðƒ À ðwZü˜i˜¨¸i˜i8Hy8H8Hi¸HX‰yyyyyÙiy¨˜yXyy¸iyˆ˜˜yyy¨yyyy¨yyX¨iˆ¨‰iiˆ¨iih(¨¸i_buf h_bfreeli _bdevsw _nblkdev _cdevsw _nchrdev _u "_httab _rhtbuf _h_openf _h_blkno _h_nxrec _htopen"~htopenflagunitdevcsv L10000L2 L1B_hcomman"Šcret _htclose"F~htcloseFflagunitdevL5x~hcommanŠunitdevcomL7¢L10001”_lbolt _sleep L9ÎL20002ÀL11èL20003òL13L20005ø_htstrat"$~htstrat$bpabppL16`L17ZL20007RL20009L_clrbuf _iodone L15œL19n_spl5 L20‚L21ŠL22˜_htstart" _spl0 ~htstart bpunitblknoL24¤L23lL25ÎL20010ØL10002öL27L28LL29,L31:_rhstart _htintr"p~htintrpbpunitL33L34ÞL35¤L37ÔL40L39 _htread"~htreaddev_htphys"x_physio _htwrite"N~htwriteNdev~htphysxunitadev_lshift hs.ool Tã¶ 4(w üÿDÃô¥ Ãô ‚ÌUß 4 ÷ Îÿ÷ Ðÿ7ÊÿÀÆÿ07¾ÿ÷‹²ÿ÷ ÷ ¨ÿw¤ÿw  ÿÄ¢ÿ·Š–ÿô¥ à � ÀEøÿ(ôÎ8ôÀÀ &æ&ô&ß Æew`ÿw \ÿ÷‹Xÿ$ÄXÿ7ŠNÿß5@ ô æ(ô&ß –%ß ô·Š/ÿ÷¥ )ÿ ÌU7Šÿ7ÿß ÷ jÿw ÿw ÿÎfææß Æewêþw æþ fææß ÆewÌþé9yyyyy‰™éyyø™éyyyXyyyy™éˆ¨™éˆ¨™_buf h_bfreeli _bdevsw _nblkdev _cdevsw _nchrdev _u "_hstab _rhsbuf _hsstrat"~hsstratbpabpmblkscsv L2L3*_iodone L1X_spl5 L4>L5FL6T_hsstart"\_spl0 cret ~hsstart\bpaddrL7œL8x_rhstart _hsintr" ~hsintr bpL9òL10Þ_deverro L20000î_hsread"ö~hsreadödev_physio _hswrite"~hswritedevdr.ooY n€¶XúTw üÿõ¥÷•%wêÿD�uÄeÌ óŒ ÀøïA�Wt@à4ÂË`æw ¶ÿD�uÄeÎ æß Ö ô öÎeß À ù < w|ÿw xÿD�uÄe +÷ dÿÎ &Îe ß Ö ô%2 óÎ æß Ö Îe æß Ö À ð‚ Â% Nß @÷ ÿ÷ ÿÑwÿw ÿD�uÄe÷ òþÎ &Îeß Ö Îeß ñÎß À ô÷ ÄþwÀþw ¼þD�uÄeü5€+ Â%#Îe ß &&Îe ÷ ˆþÖ t€U1üU@Âå Â% Îe ß üE@wNþw JþD�uÄeÎe¦ß Ö Îe€tøÿ&ß Ö Îeß wþé )héh˜¨È)éhY¨˜¨¨Ùé)éhY¨ÈxÙ)éhÈÉ)éh¨¨)_u "_bdevsw _nblkdev _cdevsw _nchrdev _partab _dr11 _dropen"~dropenflagjunkaddpdevcsv L2L3 L1cret _drclose"F~drcloseFpdevL6fL20001X_lbolt _sleep L8l_getc _drwrite"„~drwrite„cpdevwL11îL20007˜_spl5 L13®L20003žL15ÆL20005¸_putc L17ê_drxint"@_spl0 _cpass _drread"ú~drreadúcpdevwL22 L20009_passc ~drxint@cpdevwL24®L25¨L10000œ_wakeup _drrint"²~drrint²cpdevwc _drwrite"„~drwrite„cpdevwL11îL20007˜_spl5 L13®L20003žL1# /* */ #include "../param.h" #include "../systm.h" #include "../filsys.h" #include "../conf.h" #include "../buf.h" #include "../inode.h" #include "../user.h" /* * iinit is called once (from main) * very early in initialization. * It reads the root's super block * and initializes the current date * from the last modified date. * * panic: iinit -- cannot read the super * block. Usually because of an IO error. */ iinit() { register *cp, *bp; (*bdevsw[rootdev.d_major].d_open)(rootdev, 1); bp = bread(rootdev, 1); cp = getblk(NODEV); if(u.u_error) panic("iinit"); bcopy(bp->b_addr, cp->b_addr, 256); brelse(bp); mount[0].m_bufp = cp; mount[0].m_dev = rootdev; cp = cp->b_addr; cp->s_flock = 0; cp->s_ilock = 0; cp->s_ronly = 0; time[0] = cp->s_time[0]; time[1] = cp->s_time[1]; } /* * alloc will obtain the next available * free disk block from the free list of * the specified device. * The super block has up to 100 remembered * 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. */ free(dev, bno) { register *fp, *bp, *ip; 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); } return(0); } /* * Allocate an unused I node * on the specified device. * Used with file creation. * The algorithm keeps up to * 100 spare I nodes in the * super block. When this runs out, * a linear search through the * I list is instituted to pick * up 100 more. */ ialloc(dev) { register *fp, *bp, *ip; int i, j, k, ino; fp = getfs(dev); while(fp->s_ilock) sleep(&fp->s_ilock, PINOD); loop: if(fp->s_ninode > 0) { ino = fp->s_inode[--fp->s_ninode]; ip = iget(dev, ino); if (ip==NULL) return(NULL); if(ip->i_mode == 0) { for(bp = &ip->i_mode; bp < &ip->i_addr[8];) *bp++ = 0; fp->s_fmod = 1; return(ip); } /* * Inode was allocated after all. * Look some more. */ iput(ip); goto loop; } fp->s_ilock++; ino = 0; for(i=0; is_isize; i++) { bp = bread(dev, i+2); ip = bp->b_addr; for(j=0; j<256; j=+16) { ino++; if(ip[j] != 0) continue; for(k=0; ks_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; } /* * 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. */ 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); } [0]; mp < &mount[NMOUNT]; mp++) if(mp->m_bufp != NULL) { # #include "../param.h" #include "../systm.h" #include "../user.h" #include "../proc.h" #define UMODE 0170000 #define SCHMAG 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 none, just return * else update first non-zero time */ if(callout[0].c_func == 0) goto out; p2 = &callout[0]; while(p2->c_time<=0 && p2->c_func!=0) p2++; p2->c_time--; /* * if ps is high, just return */ if((ps&0340) != 0) goto out; /* * callout */ spl5(); if(callout[0].c_time <= 0) { p1 = &callout[0]; while(p1->c_func != 0 && p1->c_time <= 0) { (*p1->c_func)(p1->c_arg); p1++; } p2 = &callout[0]; while(p2->c_func = p1->c_func) { p2->c_time = p1->c_time; p2->c_arg = p1->c_arg; p1++; p2++; } } /* * lightning bolt time-out * and time of day */ out: if((ps&UMODE) == UMODE) { u.u_utime++; if(u.u_prof[3]) incupc(pc, u.u_prof); } else u.u_stime++; pp = u.u_procp; if(++pp->p_cpu == 0) pp->p_cpu--; if(++lbolt >= HZ) { if((ps&0340) != 0) return; lbolt =- HZ; if(++time[1] == 0) ++time[0]; spl1(); if(time[1]==tout[1] && time[0]==tout[0]) wakeup(tout); if((time[1]&03) == 0) { runrun++; wakeup(&lbolt); } for(pp = &proc[0]; pp < &proc[NPROC]; pp++) if (pp->p_stat) { if(pp->p_time != 127) pp->p_time++; if((pp->p_cpu & 0377) > SCHMAG) pp->p_cpu =- SCHMAG; else pp->p_cpu = 0; if(pp->p_pri > PUSER) setpri(pp); } if(runin!=0) { runin = 0; wakeup(&runin); } if((ps&UMODE) == UMODE) { u.u_ar0 = &r0; if(issig()) psig(); setpri(u.u_procp); } } } /* * timeout is called to arrange that * fun(arg) is called in tim/HZ seconds. * An entry is sorted into the callout * structure. The time in each structure * entry is the number of HZ's more * than the previous entry. * In this way, decrementing the * first entry has the effect of * updating all entries. */ timeout(fun, arg, tim) { register struct callo *p1, *p2; register t; int s; 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; } ry has the effect of * updating all entries. */ timeout(fun, arg, tim) { register struct callo *p1, *p2; register t; int s; t = tim; s = PS->integ; p1 = &callout[0]; spl7(); while(p1->c_func != 0# /* */ #include "../param.h" #include "../user.h" #include "../filsys.h" #include "../file.h" #include "../conf.h" #include "../inode.h" #include "../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) { 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 * and also on mount. */ openi(ip, rw) int *ip; { register *rip; register dev, maj; 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; 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); if (suser()) return(ip); iput(ip); return(NULL); } /* * Test if the current user is the * super user. */ suser() { if(u.u_uid == 0) return(1); u.u_error = EPERM; return(0); } /* * Allocate a user file descriptor. */ ufalloc() { register i; for (i=0; if_count==0) { u.u_ofile[i] = fp; fp->f_count++; fp->f_offset[0] = 0; fp->f_offset[1] = 0; return(fp); } printf("no file\n"); u.u_error = ENFILE; return(NULL); } 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; 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# #include "../param.h" #include "../systm.h" #include "../user.h" #include "../inode.h" #include "../filsys.h" #include "../conf.h" #include "../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; } 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; 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; } 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; } /* * 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); return(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); } _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); return(ip); } /* * Write a directory entry with * parameters left as side effects * # #include "../param.h" #include "../user.h" #include "../systm.h" #include "../proc.h" #include "../text.h" #include "../inode.h" #include "../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: */ 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. */ main() { extern schar; register i, *p; /* * zero and free all of core */ updlock = 0; i = *ka6 + USIZE; UISD->r[0] = 077406; for(;;) { UISA->r[0] = i; if(fuibyte(0) < 0) break; clearseg(i); maxmem++; mfree(coremap, 1, i); i++; } if(cputype == 70) for(i=0; i<62; i=+2) { UBMAP->r[i] = i<<12; UBMAP->r[i+1] = 0; } printf("mem = %l\n", maxmem*5/16); maxmem = min(maxmem, MAXMEM); mfree(swapmap, nswap, swplo); /* * determine clock */ UISA->r[7] = ka6[1]; /* io segment */ UISD->r[7] = 077406; lks = CLOCK1; if(fuiword(lks) == -1) { lks = CLOCK2; if(fuiword(lks) == -1) panic("no clock"); } /* * set up system process */ proc[0].p_addr = *ka6; proc[0].p_size = USIZE; proc[0].p_stat = SRUN; proc[0].p_flag =| SLOAD|SSYS; u.u_procp = &proc[0]; /* * set up 'known' i-nodes */ *lks = 0115; cinit(); binit(); iinit(); rootdir = iget(rootdev, ROOTINO); rootdir->i_flag =& ~ILOCK; u.u_cdir = iget(rootdev, ROOTINO); u.u_cdir->i_flag =& ~ILOCK; /* * make init process * enter scheduling loop * with system process */ if(newproc()) { expand(USIZE+1); estabur(0, 1, 0, 0); copyout(icode, 0, sizeof icode); /* * Return goes to loc. 0 of user init * code just copied out. */ return; } sched(); } /* * 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; } 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; } } /* * Set up software prototype segmentation * registers to implement the 3 pseudo * text,data,stack segment sizes passed * as arguments. * The argument sep specifies if the * text and data+stack segments are to * be separated. */ estabur(nt, nd, ns, sep) { register a, *ap, *dp; if(sep) { if(cputype == 40) goto err; if(nseg(nt) > 8 || nseg(nd)+nseg(ns) > 8) goto err; } else if(nseg(nt)+nseg(nd)+nseg(ns) > 8) goto err; if(nt+nd+ns+USIZE > maxmem) goto err; a = 0; ap = &u.u_uisa[0]; dp = &u.u_uisd[0]; while(nt >= 128) { *dp++ = (127<<8) | RO; *ap++ = a; a =+ 128; nt =- 128; } if(nt) { *dp++ = ((nt-1)<<8) | RO; *ap++ = a; } if(sep) while(ap < &u.u_uisa[8]) { *ap++ = 0; *dp++ = 0; } a = USIZE; while(nd >= 128) { *dp++ = (127<<8) | RW; *ap++ = a; a =+ 128; nd =- 128; } if(nd) { *dp++ = ((nd-1)<<8) | RW; *ap++ = a; a =+ nd; } while(ap < &u.u_uisa[8]) { *dp++ = 0; *ap++ = 0; } if(sep) while(ap < &u.u_uisa[16]) { *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); } /* * Return the arg/128 rounded up. */ nseg(n) { return((n+127)>>7); } = 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]; # /* */ /* * Structure of the coremap and swapmap * arrays. Consists of non-zero count * and base address of that many * contiguous units. * (The coremap unit is 64 bytes, * the swapmap unit is 512 bytes) * The addresses are increasing and * the list is terminated with the * first zero count. */ struct map { char *m_size; char *m_addr; }; /* * Allocate size units from the given * map. Return the base of the allocated * space. * Algorithm is first fit. */ malloc(mp, size) struct map *mp; { register int a; register struct map *bp; for (bp = mp; bp->m_size; bp++) { if (bp->m_size >= size) { a = bp->m_addr; bp->m_addr =+ size; if ((bp->m_size =- size) == 0) do { bp++; (bp-1)->m_addr = bp->m_addr; } while ((bp-1)->m_size = bp->m_size); return(a); } } return(0); } /* * 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); } } e!=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# #include "../param.h" #include "../inode.h" #include "../user.h" #include "../systm.h" #include "../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; if(c == '\0') return(dp); /* * If there is another component, * dp must be a directory and * must have x permission. */ if((dp->i_mode&IFMT) != IFDIR) { u.u_error = ENOTDIR; goto out; } if(access(dp, IEXEC)) goto out; /* * Gather up name into * users' dir buffer. */ cp = &u.u_dbuf[0]; while(c!='/' && c!='\0' && u.u_error==0) { if(cp < &u.u_dbuf[DIRSIZ]) *cp++ = c; c = (*func)(); } while(cp < &u.u_dbuf[DIRSIZ]) *cp++ = '\0'; while(c == '/') c = (*func)(); if(u.u_error) goto out; /* * Set up to search a directory. */ u.u_offset[1] = 0; u.u_offset[0] = 0; u.u_segflg = 1; eo = 0; u.u_count = ldiv(dp->i_size1, DIRSIZ+2); bp = NULL; eloop: /* * If at the end of the directory, * the search failed. Report what * is appropriate as per flag. */ if(u.u_count == 0) { if(bp != NULL) brelse(bp); if(flag==1 && c=='\0') { if(access(dp, IWRITE)) goto out; u.u_pdir = dp; if(eo) u.u_offset[1] = eo-DIRSIZ-2; else dp->i_flag =| IUPD; return(NULL); } u.u_error = ENOENT; goto out; } /* * If offset is on a block boundary, * read the next directory block. * Release previous if it exists. */ if((u.u_offset[1]&0777) == 0) { if(bp != NULL) brelse(bp); bp = bread(dp->i_dev, bmap(dp, ldiv(u.u_offset[1], 512))); } /* * Note first empty directory slot * in eo for possible creat. * String compare the directory entry * and the current component. * If they do not match, go back to eloop. */ bcopy(bp->b_addr+(u.u_offset[1]&0777), &u.u_dent, (DIRSIZ+2)/2); u.u_offset[1] =+ DIRSIZ+2; u.u_count--; if(u.u_dent.u_ino == 0) { if(eo == 0) eo = u.u_offset[1]; goto eloop; } for(cp = &u.u_dbuf[0]; cp < &u.u_dbuf[DIRSIZ]; cp++) if(*cp != cp[u.u_dent.u_name - u.u_dbuf]) goto eloop; /* * Here a component matched in 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); } && 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) retur# /* */ #include "../param.h" #include "../systm.h" #include "../user.h" #include "../inode.h" #include "../file.h" #include "../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 LARG * 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; 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); } /* * 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 deplete * 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); 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 unlock 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); } } akeup(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 unlock inodes in gene# /* */ #include "../param.h" #include "../seg.h" #include "../buf.h" #include "../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') 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; if(rc == '\n') { putchar('\r'); putchar(0177); putchar(0177); } putchar(0); KL->xsr = s; } /* * Panic is called on unresolvable * fatal errors. * It syncs, prints "panic: mesg" and * then loops. */ panic(s) char *s; { panicstr = s; update(); printf("panic: %s\n", s); for(;;) idle(); } /* * prdev prints a warning message of the * form "mesg on dev x/y". * x and y are the major and minor parts of * the device argument. */ prdev(str, dev) { printf("%s on dev %l/%l\n", str, dev.d_major, dev.d_minor); } /* * deverr prints a diagnostic from * a device driver. * It prints the device, block number, * and an octal word (usually some error * status register) passed as argument. */ deverror(bp, o1, o2) int *bp; { register *rbp; rbp = bp; prdev("err", rbp->b_dev); printf("bn%l er%o %o\n", rbp->b_blkno, o1, o2); } ge of the * form "mesg on dev x/y". * x and y are the major and minor parts of * the device argument. */ prdev(str, dev) { printf("%s on dev %l/%l\n", str, dev.d_major, dev.d_minor); } /* * deverr prints a diagnostic from * a device driver. * It pri# /* */ #include "../param.h" #include "../inode.h" #include "../user.h" #include "../buf.h" #include "../conf.h" #include "../systm.h" /* * Read 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 destination * u_offset byte offset in file * u_count number of bytes to read * u_segflg read to kernel/user */ readi(aip) struct inode *aip; { int *bp; int lbn, bn, on; register dn, n; register struct inode *ip; ip = aip; if(u.u_count == 0) return; ip->i_flag =| IACC; if((ip->i_mode&IFMT) == IFCHR) { (*cdevsw[ip->i_addr[0].d_major].d_read)(ip->i_addr[0]); return; } do { lbn = 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) { dn = dpcmp(ip->i_size0&0377, ip->i_size1, u.u_offset[0], u.u_offset[1]); if(dn <= 0) return; n = min(n, dn); if ((bn = bmap(ip, lbn)) == 0) return; 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 write 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 n, on; register dn, bn; 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; 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); } /* * 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; } 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==# /* */ #include "../param.h" #include "../systm.h" #include "../user.h" #include "../proc.h" #include "../inode.h" #include "../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) { 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(); 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_ppid != 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; 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 SIGQIT: case SIGINS: case SIGTRC: case SIGIOT: case SIGEMT: case SIGFPT: case SIGBUS: case SIGSEG: case 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; 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 if 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; 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); } /* * Code that the child process * executes to implement the command * of the parent process in tracing. */ procxmt() { register int i; register int *p; if (ipc.ip_lock != u.u_procp->p_pid) return(0); i = ipc.ip_req; ipc.ip_req = 0; wakeup(&ipc); switch (i) { /* read user I */ case 1: if (fuibyte(ipc.ip_addr) == -1) goto error; ipc.ip_data = fuiword(ipc.ip_addr); break; /* read user D */ case 2: if (fubyte(ipc.ip_addr) == -1) goto error; ipc.ip_data = fuword(ipc.ip_addr); break; /* read u */ case 3: i = ipc.ip_addr; if (i<0 || i >= (USIZE<<6)) goto error; ipc.ip_data = u.inta[i>>1]; break; /* write user I (for now, always an error) */ case 4: if (suiword(ipc.ip_addr, 0) < 0) goto error; suiword(ipc.ip_addr, ipc.ip_data); break; /* write user D */ case 5: if (suword(ipc.ip_addr, 0) < 0) goto error; suword(ipc.ip_addr, ipc.ip_data); break; /* 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]) { ipc.ip_data =| 0170000; /* assure user space */ ipc.ip_data =& ~0340; /* priority 0 */ } *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); } e 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]) { ipc.ip_data =| 0170000; /* assure user space */ ipc.ip_data =& ~0340; /* priority 0 */ } *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(); defaul# /* */ #include "../param.h" #include "../user.h" #include "../proc.h" #include "../text.h" #include "../systm.h" #include "../file.h" #include "../inode.h" #include "../buf.h" /* * 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 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 * 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); } } /* * 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; } /* * The main loop of the scheduling (swapping) * process. * The basic idea is: * see if anyone wants to be swapped in; * swap out processes until there is room; * swap him in; * repeat. * Although it is not remarkably evident, the basic * synchronization here is on the runin flag, which is * slept on and is set once per second by the clock routine. * Core shuffling therefore takes place once per second. * * panic: swap error -- IO error while swapping. * this is the one panic that should be * handled in a less drastic way. Its * very hard. */ sched() { struct proc *p1; register struct proc *rp; register a, n; /* * find user to swap in * of users ready, select one out longest */ goto loop; sloop: runin++; sleep(&runin, PSWP); loop: spl6(); n = -1; for(rp = &proc[0]; rp < &proc[NPROC]; rp++) if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0 && rp->p_time > n) { p1 = rp; n = rp->p_time; } if(n == -1) { runout++; sleep(&runout, PSWP); goto loop; } /* * see if there is core for that process */ spl0(); rp = p1; a = rp->p_size; if((rp=rp->p_textp) != NULL) if(rp->x_ccount == 0) a =+ rp->x_size; if((a=malloc(coremap, a)) != NULL) goto found2; /* * none found, * look around for easy core */ spl6(); for(rp = &proc[0]; rp < &proc[NPROC]; rp++) if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD && (rp->p_stat == SWAIT || rp->p_stat==SSTOP)) goto found1; /* * no easy core, * if this process is deserving, * look around for * oldest process in core */ if(n < 3) goto sloop; n = -1; for(rp = &proc[0]; rp < &proc[NPROC]; rp++) if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD && (rp->p_stat==SRUN || rp->p_stat==SSLEEP) && rp->p_time > n) { p1 = rp; n = rp->p_time; } if(n < 2) goto sloop; rp = p1; /* * swap user out */ found1: spl0(); rp->p_flag =& ~SLOAD; xswap(rp, 1, 0); goto loop; /* * swap user in */ found2: if((rp=p1->p_textp) != NULL) { if(rp->x_ccount == 0) { if(swap(rp->x_daddr, a, rp->x_size, B_READ)) goto swaper; rp->x_caddr = a; a =+ rp->x_size; } rp->x_ccount++; } rp = p1; if(swap(rp->p_addr, a, rp->p_size, B_READ)) goto swaper; mfree(swapmap, (rp->p_size+7)/8, rp->p_addr); rp->p_addr = a; rp->p_flag =| SLOAD; rp->p_time = 0; goto loop; swaper: panic("swap error"); } /* * This routine is called to reschedule the CPU. * if the calling process is not in RUN state, * arrangements for it to restart must have * been made elsewhere, usually by calling via sleep. */ swtch() { static struct proc *p; register i, n; register struct proc *rp; if(p == NULL) p = &proc[0]; /* * Remember stack of caller */ savu(u.u_rsav); /* * Switch to scheduler's stack */ retu(proc[0].p_addr); loop: runrun = 0; rp = p; p = NULL; n = 128; /* * 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); } /* * 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 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 returned value of swtch * (see above) is that this is the value that newproc's * caller in the new process sees. */ newproc() { int a1, a2; struct proc *p, *up; register struct proc *rpp; register *rip, n; p = NULL; /* * First, just locate a slot for a process * and copy the useful info from this process into it. * The panic "cannot happen" because fork has 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) 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_pid; 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 out the current process to 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); } /* * Change the size of the data+stack regions of the process. * If the size is shrinking, it's easy-- just release the extra core. * If it's growing, and there is core, just allocate it * and copy the image, taking care to reset registers to account * for the fact that the system's stack has moved. * If there is no core, arrange for the process to be swapped * out after adjusting the size requirement-- when it comes * in, enough core will be allocated. * Because of the ssave and SSWAP flags, control will * resume after the swap in swtch, which executes the return * from this stack level. * * After the expansion, the caller will take care of copying * the user's stack towards or away from the data area. */ expand(newsize) { int i, n; register *p, a1, a2; p = u.u_procp; n = p->p_size; p->p_size = newsize; a1 = p->p_addr; if(n >= newsize) { mfree(coremap, n-newsize, a1+newsize); return; } savu(u.u_rsav); a2 = malloc(coremap, newsize); if(a2 == NULL) { savu(u.u_ssav); xswap(p, 1, n); p->p_flag =| SSWAP; swtch(); /* no return */ } p->p_addr = a2; for(i=0; ip_addr); sureg(); } ack 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(# /* */ #include "../param.h" #include "../conf.h" #include "../inode.h" #include "../user.h" #include "../buf.h" #include "../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); 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; bdwrite(nbp); bdwrite(bp); } else brelse(bp); rablock = 0; if(i < 255) rablock = bap[i+1]; return(nb); } /* * Pass back c to the user at his location u_base; * update u_base, u_count, and u_offset. Return -1 * on the last character of the user's read. * u_base is in the user address space unless u_segflg is set. */ passc(c) char c; { if(u.u_segflg) *u.u_base = c; else if(subyte(u.u_base, c) < 0) { u.u_error = EFAULT; return(-1); } u.u_count--; if(++u.u_offset[1] == 0) u.u_offset[0]++; u.u_base++; return(u.u_count == 0? -1: 0); } /* * Pick up and return the next character from the user's * write call at location u_base; * update u_base, u_count, and u_offset. Return -1 * when u_count is exhausted. u_base is in the user's * address space unless u_segflg is set. */ cpass() { register c; if(u.u_count == 0) return(-1); if(u.u_segflg) c = *u.u_base; else 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); } 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 i# /* */ #include "../param.h" #include "../systm.h" #include "../user.h" #include "../proc.h" #include "../buf.h" #include "../reg.h" #include "../inode.h" /* * exec system call. * Because of the fact that an I/O buffer is used * to store the caller's arguments during exec, * and more buffers are needed to read in the text file, * deadly embraces waiting for free buffers are possible. * Therefore the number of processes simultaneously * running in exec has to be limited to NEXEC. */ #define EXPRI -1 exec() { int ap, na, nc, *bp; int ts, ds, sep; register c, *ip; register char *cp; extern uchar; /* * pick up file names * and check various modes * for execute permission */ ip = namei(&uchar, 0); if(ip == NULL) return; while(execnt >= NEXEC) sleep(&execnt, EXPRI); execnt++; bp = getblk(NODEV); if(access(ip, IEXEC) || (ip->i_mode&IFMT)!=0) goto bad; /* * pack up arguments into * allocated disk buffer */ cp = bp->b_addr; 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 implies RO text) (411 implies 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) 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) & 01777; 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; u.u_ssize = SSIZE; u.u_sep = sep; estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep); cp = bp->b_addr; ap = -nc - na*2 - 4; u.u_ar0[R6] = ap; suword(ap, na); c = -nc; while(na--) { suword(ap=+2, c); do subyte(c++, *cp); while(*cp++); } suword(ap+2, -1); /* * set SUID/SGID protections, if no tracing */ if ((u.u_procp->p_flag&STRC)==0) { if(ip->i_mode&ISUID) if(u.u_uid != 0) { u.u_uid = ip->i_uid; u.u_procp->p_uid = ip->i_uid; } if(ip->i_mode&ISGID) u.u_gid = ip->i_gid; } /* * clear sigs, regs and return */ c = ip; for(ip = &u.u_signal[0]; ip < &u.u_signal[NSIG]; ip++) if((*ip & 1) == 0) *ip = 0; for(cp = ®loc[0]; cp < ®loc[6];) u.u_ar0[*cp++] = 0; u.u_ar0[R7] = 0; for(ip = &u.u_fsav[0]; ip < &u.u_fsav[25];) *ip++ = 0; ip = c; bad: iput(ip); brelse(bp); if(execnt >= NEXEC) wakeup(&execnt); execnt--; } /* * exit system call: * pass back caller's 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); 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_cutime[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; } 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; } /* * 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); } .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 bigge# #include "../param.h" #include "../systm.h" #include "../user.h" #include "../reg.h" #include "../file.h" #include "../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); } 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); } else open1(ip, FWRITE, 1); } /* * 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; 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: ; } 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; /* * unlock to avoid possibly hanging the 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); } /* * 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(); } urn; 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]; } # /* */ #include "../param.h" #include "../systm.h" #include "../reg.h" #include "../buf.h" #include "../filsys.h" #include "../user.h" #include "../inode.h" #include "../file.h" #include "../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; 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; 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; update(); d = getmdev(); if(u.u_error) return; for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) if(mp->m_bufp!=NULL && d==mp->m_dev) goto found; u.u_error = EINVAL; return; found: for(ip = &inode[0]; ip < &inode[NINODE]; ip++) if(ip->i_number!=0 && d==ip->i_dev) { u.u_error = EBUSY; return; } (*bdevsw[d.d_major].d_close)(d, 0); ip = mp->m_inodp; ip->i_flag =& ~IMOUNT; iput(ip); ip = mp->m_bufp; mp->m_bufp = NULL; brelse(ip); } /* * Common code for mount and umount. * Check that the user's argument is a reasonable * thing on which to mount, and return the device number if so. */ getmdev() { register d, *ip; extern uchar; ip = namei(&uchar, 0); if(ip == NULL) return; if((ip->i_mode&IFMT) != IFBLK) u.u_error = ENOTBLK; d = ip->i_addr[0]; if(ip->i_addr[0].d_major >= nblkdev) u.u_error = ENXIO; iput(ip); return(d); } >m_inodp; ip->i_flag =&# /* */ /* * Everything in this file is a routine implementing a system call. */ #include "../param.h" #include "../user.h" #include "../reg.h" #include "../inode.h" #include "../systm.h" #include "../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; } } 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; 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); return; } if(access(ip, IEXEC)) goto bad; iput(u.u_cdir); u.u_cdir = ip; prele(ip); } chmod() { register *ip; if ((ip = owner()) == NULL) return; ip->i_mode =& ~07777; if (u.u_uid) u.u_arg[1] =& ~ISVTX; ip->i_mode =| u.u_arg[1]&07777; ip->i_flag =| IUPD; iput(ip); } chown() { register *ip; if (!suser() || (ip = owner()) == NULL) return; ip->i_uid = u.u_arg[1].lobyte; ip->i_gid = u.u_arg[1].hibyte; ip->i_flag =| IUPD; iput(ip); } /* * Change modified date of file: * time to r0-r1; sys smdate; file * This call has been withdrawn because it messes up * incremental dumps (pseudo-old files aren't dumped). * It works though and you can uncomment it if you like. smdate() { register struct inode *ip; register int *tp; int tbuf[2]; 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]); } 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_arg[0] & ~1; /* base of sample buf */ u.u_prof[1] = u.u_arg[1]; /* size of same */ u.u_prof[2] = u.u_arg[2]; /* pc offset */ u.u_prof[3] = (u.u_arg[3]>>1) & 077777; /* pc scale */ } yp != 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]); } 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_arg[0] & ~1; /* base of sample buf */ u.u_prof[1] = u.u_arg[1]; /* size of same */ u.u_prof[2] = u.u_arg[2]; /* pc offset # /* */ /* * 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 = unlink */ 2, &exec, /* 11 = exec */ 1, &chdir, /* 12 = chdir */ 0, >ime, /* 13 = time */ 3, &mknod, /* 14 = mknod */ 2, &chmod, /* 15 = chmod */ 2, &chown, /* 16 = chown */ 1, &sbreak, /* 17 = break */ 2, &stat, /* 18 = stat */ 2, &seek, /* 19 = seek */ 0, &getpid, /* 20 = getpid */ 3, &smount, /* 21 = mount */ 1, &sumount, /* 22 = umount */ 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, /* 30 = smdate; inoperative */ 1, &stty, /* 31 = stty */ 1, >ty, /* 32 = gtty */ 0, &nosys, /* 33 = x */ 0, &nice, /* 34 = nice */ 0, &sslep, /* 35 = sleep */ 0, &sync, /* 36 = sync */ 1, &kill, /* 37 = kill */ 0, &getswit, /* 38 = switch */ 0, &nosys, /* 39 = x */ 0, &nosys, /* 40 = x */ 0, &dup, /* 41 = dup */ 0, &pipe, /* 42 = pipe */ 1, ×, /* 43 = times */ 4, &profil, /* 44 = prof */ 0, &nosys, /* 45 = tiu */ 0, &setgid, /* 46 = setgid */ 0, &getgid, /* 47 = getgid */ 2, &ssig, /* 48 = sig */ 0, &nosys, /* 49 = x */ 0, &nosys, /* 50 = x */ 0, &nosys, /* 51 = x */ 0, &nosys, /* 52 = x */ 0, &nosys, /* 53 = x */ 0, &nosys, /* 54 = x */ 0, &nosys, /* 55 = x */ 0, &nosys, /* 56 = x */ 0, &nosys, /* 57 = x */ 0, &nosys, /* 58 = x */ 0, &nosys, /* 59 = x */ 0, &nosys, /* 60 = x */ 0, &nosys, /* 61 = x */ 0, &nosys, /* 62 = x */ 0, &nosys /* 63 = x */ }; 5 = tiu */ 0, &setgid, /* 46 = setgid */ 0, &getgid, /* 47 = getgid */ 2, &ssig, /* 48 = sig */ 0, &nosys, /* 49 = x */ 0, &nosys, /* 50 = x */ 0, &nosys, /* 51 = x */ 0, &nosys, /* 52 = x */ 0, &nosys, /* 53 = x */ 0, &nosys, /* 54 = x */ 0, &nosys, /* 55 = x */ 0, &nosys, /* 56 = x */ 0, &nosys, /* 57 = x */ 0, &nosys, /* 58 = x */ 0, &nosys, /* 59 = x */ 0, &nosys, /* 60 = x */ # /* */ #include "../param.h" #include "../systm.h" #include "../user.h" #include "../proc.h" #include "../text.h" #include "../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; 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); } } } } /* * Attach to a shared text segment. * If there is no shared text, just return. * If there is, hook up to it: * if it is not currently being used, it has to be read * in from the inode (ip) and established in the swap space. * If it is being used, but is not currently in core, * a swap has to be done to get it back. * The full coroutine glory has to be invoked-- * see slp.c-- because if the calling process * is misplaced in core the text image might not fit. * Quite possibly the code after "out:" could check to * see if the text does fit and simply swap it in. * * panic: out of swap space */ xalloc(ip) int *ip; { register struct text *xp; register *rp, ts; if(u.u_arg[1] == 0) return; rp = NULL; for(xp = &text[0]; xp < &text[NTEXT]; xp++) if(xp->x_iptr == NULL) { if(rp == NULL) rp = xp; } else if(xp->x_iptr == ip) { xp->x_count++; u.u_procp->p_textp = xp; goto out; } 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); } p = 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 *# #include "../param.h" #include "../systm.h" #include "../user.h" #include "../proc.h" #include "../reg.h" #include "../seg.h" #define EBIT 1 /* user error bit in PS: C-bit */ #define UMODE 0170000 /* user-mode bits in PS word */ #define SETD 0170011 /* SETD instruction */ #define SYS 0104400 /* sys (trap) instruction */ #define USER 020 /* user-mode flag added to dev */ /* * structure of the system entry table (sysent.c) */ struct sysent { int count; /* argument count */ int (*call)(); /* name of handler */ } sysent[64]; /* * Offsets of the user's registers relative to * the saved r0. See reg.h */ char regloc[9] { R0, R1, R2, R3, R4, R5, R6, R7, RPS }; /* * Called from l40.s or l45.s when a processor trap occurs. * The arguments are the words saved on the system stack * by the hardware and software during the trap processing. * Their order is dictated by the hardware and the details * of C's calling sequence. They are peculiar in that * this call is not 'by value' and changed user registers * get copied back on return. * dev is the kind of trap that occurred. */ trap(dev, sp, r1, nps, r0, pc, ps) { register i, a; register struct sysent *callp; savfp(); if ((ps&UMODE) == UMODE) 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; case 6+USER: /* sys call */ u.u_error = 0; ps =& ~EBIT; callp = &sysent[fuiword(pc-2)&077]; if (callp == sysent) { /* indirect */ a = fuiword(pc); pc =+ 2; i = fuword(a); if ((i & ~077) != SYS) i = 077; /* illegal */ callp = &sysent[i&077]; for(i=0; icount; i++) u.u_arg[i] = fuword(a =+ 2); } else { for(i=0; icount; i++) { u.u_arg[i] = fuiword(pc); pc =+ 2; } } u.u_dirp = u.u_arg[0]; trap1(callp->call); if(u.u_intflg) u.u_error = EINTR; if(u.u_error < 100) { if(u.u_error) { ps =| EBIT; r0 = u.u_error; } goto out; } i = SIGSYS; break; /* * Since the floating exception is an * imprecise trap, a user generated * trap may actually come from kernel * mode. In this case, a signal is sent * to the current process to be picked * up later. */ case 8: /* floating exception */ psignal(u.u_procp, SIGFPT); return; case 8+USER: i = SIGFPT; break; /* * 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); out: if(issig()) psig(); setpri(u.u_procp); } /* * Call the system-entry routine f (out of the * sysent table). This is a subroutine for trap, and * not in-line, because if a signal occurs * during processing, an (abnormal) return is simulated from * the last caller to savu(qsav); if this took place * inside of trap, it wouldn't have a chance to clean up. * * If this occurs, the return takes place without * clearing u_intflg; if it's still set, trap * marks an error which means that a system * call (like read on a typewriter) got interrupted * by a signal. */ trap1(f) int (*f)(); { u.u_intflg = 1; savu(u.u_qsav); (*f)(); u.u_intflg = 0; } /* * nonexistent system call-- set fatal error code. */ nosys() { u.u_error = 100; } /* * Ignored system call */ nullsys() { } if this took place * inside of trap, it wouldn't have a cha:>.h ð€&Ð 6÷ ß ‰w ôÆåõ%Îfß ^Îß @5ôÿõqøÿÃÄõ•1öÿý¥-ôÿ'-@ŸôÿÁ:7Ü þy õ{øÿÄ@õ…øÿÄuŸôÿöÿ @Ÿôÿæ�ß ^Ö Îß µ ôÿý‹ôÿÕÃ@øÿp�öÿ føÿß €Ö 7¨ÎŸß ^Îß Î~ÀÀ @m&ß Ö À Î¬ß ^Îß ÷fÀÀe@-ÀÀ @mß v&ÀÀ @m&÷ 6Ö t€U7,ß Î<ß ÷”À÷eÈ- ,÷åÀß ÷”ÿ-ò*Àüð-è$ð-â ð5€ÎÛß ^Îß ÷ à÷ BwV÷%’ ®Ȇ÷ ¾¾Î¶ß ^÷ $·÷e¦÷%’  ˆ÷ œÎÈß ^÷ Ίºw D@ñApN&ß lÖ ÀNÎe&ß lÖ  Ô¥.NÎe&ß lÖ w²w  æ uøÿ Ä@Ÿøÿß Æ ÁWp(Cƒ`„ µ øÿÄ%îÄ  wtÄ%ÁWp(C„ ÷ý@øÿðw Fõ%aõ%z@Àe ÿõ%9 @Àeîÿw&õ%0ò øw õ õ%Îîß ^Îß ÎfæHß À–%À Îß ^Îß Îæ’æ"ß ž–%À Î ß ^Îß w¨w –B Ã%8 uÄ`ÄeÐÿƒ”Ã%0ôw~w lÀè 7 Ü.Àà À Îß ^Îß Î¾ß Â”Â%’ ƒ€’Àå  ‚À xVÊ• ‚ ðÊ• ûÎþæ”æß ä–%÷ zÏ”Àe”€ †€’Àå  ‚À x^Ê• ‚ îÊ• û„ æ”æß ä–%wÀw ®Æå~w,DÄeÀŸ" ·  %ß ôw�7 7 ׯþ-· ö· ô÷(wè7 ê .÷wÞƒÃeÁ*BÚ üJ Ó•-÷ R r f÷ ðÿ€Àe0�‡•à •@à >ÁŠ Ò‹ƒ D~8ÂRÂV÷ hÓ•0 ÷ $f v÷ öÿ€€LÀe0 9Àe�‡À4Â.÷ ” À& ÷ †7wæþ‚Âeƒà&æ Ä Ãmô÷ òß Ã~Ä Ž”ß à Î ß Ã~Ö „w þ7 Æ ÀŸ¼· ¸Àå0 úÿ ‚· ¤Wp `ìÀe0ƒÄeÓ•?‡f…ÀŒ÷ ,À‚P�· x÷ r÷ @…‡f…÷ …‡ÀV Àå¦ 7ÀD€ ‰Z÷¦ :÷2×-,‚÷$‡f…wØwÔ‰`†w’…‡f…@w¼w¸‰f†wp…‡f…@w wœ‰l†wN …‡f…@w‚w~‰r†w*…‡f…@‰@…&æ¦æ HADCBF…‡7bÀÿÿF…‡0123dtŠŠŠŠ~r’üøøôB>>:arg count /dev/rrkx/dev/tapx/dev/rrkxbad option: %c open failed bad name can not find uic can not find file linked files only bad block number seek failed read failed corrupted file Ôd*o$xfftecsàl‚rüÿðÿýÿøÿ‰¦ ‰‰‰‰crt0.ostartgetd.o~mainargcfpôÿfileøÿjpargvunitöÿmfd1~dosname cpns~pack1ljnpøÿrsval~r50Æc~getbbn~atoovcpsnum~rdfile endbplenprintf.o^formp˜ looprrjustš ndigitž gnumÒwidth– ndfndœ swtab*decimalÔoctal*hex$floatfscientcharacstringlogicalàremote‚prbufŒprstr”ffltpr.oputchr.oflJopen.o€read.ožseek.oÀwrite.oäexit.ocsv.ocerror.o,savr5$” _exit"_main"_duic$x_fd$z_mfdp$|_ufd$~_ufdp$�_textb$’csv"_printf"^_open"€_dosname" _atoo"v_getb"_rdfile" cret"_pack1"l_r50"Æ_seek"À_read"ž_write"äpfloat"pscien"_putchar"_flush">_fout$  cerror",_errno$’ calàremote‚prbufŒprstr”ffltpr.oputchr.oflJopen.o€read.ožseek.oÀwrite.oäexit.ocsv.ocerror.o,savr5$” _exit"_main"_duic$x_fd$z_mfdp$|_ufd$~_ufdp$�_textb$’# /* * getdos file [n m] */ /* * d.c.anderson nov,1975 */ /* global variables */ int duic; /* dos uic code */ int fd; /* file descriptor */ int binary; /* set if no cr,lf to be done */ struct mfdent { /* mfd entry structure */ int uic; int firstb; int ufdsize; int ignore; } *mfdp; struct ufdent { /* ufd entry structure */ int name[2]; int ext; int date; int ebp; int head; int length; int tail; int prot; } ufd, *ufdp; struct block { /* dos disk block structure */ int link; char text[510]; } textb; main(argc,argv) int argc; char *argv[]; { char *file, unit, *fp; register int mfd1, jp; if( argc<2){ printf("arg count\n"); exit(1); } fp= argv[1]; file="/dev/tap0"; jp=1; mfd1=64; unit='0'; if( *fp == '-' ) { while( *(++fp) ){ switch( *fp ){ case 't': file="/dev/tap0"; mfd1=64; continue; case 'd': file="/dev/rrk1"; mfd1=1;continue; case '0': case '1': case '2': case '3': unit = *fp;continue; case 'b': binary++; continue; default: { printf("bad option: %c\n",*fp); exit(1);} } } jp=2; } file[8]= unit; if( (fd=open(file,0))<0) { printf("open failed\n"); exit(1);} if( dosname(argv[jp],ufd.name )){ printf("bad name\n"); exit(1);} duic=0401; if( argc ==(jp+3)) duic=atoo(argv[jp+1])<<8 | atoo(argv[jp+2]); getb(mfd1); getb(textb.link); /* -- search for the uic */ mfdp=textb.text; while( (mfdp++)->uic != duic ) { if( mfdp > textb.text+510){ if( textb.link ==0) { printf("can not find uic\n"); exit();} getb(textb.link); mfdp=textb.text;} } /* -- found the uic */ getb( (--mfdp)->firstb ); ufdp= textb.text; while( ufdp->name[0] != ufd.name[0] || ufdp->name[1]!= ufd.name[1] || ufdp->ext != ufd.ext ){ if( (++ufdp)>textb.text+510){ if( textb.link==0){ printf("can not find file\n");exit();} getb(textb.link); ufdp=textb.text;} } /* found the file */ if( ufdp->date & 0100000){ printf("linked files only\n"); exit(1);} rdfile(); exit(); } /* * dosname - convert ascii to r50 name */ dosname(s,n) char *s; int n[]; { register char *cp; cp=s; n[1]=n[2]=0; if( r50(*cp)==0) return(1); cp=pack1(cp,&n[0]); cp=pack1(cp,&n[1]); if( *cp++ != '.') return(0); pack1(cp,&n[2]); return(0); } /* * pack1 -- return a radix 50 packed name */ pack1(s,n) char *s; int n[]; { register int j,val,r; char *p; p=s; j=val=0; while( j<3 && (r=r50(*p)) ){ val = val*40 + r; j++; p++; } for(; j<3; j++) val=* 40; n[0]=val; return(p); } /* * */ r50(c) int c; { if( c>='a' && c<='z') return( c-'a'+1); if( c>='0' && c<='9') return( c-'0'+30); return(0); } /* * */ getb(bn) int bn; { if( bn<0 || bn>4872){ printf("bad block number\n"); exit(1);} if( seek(fd,bn,3) < 0) { printf("seek failed\n"); exit(1);} if( read(fd,&textb,512) < 0 ) { printf("read failed\n"); exit(1);} } /* * ascii to octal conversion from cp */ atoo(s) char *s; { register int num,c; register char *p; p=s; num=0; while( (c= *p++) >= '0' && c<'8'){ num = num*8 + (c-'0'); } return(num); } /* * read a file , xfer to file 1 */ rdfile() { register int endb; register int len; register char *p; endb= ufdp->ebp; len= ufdp->length; textb.link = ufdp->head; while( textb.link ){ if( len-- <= 0) { printf("corrupted file\n"); exit(1);} getb(textb.link); if( binary == 0) for(p=textb.text; plength; textb.link = ufdp->head; while( textb.link ){ if( len-- <= 0) { printf("corrupted file\n"); exit(1);} getb(textb.link); if( binary == 0) for(p=textb.text; p= NDJ11) { u.u_error = ENXIO; return; } tp = &DJ11[dev.d_minor]; if(u.u_procp->p_ttyp == 0) u.u_procp->p_ttyp = tp; tp->t_addr = djstart; /* a special start routine */ tp->t_dev = dev; if((tp->t_state&ISOPEN) == 0) { tp->t_state = SSTART | ISOPEN | CARR_ON; tp->t_flags = XTABS | LCASE | ECHO | CRMOD; tp->t_erase = CERASE; tp->t_kill = CKILL; } DJADDR->djcsr = DJTIE | DJTSE | DJRE | DJRIE; } djclose(dev) { register struct tty *tp; tp = &DJ11[dev.d_minor]; wflushtty(tp); tp->t_state = 0; } djread(dev) { ttread(&DJ11[dev.d_minor]); } djwrite(dev) { ttwrite(&DJ11[dev.d_minor]); } djstart(atp) struct tty *atp; { /* enable xmitter for this line */ DJADDR->djtcr =| 1<<(atp-DJ11); } djxint(dev) { register int c; register struct tty *tp; while (DJADDR->djcsr&DJTR) /*loop till xmitter happy */ { c = DJADDR->djtbuf; tp = &DJ11[c>>8]; if((c = getc(&tp->t_outq)) >= 0) DJADDR->djtbuf = c + (partab[c]&0200); else DJADDR->djtcr =& ~(1<<(tp-DJ11)); /*turn it off*/ if(tp->t_outq.c_cc == 0 || tp->t_outq.c_cc == TTLOWAT) wakeup(&tp->t_outq); } } djrint(dev) { register int c, *addr; register struct tty *tp; while (DJADDR->djrbuf) /*loop till fifo empty*/ { c = DJADDR->djrbuf; if(c&ERRFLAG) return; tp = &DJ11[(c>>8)&017]; /*line number*/ c =& 0177; ttyinput(c,tp); } } djsgtty(dev,v) int *v; { register struct tty *tp; tp = &DJ11[dev.d_minor]; ttystty(tp,v); } c + (partab[c]&0200); else DJADDR->djtcr =& ~(1<<(tp-DJ11)); /*turn it off*/ if(tp->t_outq.c_cc == 0 || tp->t_outq.c_cc == TTLOWAT) wakeup(&tp->t_outq); } } djrint(dev) { register int c, *addr; register struct tty *tp; while (DJADDR->djrbuf) /*loop till fifo empt# /* * dr11-c word driver */ #include "../param.h" #include "../user.h" #include "../conf.h" #include "../tty.h" #define DRADDR 0167770 #define PDR 9 /* number of dr11's */ #define NDR11 2 #define DRHIWAT 50 #define DRLOWAT 14 /* control bits */ #define INPRDY 0100000 #define OUTRDY 0000200 #define OUTINT 0000100 #define INPINT 0000040 struct { /*dr11 registers */ int csr; int xbuf; int rbuf; }; struct dr { /* dr control structure */ int lock; /* 1=opened */ int addr; struct clist inpq; /* input character queue */ struct clist outq; /* output character queue */ }; struct dr dr11[NDR11]; dropen(dev,flag) { register struct dr *p; register int *add,junk; if ( dev.d_minor >= NDR11 ) { u.u_error = ENXIO; return; } p= &dr11[dev.d_minor]; if( p-> lock ==0){ p-> lock++; p->addr=add= DRADDR - (dev.d_minor*8); junk=add->rbuf; /* clear any hanging input */ add->csr= (INPINT | OUTINT); } else u.u_error = ENXIO; } drclose(dev) { extern lbolt; register struct dr *p; p= &dr11[dev.d_minor]; while( p->outq.c_cc) sleep( &lbolt,PDR); while( getc(&p->inpq) >= 0); p->lock=0; (p->addr)->csr=0; } drwrite(dev) { register struct dr *p; register c,w; extern lbolt; p= &dr11[dev.d_minor]; w=0; while( (c=cpass()) >= 0){ spl5(); while( p->outq.c_cc > DRHIWAT) sleep(&p->outq,PDR); while( putc(c,&p->outq) < 0) sleep( &lbolt,PDR); if( ++w == 2){ w=0; drxint(dev); } spl0(); } } drread(dev) { register struct dr *p; register c,w; p= &dr11[dev.d_minor]; spl5(); do{ while( (c=getc(&p->inpq))<0) sleep(&p->inpq,PDR); } while ( passc(c) >= 0); spl0(); } drxint(dev) { register struct dr *p; register int c,w; p= &dr11[dev.d_minor]; if( ((p->addr)->csr & OUTRDY) ==0) return; if( (w= (p->outq.c_cc)) >= 2){ (p->addr)->xbuf = (getc(&p->outq)<<8) | getc(&p->outq); (p->addr)->csr =| OUTINT; if( (w=-2)==0 || w==DRLOWAT) wakeup(&p->outq); } else (p->addr)->csr =& ~OUTINT; } drrint(dev) { register struct dr *p; register int c,w; p= &dr11[dev.d_minor]; w= (p->addr)->rbuf; putc(w,&p->inpq); putc(w>>8, &p->inpq); wakeup(&p->inpq); } spl0(); } drxint(dev) { register struct dr *p; register int c,w; p= &dr11[dev.d_minor]; if( ((p->addr)->csr & OUTRDY) ==0) return; if( (w= (p->outq.c_cc)) >= 2){ (p->addr)->xbuf = (getc(&p->outq)<<8) | getc(&p->outq); (p->addr)->csr =| OUTINT; if( (w=-2)==0 || w==DRLOWAT) wakeup(&p->outq); } else (p->addr)->csr =& ~OUTINT; } drrint(dev) { register struct dr *p; register int c,w; p= &dr11[dev.d_min# /* */ /* * general TTY subroutines * modified for 8 bit i/o by d.anderson, may 27,1976 */ #include "../param.h" #include "../systm.h" #include "../user.h" #include "../tty.h" #include "../proc.h" #include "../inode.h" #include "../file.h" #include "../reg.h" #include "../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; /* * 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. */ sgtty(v) int *v; { register struct file *fp; register struct inode *ip; if ((fp = getf(u.u_ar0[R0])) == NULL) return; ip = fp->f_inode; if ((ip->i_mode&IFMT) != IFCHR) { u.u_error = ENOTTY; return; } (*cdevsw[ip->i_addr[0].d_major].d_sgtty)(ip->i_addr[0], v); } /* * Wait for output to drain, then flush input waiting. */ wflushtty(atp) struct tty *atp; { register struct tty *tp; tp = atp; spl5(); while (tp->t_outq.c_cc) { tp->t_state =| ASLEEP; sleep(&tp->t_outq, TTOPRI); } flushtty(tp); spl0(); } /* * Initialize clist by freeing all character blocks, then count * number of character devices. (Once-only routine) */ cinit() { register int ccp; register struct cblock *cp; register struct cdevsw *cdp; ccp = cfree; for (cp=(ccp+07)&~07; cp <= &cfree[NCLIST-1]; cp++) { cp->c_next = cfreelist; cfreelist = cp; } ccp = 0; for(cdp = cdevsw; cdp->d_open; cdp++) ccp++; nchrdev = ccp; } /* * 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( tp->t_flags&RAW) { tp->t_delct--; putc(c,&tp->t_canq); return(1); } if (c==0377) { tp->t_delct--; break; } if (bp[-1]!='\\') { if (c==tp->t_erase) { if (bp > &canonb[2]) bp--; continue; } if (c==tp->t_kill) goto loop; if (c==CEOT) continue; } else if (maptab[c] && (maptab[c]==c || (tp->t_flags&LCASE))) { if (bp[-2] != '\\') c = maptab[c]; bp--; } *bp++ = c; if (bp>=canonb+CANBSIZ) break; } bp1 = bp; bp = &canonb[2]; c = &tp->t_canq; while (bpt_flags; if( t_flags & RAW ) goto skip; if ((c =& 0177) == '\r' && t_flags&CRMOD) c = '\n'; if ((t_flags&RAW)==0 && (c==CQUIT || c==CINTR)) { signal(tp, c==CINTR? SIGINT:SIGQIT); flushtty(tp); return; } if(t_flags&LCASE && c>='A' && c<='Z') c =+ 'a'-'A'; skip: if (tp->t_rawq.c_cc>=TTYHOG) { flushtty(tp); return; } putc(c, &tp->t_rawq); if (t_flags&RAW || c=='\n' || c==004) { wakeup(&tp->t_rawq); if ( t_flags&RAW ||(putc(0377, &tp->t_rawq)==0)) tp->t_delct++; } if( t_flags&RAW) return; 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; if( rtp->t_flags&RAW) { putc(ac,&rtp->t_outq); return; } 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) { colp = "({)}!|^~'`"; while(*colp++) if(c == *colp++) { ttyoutput('\\', rtp); c = colp[-2]; break; } if ('a'<=c && c<='z') c =+ 'A' - 'a'; } /* * turn to 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; /* 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 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 startup routine. */ ttstart(atp) struct tty *atp; { register int *addr, c; register struct tty *tp; struct { int (*func)(); }; tp = atp; addr = tp->t_addr; if (tp->t_state&SSTART) { (*addr.func)(tp); return; } if ((addr->tttcsr&DONE)==0 || tp->t_state&TIMEOUT) return; if ((c=getc(&tp->t_outq)) >= 0) { if( tp->t_flags&RAW) { addr->tttbuf = c; return; } if (c<=0177) addr->tttbuf = c | (partab[c]&0200); else { timeout(ttrstrt, tp, c&0177); tp->t_state =| TIMEOUT; } } } /* * Called from device's read routine after it has * calculated the tty-structure given as argument. * The pc is backed up for the duration of this call. * In case of a caught interrupt, an RTI will re-execute. */ ttread(atp) struct tty *atp; { register struct tty *tp; tp = atp; if ((tp->t_state&CARR_ON)==0) return; if (tp->t_canq.c_cc || canon(tp)) while (tp->t_canq.c_cc && passc(getc(&tp->t_canq))>=0); } /* * Called from the device's write routine after it has * calculated the tty-structure given as argument. */ 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 information 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); } /old = sbrk(increment); / modified by dca, 12-aug-76 to check overflow condition. / /sbrk gets increment more core, and returns a pointer / to the beginning of the new core area / .globl _sbrk,_end, cerror _sbrk: mov r5,-(sp) mov sp,r5 mov nd,0f add 4(r5),0f bcs 2f / *** sys 0; 9f bec 1f 2: / *** jmp cerror 1: mov nd,r0 add 4(r5),nd mov (sp)+,r5 rts pc .globl _brk / brk(value) / as described in man2. / returns 0 for ok, -1 for error. _brk: mov r5,-(sp) mov sp,r5 mov 4(r5),0f sys 0; 9f bec 1f jmp cerror 1: mov 4(r5),nd clr r0 mov (sp)+,r5 rts pc .data 9: sys break; 0:.. nd: _end nt more core, and returns a pointer / to the beginning of the new core area / .globl _sbrk,_end, cerror _sbrk: mov r5,-(sp) mov sp,r5 mov nd,0f add 4(r5),0f bcs 2f / *** sys 0; 9f bec 1f 2: / *** jmp cerror 1: mov nd,r0 add 4(r5),nd mov (sp)+,r5 rts pc .globl _brk / brk(value) / as described in man2. / returns 0 for ok, -1 for error. _brk: mov r5,-(sp) mov sp,r5 mov 4(r5),0f sys 0; 9f 4 i4i2 .+2 sys signal; 2; 1 ror r0 bcs 1f sys signal; 2; restor 1: mov (sp),r0 mov r0,ifdw sys gtty; oldw mov (sp)+,r0 sys stty; raw mov (sp),r0 mov r0,ifdr sys gtty; oldr mov (sp)+,r0 sys stty; raw jmp retrn / / restore- internal routine to restore old tty modes / restore: mov ifdr,r0 sys stty; oldr mov ifdw,r0 sys stty; oldw rts pc restor: jsr pc,restore sys exit .globl calout. calout.: temp .+2 jsr pc,restore jmp retrn .data oldr: .=.+6 oldw: .=.+6 raw: 0; 0; 40 ifdr: 0 ifdw: 0 temp: 0;0 sys signal; 2; 1 ror r0 bcs 1f sys signal; 2; restor 1: mov (sp),r0 mov r0,ifdw sys gtty; oldw mov (sp)+,r0 sys stty; raw mov (sp),r0 mov r0,ifdr sys gtty; oldr mov (sp)+,r0 sys stty; raw jmp retrn / / restore- internal routine to restore old tty modes / restore: mov ifdr,r0 sys stty; oldr mov ifdw,r0 sys stty; oldw rts pc restor: jsr pc,restore sys exit .globl calout. calout.: temp .+2 jsr pc,restore jmp retrn .data oldr: .=.+6 oldw: .=.+6 raw: 0; 0; 40 ifdr: 0 ifdw/ tty control package .globl retrn / / stat(name,buf) / integer stat / integer*2 buf(18) / integer*1 name(??) / .globl stat. stat.: temp lvalp; 2 lvalp; 4 .+2 mov (sp)+,1f /buf mov (sp)+,0f sys stat; 0:.. ; 1:.. br ret / / stty(ifd,iarg) / integer ifd,stty / integer*2 iarg(3) / .globl stty. stty.: temp rval4p; 2 i4i2 lvalp; 4 .+2 mov (sp)+,0f mov (sp)+,r0 sys stty; 0:.. br ret / / gtty(ifd,iarg) / integer ifd,gtty / integer*2 iarg(3) / .globl gtty. gtty.: temp rval4p; 2 i4i2 lvalp; 4 .+2 mov (sp)+,0f mov (sp)+,r0 sys gtty; 0:.. ret: bec 1f mov $-1,r0 1: mov r0,temp+2 sxt temp jmp retrn .data temp: 0; 0 emp lvalp; 2 lvalp; 4 .+2 mov (sp)+,1f /buf mov (sp)+,0f sys stat; 0:.. ; 1:.. br ret / / stty(ifd,iarg) / integer ifd,stty / integer*2 iarg(3) / .globl stty. stty.: temp rval4p; 2 i4i2 lvalp; 4 .+2 mov (sp)+,0f mov (sp)+,r0 sys stty; 0:.. br ret / / gtty(ifd,iarg) / integer ifd,gtty / integer*2 iarg(3) / .globl gtty. gtty.: temp rval4p; 2 i4i2 lvalpmÿaxis.o8 \ ¶@öæxøÜ– Þܘܖ ÞÜœ š ÜÞܤÜÞàžâÞÞœàÜž¨ÜÞà¢âÞ¢Þ¢àÜž¬ ¦°ÜªÞàâààâ°äââÞÞÜ´´¸´¼´œž´¸ž¼¼¸¼œ¼®Öž¼¸¼´¸²¶¼º¸¼À¨¬~4˜¨¬†TœÄ¨¬~4œ¨¬†T˜ÈÀÌД¤Ð°ÜÄÞÈà¾âÌä æ¼0üèÜĘÄÈœÈÌÀ̘°˜Ô°œØÔ¨,œÄب,˜ÈÜÄÞÈàÂâÜО¼Ð°jÜÔÞØà¶âÜÔ˜ÔØœØÜÔÞØà¶âÜĘÄÈœÈÜÄÞÈà¶âܰưʤÎÜÞ¸¼àÞÞžàÜ  ˜¨¬ŽtœÄ œ¨¬Žt˜ÈÜÄÞÈàÒâä æ¤èܸ¼hÄÖ¤ž˜ÄÈÖ¤žœÈÜÄÞÈàÒâÚä æâèÜÄæ˜êœÄÈæœê˜ÈÜÄÞÈà¾â¸¼ä æîèÜŽ=5ú´C}@£pÈCƒ8·H BÌ>ÌÌ@u>�Â×?= ?(\õ>�Â(x10 ) õ?�Â�>(\(f3.0) (f6.4) (f6.3) (f6.2) (f6.1) (f6.0) (f6.0) ̾ÌÌÌ>ÌÌ€¿€¿L>ÌÌL>ÌÌ€?€?L¾ÌÌL¾ÌÌ€¿?™™&Àff?™™¿™™€?¿™™&@ffÜ¿õ(”?ázTÀáz0@ףܿõ(”?ázTÀáz0@×£(Hhˆ(˜¨¸(Hhˆ(˜è¸hHh(ˆ8¸(h(˜h¸((h(H(˜˜(H(˜¸Hظ((h(H(˜HØ(H(˜HظhH8x¸(H((h(˜¸((hH(hˆ8(˜¸(˜Øˆ(˜è¸Hx¸Hx¸HH8HXHHˆ¸H¸HH¨HHÈØHH¸HHøHH(H8(HH¸HHHˆX¸hHHˆHˆ8HHˆHˆØ¸hHHˆHˆ8HHˆHˆ8¸hH¸8HhX8Hˆ(8¨8¨8¨8¨8¨HȨ˜èHH8¸HH8¸HhH8¸XhH(Hˆ8¸hH(Hˆ8¸HH(HˆØ¸HH(Hˆ8¸(8¨8¨8¨˜X8HhX8Hˆ(8¨8¨8¨˜XHHظHHظ(8¨8¨8¨˜XHHظHHظ(8¨8¨8¨˜XXHH(ˆHH(ˆØH((HHˆ(˜h(H(˜ˆØ¸hHHˆ8HHˆHˆØ¸hHHˆ8HHˆHˆ8¸(8¨8¨8¨X¨X¨8¨˜xHHˆH˜HHHHØ(ˆHˆ8¸HHHHØ(ˆHˆ8¸(8¨8¨8¨8¨X¨8¨˜xHHHˆ8HHˆØ¸HHHˆ8HHˆ8¸(8¨8¨8¨HHˆ(X¨8¨˜è˜˜axis."axis_østsp ftÜrval4 c0–rval4p angle_ rmp4 call cos. gmv4 c_˜c1–sin. s_œc2šlrot_i4r4 rad4 t_ ns_iabs. k_¤c3žmin0. c4œmax0. c5žiad4 l_¨c6¢mod. c7¢c8¢c9žm_¬size_ c10¦r4i4 n_°c11ªzmin_abs. zdel_amax1. alog10. axp_´ixp_¸jxp_¼c12œrge4 lif2 goto .10´c13žisb4 c14œile4 c15®igt4 lor2 c16žine4 c17²rlt4 lan2 c18¶c19ºrpi4 d_Àx_arval d2~xx_4d3†yy_Trsb4 xa_Äy_ya_Èrdv4 za_Ìlval i_Ðizero_”gas4 t0˜do14 o0stst c20¾gal8 format_ünumber. .100xb_Ôyb_Øgar4 ww_,c21Âplot. c22žt1°o1jc23¶c24¶.200@c25¶c26Æc27Êc28Îc29žamin0. d4Žzz_tc30Òlvalp string_symbol. ieq4 retrn c31Öc32žc33Öc34žc35Òc36Úc37âc38æc39êc40æc41êc42¾c43îd0rd1xbaseöline.o8 ò5 ¶œ~@�Ž’’f––ššZjš`jXnž ¢ jzŒ¢¢ržfZ–ZšZ¦f`–`š`ª~¦€ª‚r„~j®²f$²’V®f®²Z–ZšZ¶²`–`š`º j�ª¢®¢Rj®~¶€º‚ž„~ jâR~¶v€ºv‚z„ †jˆfŠ~~¶€º‚r„~�>(\?(\((Xhˆˆ¨hˆ(¨hˆØˆ(ˆØˆ(hxˆˆh(h(ˆèxøˆhˆhˆØˆØHˆØXhˆØˆØHˆØXh˜¸È¸È¸Èèøˆh¸ˆHø¸ˆ(hˆˆ¨hˆØˆØHˆØXhˆØˆØHˆØXh(ˆÈxøˆˆèxøˆh˜¸È¸È¸Èèø(ˆÈxø˜ˆˆH˜ˆˆH˜¸ÈXȸȸÈ蘘¸È¸È¸Èèøøˆˆline."line_Žrval4p n_k_imp4 gmv4 n1_’rval4 c0fiad4 im_–id_šarvalp d0Zx_c1ji4r4 req4 d1`y_c2jlor2 lif2 retrn c3nipen_žj_ m_¢c4jige4 goto .10Œing4 c5rc6frsb4 rdv4 x1_¦c7fy1_ªstsp ft~lval stst c8rcall plot. c9jjcnt_®i_²c10fgas4 t0do24 o0Vc11fxp_¶yp_ºc12jieq4 .20ªine4 .30Rc13jc14jc15vc16vc17zlvalp ocsym_ c18jc19fsymbol. c20rbaseŒnumber.o8 +Y ¶tþfâfæ4fdâæ fâdfæ’êfjjd⎔Xîðòôö øjúîdde(Hhx(H¨HØH(xHH(hHˆ˜(Hhx(H¨HHøH(8HXhxx˜¨HØHØHØ(ØHØ(Ø(˜˜number."number_þlval i_frval4 c0âgas4 goto t0c1ædo14 o04.1gal1 iwk_c2âing4 i4i1 gas1 c3ælvalp format_ encod rnum_rio4 endio c4ât1Xc5æo1’c6êisb4 gmv4 n_jgar1 i1i4 c7âine4 lif2 .3”.2Žretrn stsp ftîx_stst y_height_angle_ call symbol. d0Öd1Übaseüsymbol.o8 ^6 ¶ ¼D�¾| € € �$& ”„ „  ˆ „  Œ � ” € ˜Š| œ˜ �  ˜ Œ ˆ � ”  ˜ Œ ˆ ” ˜€ ˜ô¤œ | ¨˜ ¬œ ˜ Œ   ˜ ˆ ¤   °¨ ¤ °¬ ˜° ˜´ € ¤rì € ˜ ¸ � ¨ ¸ ¼ ” ¬ ¸ À Ä  È  Ì    � Ä     ” È    Ð  ¼ Ä     À È    Ô Ð Ô šì€ ´ ˜° ¼ ¨ Ø À ¬ Ü ¼ � À ” ¨ ¨ ¬ ¬ à ˜à € t´ x˜ä ´ ° ´ ä |è è �JLä | ì ð ˜rð è Lì 𠘺Âô ô ´¨ø ø ¸º@ô ¨ü �   ø ¤ ü ¼ ” ¤ ø   ü À ¼  À  œ  ¤œ H¬œ f� ¨ � ” ¬ ” ¬œ úº€€Ž=˜ù€AAÀAàA $ !# " $""$ $8 $$    $"$  # "   8"8$"" 8$8 ! $8! !8#8 8        " 8  888"8$ "#%8 8'8 " #%!##'!&8&$ &% #!#!#' #!&'& &% #!&$ &!88"&$8!$&%8  !% #& &%#!!&&!' '#!&%$ '!''8 '  ''!&&%!&8 &% !# &'!'&' ''8 '' 8 $ ' ' &                ")08@GN\iosy{}‚‡�”¢¨«³»ÄÉÏÕÛááéîù!%)49?AFHSXant~‹�¡®¹ÅÈÍÐßî÷ *06<DGLP[box…‰�•šŸ¤«¯±µ¸(H(Hˆˆ¨¸Èø(ˆ(HHˆHhxHHˆHh˜H(H(Hˆˆ¸ÈˆˆHHˆˆˆ(ˆˆx(xHˆˆˆ(ˆˆ˜(xHˆH(ˆÈ¸ÈˆHȈˆ8HHˆHˆˆ(Hˆˆ(Hˆˆ(Hˆˆ(HˆHˆHˆˆ¸ÈHˆˆHHhXHˆˆˆ(˜Hˆˆˆ(˜HH˜¸˜¸˜¸hèHHˆˆxHhøHHˆˆxHhøHh8HHHˆˆxHhøHHˆˆxHhøHh8Hˆˆ8¸ÈˆHˆÈHˆˆ˜Hˆˆ˜HˆHˆHˆˆHˆˆH˜ˆ¸È˜ˆØˆø(ˆHHˆˆHHˆhHˆˆ¨¸ÈˆhH˜ˆ¸È˜ˆØˆˆHˆH8(Hˆˆxˆˆˆ¨¸Hˆˆè¸Èˆˆˆˆ¨¸Hˆˆˆ(˜ˆˆ(xHˆˆˆ(˜ˆˆ(˜HH˜¸˜¸˜¸h(ˆHȈHȈˆ˜Hˆˆ˜HˆHÈøøsymbol."symbol_¾rval4p height_gmv4 h_| nchar_ nc_€ rval4 c0�ine4 lif2 goto .20&.10$retrn theta_ c1”rmp4 th_„ stsp ft call sin. si_ˆ cos. co_Œ x1_x_� y1_y_” c2˜ige4 .50.30Šc3œrdv4 fact_˜ c4 rsb4 c5 rad4 c6˜c7˜ing4 .60.40ôc8¤ic_œ .70c9¨i4r4 c10¬xa_  ya_¤ c11°xt_¨ c12°yt_¬ c13˜idel_° c14˜j_´ c15¤ile4 .100ì.80rc16˜isb4 float. stlen_¸ xn_¼ yn_À lval xnow_Ä stst ynow_È g_Ì where. abs. max1. del1_Ð del2_Ô rlt4 .90šc17˜xk_Ø yk_Ü rng4 ii_à c18˜gas4 t0údo14 o0tarvalp d0xbcd_i1i4 c19˜iad4 itsub_ä gar4 kct_|ict_è c20�ieq4 .200Lkoc_| loc_ì i_ð c21˜t1fo1Lc22˜gar1 ifont_Âiy_ô c23´idv4 i4l2 c24¨ian4 l2r4 xx_ø c25¸req4 .110@c26¨yy_ü plot. c27¤.115Hc28¬c29¬.210pd1~d2„d3Šbase¼where.o8 i6 ¶ˆ>ü@::úD(8X((8ˆ˜¨(8X((8ˆ˜¨(8¨where."where_@rval4 _com502 xcur_i4r4 c0:fact_rmp4 rdv4 gmv4p x_ycur_c1:y_factr_retrn base>xorg_yorg_ istate_factor.o8 ã5 ¶Ô¨(HXxxfactor."factor_rval4p factr_gmv4 _com502 fact_retrn basexcur_ycur_xorg_yorg_ istate_plot.oo8 ýX ¶$ t*,~6tt:0">B:V€BjÔF‚F†‚Іނ†’ÖôôHH’H–’6L–’P(6–t–vttŠvttvŠxTzvvttŽvttvŽxTzvvtX\ìt`vttšvtHdH<pt`vttšvtHttH’¾t`vttšvthtlvttšvttpvt(021h type cr to continue )çåæúDÙ80(8(hxˆ¨¸È(øxÈ(øxÈ(XøxÈ(XøxÈ(¸(8¸ØèÈ(¸(8¸Øè((8Hè((8Hè(è8(è8ÈèȘ(Øè8(Øè8ÈXè(è((øx(è((øx(èˆHX¨hˆHX¨hˆˆHX(Xˆ¨ˆˆ¨hˆHX¨hˆˆHX(Xˆ¨ˆˆ¨h(¨(Øè¨(¨(øxˆHX¨hˆHX¨8(è¨(è8(¨(øxˆHX¨hˆHX¨8(計¨¨(¨(ÈxˆHX¨hˆHX¨8(HH(8ˆHX¨hˆHX¨8ˆHX¨hplot."plot_~rval4 _com502 istate_c06ine4 lif2 stsp fttcall plots. rval4p ip_c1:ieq4 goto .4"c2>.8c3:ing4 .5€c4B.7Ôx_c5Frmp4 fact_r4i4 gmv4 ix_‚y_c6Fiy_†xcur_isb4 idx_Šycur_idy_Žipc_’iif4 .1Ö.2ôc7Hc8Hc9Hline_–c106c11Lc12Pc136lval stst xdl. c14Tishift. c15T_bufcon bytcnt_c16Xiad4 c17\ilt4 retrn c18`iack_šrdl. c19Hc20dc21H.91pc22`c23Hcalout. c24Hile4 .903¾c25`c26h.901iowf endio paus c27lc28pbase|xorg_yorg_ plots.o8 6 ¶d`”h`<bHd`l`<bLd`plLpLd|PçLLLL T`pbld`LÞP'X`\b`L(024h can not open /dev/tty1 )(013h calin failed)/dev/tty1 €@08XxXx˜¨¸8XxXx˜¨¸((HXhXX¨¸Èh¸è¸è¸è¸è¸è8XxXx˜ˆ¨¸XXX¨¸¸è8Xx˜¸8XXplots."plots_h.1stsp ft`lval c0<stst c1Hcall open. gmv4 ifdw_lc2<c3Lifdr_prval4 c4Ligt4 c5Llan2 lif2 goto .2|c6P.100iowf endio paus c7L_com502 xcur_c8Lycur_c9Lxorg_c10Lyorg_ c11Tfact_calin. c12Li4r4 rne4 c13P.101'c14Xistate_c15\xdl. c16L_bufcon bytcnt_retrn basefscale.o8 ,6 ¶T  :�¢²|p¶|pº¾|J¾²žÚ¾pܶÞÚ¶Ú¾pܺÞÚº:€Â„ƈ¶ºÊÊ€äˆÊ¾|þ¾Œ�Úʾ ¦ÜÚÎ΀FÎ�ξ ¦”ÚÎÜÚÒÒÆ„ÒÚ˜ºÒÜÚÖºÖÌÖÒÖ˜ÒÖ¶ðÖÂÒÆò²|pÂÆÚ¶ºÆœÜÚ²|pÆð}½@Xÿ€@ B€@SA€@A A((Xhˆ¨hˆ¨hˆ8Hˆ(hˆˆ¨ˆˆˆ¨¸hˆˆ¨ˆˆˆ¨ØhHˆhˆhˆˆˆ8H(hhˆˆ˜¨ˆ(hhˆ8Hˆøˆˆˆˆ(hˆ¨HXhˆˆˆ¨ˆˆ8hˆ(ˆˆˆˆ¨¸ÈHhˆˆè¨HˆˆˆˆHˆhˆ¨Hhˆˆˆ¨ˆˆ8hˆ(HˆHˆXˆˆ¨HˆhˆhHˆˆXhˆˆˆ(ˆˆ8ˆh8ˆhˆ¨H88ˆ(XˆXhˆ8˜˜scale."scale_¢rval4p n_k_imp4 gmv4 m_²rval4 c0|arvalp d0px_xmax_¶c1|xmin_ºlval i_¾c2|gas4 goto t0:do24 o0žstsp ftÚcall amax1. .5ramin1. c3€x0_Âc4„dx_Æc5ˆrsb4 rmp4 s_rdv4 w_Êc6€req4 lif2 c7ˆc8|t1òc9Œdo14 o1c10�gar4 t_¦alog10. rad4 b_Îc11€rlt4 c12�c13”ifix. rpi4 c_Òrgt4 .21c14˜aint. d_Öc15˜c16|iad4 alvalp c17œc18|retrn d1vbase dlio.o8 q6 ¶`®ÀÄÀ7¶À°‰Ä Ä÷ ÷eÀ’‰†Àÿÿ7ˆ÷ ‚wºÿÄV0‰ ‡0‰œ€7V ‰´€‰º€7D ‰®€‰ºwvÿÀ2‰®À,‰´‡÷ êÿ‰Ä¦÷ àÿwRÿ  ˆ˜ˆ˜  retrn xdl."tempÄifdwÂret4rdl."ifdrÀcalin."Frval4p i4i2 restorœoldw´rawºoldr®restoreŠcalout."¢ishift.o8 y6 ¶” < €�v7wwàÿ8H8 retrn ishift."temp rval4p i4i2  ˆ˜ˆ˜‰² ²"Îe·À€‰†Àÿÿ7v÷ pwºÿ²V0‰ ‡0‰Š€7D ‰¢€‰¨€72 ‰œ€‰¨wvÿÀ ‰œÀ‰¢‰ 8Hˆ 8H8H retrn xdl."temp²rval4p i4i2 ifdr®ret4rdl."lvalp calin."FrestoreŠifdw°oldw¢raw¨oldrœ"Îe·À€‰†Àÿÿ7v÷ pwºÿ²V0‰ ‡0‰Š€7D ‰¢€‰¨€72 ‰œ€‰¨wvÿÀ ‰œÀ‰¢‰ 8Hˆ 8H8H retrn xdl."temp²rval4p i4i2 ifdr®ret4rdl."lvalp calin."FrestoreŠifdw°oldw¢raw: assemble calcomp library fc -c *.f as - dlio.s; mv a.out dlio.o ar r cal.a number.o symbol.o where.o ar r cal.a axis.o factor.o line.o plot.o ar r cal.a plots.o scale.o dlio.o rm *.o ˆ 8H8H retrn xdl."temp²rval4p i4i2 ifdr®ret4rdl."lvalp calin."FrestoreŠifdw°oldw¢raw/ tty control package .globl retrn / / stat(name,buf) / integer stat / integer*2 buf(18) / integer*1 name(??) / .globl stat. stat.: temp lvalp; 2 lvalp; 4 .+2 mov (sp)+,1f /buf mov (sp)+,0f sys stat; 0:.. ; 1:.. br ret / / stty(ifd,iarg) / integer ifd,stty / integer*2 iarg(3) / .globl stty. stty.: temp rval4p; 2 i4i2 lvalp; 4 .+2 mov (sp)+,0f mov (sp)+,r0 sys stty; 0:.. br ret / / gtty(ifd,iarg) / integer ifd,gtty / integer*2 iarg(3) / .globl gtty. gtty.: temp rval4p; 2 i4i2 lvalp; 4 .+2 mov (sp)+,0f mov (sp)+,r0 sys gtty; 0:.. ret: bec 1f mov $-1,r0 1: mov r0,temp+2 sxt temp jmp retrn .data temp: 0; 0 emp lvalp; 2 lvalp; 4 .+2 mov (sp)+,1f /buf mov (sp)+,0f sys stat; 0:.. ; 1:.. br ret / / stty(ifd,iarg) / integer ifd,stty / integer*2 iarg(3) / .globl stty. stty.: temp rval4p; 2 i4i2 lvalp; 4 .+2 mov (sp)+,0f mov (sp)+,r0 sys stty; 0:.. br ret / / gtty(ifd,iarg) / integer ifd,gtty / integer*2 iarg(3) / .globl gtty. gtty.: temp rval4p; 2 i4i2 lvalp