Check-in Differences
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Difference From:

[fab15b88a6] tweaks to mmu.s (net) and tty.c (raw mode) (user: pnr tags: trunk, date: 2020-01-27 18:17:23)

To:

[b95342aaa8] Proof of concept local IPC (user: pnr tags: FSS, date: 2020-05-18 19:59:04)

Changes to ccom/c11.c.

1077
1078
1079
1080
1081
1082
1083

1084
1085
1086
1087
1088
1089
1090
		outname(s);
		printf("%s:\n", s);
		break;

	case RLABEL:
		outname(s);
		printf("%s:\n", s);

		break;

	case BRANCH:
		branch(geti(), 0, 0);
		break;

	case SETREG:







>







1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
		outname(s);
		printf("%s:\n", s);
		break;

	case RLABEL:
		outname(s);
		printf("%s:\n", s);
		printf("~~%s:\n", s+1);
		break;

	case BRANCH:
		branch(geti(), 0, 0);
		break;

	case SETREG:

Changes to v6/Makefile.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
UFS	= ${INSTDIR}/bin/ufs


ASMOBJS = low.o mch.o mmu.o thunk.o drv_cf.o

UV6OBJS = alloc.o bio.o clock.o conf.o drv_tty.o tty.o dsk.o fio.o iget.o mem.o nami.o \
	pipe.o prf.o rdwri.o sig.o slp.o subr.o sys1.o sys2.o sys3.o sys4.o sysent.o \
	trap.o main.o malloc.o

.c.o:
	${CC} -c -DKERNEL -D${MODEL} -O -o $@ $<
.s.o:
	${AS} -u -o $@ $<

all: unix strip







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
UFS	= ${INSTDIR}/bin/ufs


ASMOBJS = low.o mch.o mmu.o thunk.o drv_cf.o

UV6OBJS = alloc.o bio.o clock.o conf.o drv_tty.o tty.o dsk.o fio.o iget.o mem.o nami.o \
	pipe.o prf.o rdwri.o sig.o slp.o subr.o sys1.o sys2.o sys3.o sys4.o sysent.o \
	trap.o main.o malloc.o pair.o

.c.o:
	${CC} -c -DKERNEL -D${MODEL} -O -o $@ $<
.s.o:
	${AS} -u -o $@ $<

all: unix strip

Changes to v6/alloc.c.

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

	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(dp = &ip->i_mode; dp < &ip->i_addr[8];)
				*dp++ = 0;
			fp->s_fmod = 1;
			return(ip);







|







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

	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, 0);
		if (ip==NULL)
			return(NULL);
		if(ip->i_mode == 0) {
			for(dp = &ip->i_mode; dp < &ip->i_addr[8];)
				*dp++ = 0;
			fp->s_fmod = 1;
			return(ip);

Changes to v6/conf.c.

42
43
44
45
46
47
48






















};

/* root file system device = {0, 0} */
int rootdev = 0;

/* start of swap space */
int swplo = NBLKS;





























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
};

/* root file system device = {0, 0} */
int rootdev = 0;

/* start of swap space */
int swplo = NBLKS;

extern int ufs_nami();
extern struct inode* openi(), nullopn();
/*
extern int prput(), prfree(), prupdat(), prread(), prwrite(), prtrunc();
extern int prstat(), prnami(), prmount(), prioctl();
extern struct inode *prget();
*/
extern nulldev(), nodev(), rdpair(), wrpair(), frepair();
extern struct inode *getpair();
extern sfsput(), sfsrd(), sfswr(), sfsnam(), sfsstat(), sfsfree();
extern struct inode *sfsget(), *sfsopn();

struct fstypsw fstypsw[3] = {
  { 0, 0, 0, 0, 0, 0, 0, 0, ufs_nami, 0, 0, openi},
/*  { prput, prget, prfree, prupdat, prread, prwrite, prtrunc,
		prstat, prnami, prmount, prioctl}, */
  { nulldev, getpair, frepair, nulldev, rdpair, wrpair, nulldev, nulldev, nodev, nodev, nulldev, nullopn },
  { sfsput, sfsget, sfsfree, nulldev, sfsrd, sfswr, nulldev, sfsstat, sfsnam, nodev, nulldev, sfsopn }
};

int	nfstyp = 3;

Changes to v6/conf.h.

49
50
51
52
53
54
55


















} cdevsw[];

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

























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
} cdevsw[];

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

/* file system types */
struct fstypsw {
	int		(*t_put)();
	struct inode	*(*t_get)();
	int		(*t_free)();
	int		(*t_updat)();
	int		(*t_read)();
	int		(*t_write)();
	int		(*t_trunc)();
	int		(*t_stat)();
	int		(*t_nami)();
	int		(*t_mount)();
	int		(*t_ioctl)();
	struct inode	*(*t_open)();
} fstypsw[];

int nfstyp;

Changes to v6/fio.c.

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/*
 * 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.
 */
void
openi(ip, rw)
	register struct inode *ip;
{
	register int dev, maj;

	dev = ip->i_addr[0];
	maj = ip->i_addr[0].d_major;
................................................................................
		(*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.
................................................................................
 */
struct inode*
owner()
{
	register struct inode *ip;
	extern int 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);







|







 







|







 







|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/*
 * 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.
 */
struct inode *
openi(ip, rw)
	register struct inode *ip;
{
	register int dev, maj;

	dev = ip->i_addr[0];
	maj = ip->i_addr[0].d_major;
................................................................................
		(*cdevsw[maj].d_open)(dev, rw);
		break;
	case IFBLK:
		if(maj >= nblkdev)
			goto bad;
		(*bdevsw[maj].d_open)(dev, rw);
	}
	return ip;

bad:
	u.u_error = ENXIO;
}

/*
 * Check mode permission on inode pointer.
................................................................................
 */
struct inode*
owner()
{
	register struct inode *ip;
	extern int uchar();

	if ((ip = namei(uchar, NI_SEARCH, 0)) == NULL)
		return(NULL);
	if(u.u_uid == ip->i_uid)
		return(ip);
	if (suser())
		return(ip);
	iput(ip);
	return(NULL);

Changes to v6/iget.c.

1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
..
21
22
23
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
..
64
65
66
67
68
69
70

71
72


73
74
75
76
77
78
79
...
100
101
102
103
104
105
106


107
108

109



110
111
112
113



114
115
116
117

118
119
120
121
122
123
124
...
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139




140
141
142
143
144
145
146
...
169
170
171
172
173
174
175

176
177
178



179
180
181
182
183
184
185
186
...
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

#include "param.h"
#include "systm.h"
#include "user.h"
#include "inode.h"
#include "filsys.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
................................................................................
 * 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"
 */
struct inode *
iget(dev, ino)
	int dev;
	int ino;

{
	register struct inode *p;
	struct inode *freeip;
	struct buf   *bp;
	register struct mount *mp;
	register struct dinode *dp;
	register int i;

loop:
	freeip = 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(mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
					if(mp->m_inodp == p) {
						dev = mp->m_dev;
						ino = ROOTINO;

						goto loop;
					}
				panic("mount table failure");
			}
			p->i_count++;
			p->i_flag |= ILOCK;
			return(p);
................................................................................
	if((p = freeip) == 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;

	bp = bread(dev, (ino+31)>>4);
	if (bp->b_flags&B_ERROR) {
		brelse(bp);
		iput(p);
		return(NULL);
................................................................................
 * write the inode out and if necessary,
 * truncate and deallocate the file.
 */
void
iput(rp)
	register struct inode *rp;
{


	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.
 */
void
iupdat(p, tm)
	struct inode *p;
	unsigned long *tm;
{
	register struct buf *bp;
	register struct dinode *dp;
	int i;

	if((p->i_flag&(IUPD|IACC)) != 0) {




		if(getfs(p->i_dev)->s_ronly)
			return;
		i = p->i_number+31;
		bp = bread(p->i_dev, i>>4);
		dp = (struct dinode*) (bp->b_addr + 32 * (i & 017));
		/* Copy kernel format to disk format */
		dp->d_mode   = p->i_mode;
................................................................................
 */
void
itrunc(p)
	register struct inode *p;
{
	struct buf *bp, *dp;
	register int *cp, *ep, *ap;


	if((p->i_mode&(IFCHR&IFBLK)) != 0)
		return;




	for(ap = &p->i_addr[7]; ap >= &p->i_addr[0]; ap--) {
		if(*ap == 0)
			continue;
		/* if each address is an indirect block ... */
		if((p->i_mode&ILARG) != 0) {
			bp = bread(p->i_dev, *ap);
			/* ... free its 512 pointers */
................................................................................
	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.
 */
void
wdir(ip)
	struct inode *ip;
{
	u.u_dent.u_ino = ip->i_number;
	memcpy(&u.u_dent.u_name[0], &u.u_dbuf[0], DIRSIZ);
	u.u_count = DIRSIZ + 2;
	u.u_base = (char*) &u.u_dent;
	u.u_segflg++;
	writei(u.u_pdir);
	u.u_segflg--;
	iput(u.u_pdir);
}







>

<

|







 







|
|
|
>











|








|
|
>







 







>


>
>







 







>
>


>
|
>
>
>
|
|
|
|
>
>
>
|



>







 







|




|


>
>
>
>







 







>



>
>
>
|







 







|









|
|

|

|






1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
...
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
...
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

#include "param.h"
#include "systm.h"
#include "user.h"
#include "inode.h"
#include "filsys.h"
#include "buf.h"
#include "conf.h"


/*
 * Look up an inode by device,inumber,fstype
 * 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
................................................................................
 * 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"
 */
struct inode *
iget(dev, ino, fstyp)
	register int dev;
	register int ino;
        register int fstyp;
{
	register struct inode *p;
	struct inode *freeip;
	struct buf   *bp;
	register struct mount *mp;
	register struct dinode *dp;
	register int i;

loop:
	freeip = NULL;
	for(p = &inode[0]; p < &inode[NINODE]; p++) {
		if(dev==p->i_dev && ino==p->i_number && fstyp==p->i_fstyp) {
			if((p->i_flag&ILOCK) != 0) {
				p->i_flag |= IWANT;
				sleep(p, PINOD);
				goto loop;
			}
			if((p->i_flag&IMOUNT) != 0) {
				for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
					if(mp->m_inodp == p) {
						dev   = mp->m_dev;
						ino   = ROOTINO;
                                                fstyp = mp->m_fstyp;
						goto loop;
					}
				panic("mount table failure");
			}
			p->i_count++;
			p->i_flag |= ILOCK;
			return(p);
................................................................................
	if((p = freeip) == NULL) {
		printf("Inode table overflow\n");
		u.u_error = ENFILE;
		return(NULL);
	}
	p->i_dev    = dev;
	p->i_number = ino;
        p->i_fstyp  = fstyp;
	p->i_flag   = ILOCK;
	p->i_count++;
	if(fstyp)
		return((*fstypsw[fstyp].t_get)(fstyp, dev, ino, p));
	p->i_lastr  = -1;

	bp = bread(dev, (ino+31)>>4);
	if (bp->b_flags&B_ERROR) {
		brelse(bp);
		iput(p);
		return(NULL);
................................................................................
 * write the inode out and if necessary,
 * truncate and deallocate the file.
 */
void
iput(rp)
	register struct inode *rp;
{
	register int fstyp;

	if(rp->i_count == 1) {
		rp->i_flag |= ILOCK;
		fstyp = rp->i_fstyp;
		if(rp->i_nlink <= 0)
			if(fstyp)
				(*fstypsw[fstyp].t_free)(rp);
			else {
				itrunc(rp);
				rp->i_mode = 0;
				ifree(rp->i_dev, rp->i_number);
			}
		if(fstyp)
			(*fstypsw[fstyp].t_put)(rp);
		else
			iupdat(rp, &time);
		prele(rp);
		rp->i_flag = 0;
		rp->i_number = 0;
		rp->i_fstyp = 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.
 */
void
iupdat(p, tm)
	register struct inode *p;
	unsigned long *tm;
{
	register struct buf *bp;
	register struct dinode *dp;
	register int i, fstyp;

	if((p->i_flag&(IUPD|IACC)) != 0) {
		if((fstyp = p->i_fstyp)) {
			(*fstypsw[fstyp].t_updat)(p, tm);
			return;
		}
		if(getfs(p->i_dev)->s_ronly)
			return;
		i = p->i_number+31;
		bp = bread(p->i_dev, i>>4);
		dp = (struct dinode*) (bp->b_addr + 32 * (i & 017));
		/* Copy kernel format to disk format */
		dp->d_mode   = p->i_mode;
................................................................................
 */
void
itrunc(p)
	register struct inode *p;
{
	struct buf *bp, *dp;
	register int *cp, *ep, *ap;
	register int fstyp;

	if((p->i_mode&(IFCHR&IFBLK)) != 0)
		return;
	if((fstyp = p->i_fstyp)) {
			(*fstypsw[fstyp].t_trunc)(p);
			return;
	}
	for(ap = &p->i_addr[7]; ap >= &p->i_addr[0]; ap--) {
		if(*ap == 0)
			continue;
		/* if each address is an indirect block ... */
		if((p->i_mode&ILARG) != 0) {
			bp = bread(p->i_dev, *ap);
			/* ... free its 512 pointers */
................................................................................
	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->i_number);
	return(ip);
}

/*
 * Write a directory entry with
 * parameters left as side effects
 * to a call to namei.
 */
void
wdir(ino)
	int ino;
{
	u.u_dent.u_ino = ino;
	memcpy(&u.u_dent.u_name[0], &u.u_dbuf[0], DIRSIZ);
        u.u_count = DIRSIZ + 2;
	u.u_base = (char*) &u.u_dent;
	u.u_segflg++;
	writei(u.u_pdir);
	u.u_segflg--;
	iput(u.u_pdir);
}

Changes to v6/inode.h.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82













83
	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_fill;		/* explicit alignment filler */
	unsigned long	i_size;		/* file size in bytes */
	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 */
................................................................................
/* inode function prototypes */
#ifdef KERNEL
struct inode *ialloc();
struct inode *namei();
struct inode *iget();
struct inode *maknode();
void ifree();
void openi();
void closei();
void iput();
void iupdat();
void itrunc();
void readi();
void writei();
void wdir();
int bmap();
int access();













#endif







|







 







|









>
>
>
>
>
>
>
>
>
>
>
>
>

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	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_fstyp;	/* filesystem type */
	unsigned long	i_size;		/* file size in bytes */
	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 */
................................................................................
/* inode function prototypes */
#ifdef KERNEL
struct inode *ialloc();
struct inode *namei();
struct inode *iget();
struct inode *maknode();
void ifree();
struct inode *openi();
void closei();
void iput();
void iupdat();
void itrunc();
void readi();
void writei();
void wdir();
int bmap();
int access();

#define NI_SEARCH	0	/* find file */
#define NI_CREAT	1	/* find file, create if it doesn't exist */
#define NI_UNLINK	2	/* unlink file */
#define NI_MKNOD	3	/* create node, error if it already exists */
#define NI_LINK		4	/* make a link, error if exists */

struct state {
        struct inode *dp;	/* search dir */
        char c;			/* current path char */
        int param;              /* creation parameter */
};

#endif

Changes to v6/main.c.

35
36
37
38
39
40
41


42
43
44
45
46
47
48
..
77
78
79
80
81
82
83
84
85
86
87



88
89
90
91
92
93
94
	0xc7c0, 0x64f,
	0x0200, BOTUSR+0x18,
	0xc7c0, 0x2c60, 11,
	0x10ff, BOTUSR+0x18, 0x000,
	0x2f65, 0x7463, 0x2f69, 0x6e69, 0x7400
};



/*
 * Initialization code, called from mch.S as soon as a stack
 * has been established.
 * Functions:
 *	hand craft 0th process
 *	call all initialization routines
 *	fork - process 0 to schedule
................................................................................
	proc[0].p_flag |= SLOAD|SSYS;
	u.u_procp = &proc[0];

	/* set up 'known' i-nodes */
	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()) {







>
>







 







|

|

>
>
>







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
	0xc7c0, 0x64f,
	0x0200, BOTUSR+0x18,
	0xc7c0, 0x2c60, 11,
	0x10ff, BOTUSR+0x18, 0x000,
	0x2f65, 0x7463, 0x2f69, 0x6e69, 0x7400
};

int prmount();

/*
 * Initialization code, called from mch.S as soon as a stack
 * has been established.
 * Functions:
 *	hand craft 0th process
 *	call all initialization routines
 *	fork - process 0 to schedule
................................................................................
	proc[0].p_flag |= SLOAD|SSYS;
	u.u_procp = &proc[0];

	/* set up 'known' i-nodes */
	cinit();
	binit();
	iinit();
	rootdir = iget(rootdev, ROOTINO, 0);
	rootdir->i_flag &= ~ILOCK;
	u.u_cdir = iget(rootdev, ROOTINO, 0);
	u.u_cdir->i_flag &= ~ILOCK;
  
  /* set up '/proc' fs */
  prmount(2, "/proc", 0);

	/*
	 * make init process
	 * enter scheduling loop
	 * with system process
	 */
	if(newproc()) {

Changes to v6/nami.c.

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42













































































43
44






















45
46
47
48
49
50
51
52
53
54
55
56
57
58
59


60
61
62
63
64
65

66
67
68
69
70
71
72
..
74
75
76
77
78
79
80

81
82

83
84
85
86
87
88
89
90

91
92

93

94
95



96
97

98
99









100
101
102



103







104






105



















106
107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125

126




127
128
129
130
131
132
133
134
135



136
137


138
139
140
141
142
143
144
145
146
147
148

149
150
151
152
153




154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185

#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 saught
 *	1 if name is to be created
 *	2 if name is to be deleted
 */
struct inode *
namei(func, flag)
	int (*func)();
	int flag;

{
	register struct inode *dp;
	register int c;
	register char *cp;
	int eo;
	struct buf *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) {
................................................................................
			*cp++ = c;
		c = (*func)();
	}
	while(cp < &u.u_dbuf[DIRSIZ])
		*cp++ = '\0';
	while(c == '/')
		c = (*func)();

	if(u.u_error)
		goto out;


	/*
	 * Special handling for ".." allowing chdir out of mounted
	 * file system. We know NMOUNT == 2.
	 */
	if (u.u_dbuf[0]=='.' && u.u_dbuf[1]=='.' && u.u_dbuf[2]=='\0' &&
	    dp->i_number == ROOTINO && dp->i_dev == mount[1].m_dev &&
	    mount[1].m_inodp != 0) {

		iput(dp);
		dp = mount[1].m_inodp;

		dp->i_count++;

	}




	/*
	 * Set up to search a directory.

	 */
	u.u_offset = 0;









	eo = 0;
/*	u.u_segflg = 1; */
	u.u_count = dp->i_size >> 4;



	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 = 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(((int) u.u_offset & 0777) == 0) {
		if(bp != NULL)
			brelse(bp);



		bp = bread(dp->i_dev,
			bmap(dp, (int) (u.u_offset >> 9)));


	}

	/*
	 * 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.
	 */
	memcpy(&u.u_dent, bp->b_addr + ((int) u.u_offset & 0777), DIRSIZ+2);
	u.u_offset += DIRSIZ+2;

	u.u_count--;
	if(u.u_dent.u_ino == 0) {
		if(eo == 0)
			eo = u.u_offset;
		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);
	}
	iput(dp);
	dp = iget(dp->i_dev, 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.
 */






>








|
<
<


|


>


|


|









<


|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





<
<
<
<
<
<




>
>
|

<
<
|
|
>







 







>

<
>



|


|
|
>
|
<
>
|
>
|
|
>
>
>
|
|
>
|
<
>
>
>
>
>
>
>
>
>
|
<
<
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





<
<
<
|
|
<
>
|
|
|
|
|
<
|
<
<
>
|
>
>
>
>

<
<
<
<
<
<
<
<
>
>
>
|
<
>
>
|
<
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
>
>
>
>
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147






148
149
150
151
152
153
154
155


156
157
158
159
160
161
162
163
164
165
...
167
168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206
207
208


209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251



252
253

254
255
256
257
258
259

260


261
262
263
264
265
266
267








268
269
270
271

272
273
274










275
276




277
278
279
280
281



282










283
284









285
286
287
288
289
290
291

#include "param.h"
#include "inode.h"
#include "user.h"
#include "systm.h"
#include "buf.h"
#include "conf.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 = SEARCH, CREAT, etc.


 */
struct inode *
namei(func, flag, param)
	int (*func)();
	int flag;
        int param;
{
	register struct inode *dp;
	register int c, fstyp;
	register char *cp;
	int eo;
	struct state s;

	/*
	 * If name starts with '/' start from
	 * root; otherwise start from current dir.
	 */

	dp = u.u_cdir;
	if((c=(*func)()) == '/')
		dp = rootdir;

	while(c == '/')
		c = (*func)();
	if(c == '\0' && flag != NI_SEARCH) {
		u.u_error = ENOENT;
		return NULL;
	}

	dp->i_count++;
	s.dp = dp;
	s.c  = c;
        s.param = param;
	for (;;) {
	        if((fstyp = s.dp->i_fstyp) >= nfstyp) panic("namei nfstyp");
	        switch((*fstypsw[fstyp].t_nami)(func, flag, &s)) {
		/* null return (error or no lookup) */
	        case 1:	iput(s.dp);
			return NULL;
		/* change in file system */
	        case 2: if(s.c)
	                        break;
		/* found */
	        case 0:	return s.dp;
                
	        default:
	                panic("namei ret");
	        }
	}
}

int
dsearch(dp, eop, pg)
	struct inode *dp;
	int *eop;
        struct buf *(*pg)();
{
	int ino, eo;
	register struct buf *bp;
        register char *cp;

	/*
	 * Set up to search a directory.
	 */
	u.u_offset = 0;
	u.u_count  = dp->i_size >> 4;
	bp  = NULL;
	eo = ino = 0;

eloop:
	while(u.u_count>0) {
		/*
		 * If offset is on a block boundary,
		 * read the next directory block.
		 * Release previous if it exists.
		 */
		if(((int) u.u_offset & 0777) == 0) {
			if(bp != NULL)
				brelse(bp);
                        if(pg != NULL)
                                bp = pg(dp, (int) (u.u_offset >> 9));
                        else
                                bp = bread(dp->i_dev,
                                        bmap(dp, (int) (u.u_offset >> 9)));
		}
	
		/*
		 * 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.
		 */
		memcpy(&u.u_dent, bp->b_addr + ((int) u.u_offset & 0777), DIRSIZ+2);
		u.u_offset += DIRSIZ+2;
		u.u_count--;
		if(u.u_dent.u_ino == 0) {
			if(eo == 0)
				eo = u.u_offset;
			continue;
		}
		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;
			}

		ino = u.u_dent.u_ino;
		break;
	}
	if(bp != NULL)
		brelse(bp);
	*eop = eo;
	return ino;
}

struct mount *findmount();

int
ufs_namei(func, flag, s)
        int (*func)();
        int flag;
	struct state *s;
{
	register char c = s->c;
	register struct inode *ip, *dp = s->dp;
	register char *cp;
	int eo, fstyp = dp->i_fstyp;

cloop:
	/*
	 * Here dp contains pointer
	 * to last component matched.






	 * If there is another component,
	 * dp must be a directory and
	 * must have x permission.
	 */
	if(c == '\0')
	 	return 0;
	if((dp->i_mode&IFMT) != IFDIR)
		u.u_error = ENOTDIR;


	access(dp, IEXEC);
	if(u.u_error)
		return 1;

	/*
	 * Gather up name into
	 * users' dir buffer.
	 */
	cp = &u.u_dbuf[0];
	while(c!='/' && c!='\0' && u.u_error==0) {
................................................................................
			*cp++ = c;
		c = (*func)();
	}
	while(cp < &u.u_dbuf[DIRSIZ])
		*cp++ = '\0';
	while(c == '/')
		c = (*func)();
	s->c = c;
	if(u.u_error)

		return 1;

	/*
	 * Special handling for ".." allowing chdir out of mounted
	 * file system.
	 */
	if (u.u_dbuf[0]=='.' && u.u_dbuf[1]=='.' && u.u_dbuf[2]=='\0' &&
	    dp->i_number == ROOTINO) {
                struct mount *mp = findmount(dp->i_fstyp, dp->i_dev);
                if(mp) {
			iput(dp);

			s->dp = dp = mp->m_inodp;
			dp->i_count++;
			plock(dp);
		}
	}

	if(dsearch(dp, &eo, NULL)) {
	
		/*
		 * Here a component matched in a directory.
		 * If at end of path, check flag
		 */

                if(c=='\0') {
                        u.u_pdir = NULL; /* for NI_CREAT */
                        switch(flag) {

                        case NI_UNLINK:
                                if(access(dp, IWRITE))
                                        return 1;
                                /* Avoid hanging on '.' */
                                if(dp->i_number == u.u_dent.u_ino) {
                                        ip = dp;


                                        dp->i_count++;
                                } else
                                        ip = iget(dp->i_dev, u.u_dent.u_ino, fstyp);
                                if(ip == NULL)
                                        return 1;
                                if((ip->i_mode&IFMT)==IFDIR && !suser())
                                        goto delout;
                                /* Don't unlink a mounted file. */
                                if (ip->i_dev != dp->i_dev) {
                                        u.u_error = EBUSY;
                                        goto delout;
                                }
                                u.u_offset -= DIRSIZ+2;
                                u.u_pdir = dp;
                                dp->i_count++;
                                wdir(0);
                                ip->i_nlink--;
                                ip->i_flag |= IUPD;
                        delout:
                                iput(ip);
                                return 1;

                        case NI_LINK:
                        case NI_MKNOD:
                                u.u_error = EEXIST;
                                return 1;
                        }
		}

		iput(dp);
		s->dp = dp = iget(dp->i_dev, u.u_dent.u_ino, fstyp);
		if(dp == NULL)
			return 1;
		if(fstyp != dp->i_fstyp)
			return 2;
		goto cloop;
	}
	
	/*
	 * If at the end of the directory,
	 * the search failed. Report what
	 * is appropriate as per flag.
	 */



        if(c=='\0') {
                if(access(dp, IWRITE))

                        return 1;
                u.u_pdir = dp;
                if(eo)
                        u.u_offset = eo-DIRSIZ-2;
                else
                        dp->i_flag |= IUPD;




                switch(flag) {

                case NI_MKNOD:
                case NI_CREAT:
                        s->dp = maknode(s->param); /* iputs old dp */
                        return 0;









                case NI_LINK:
                        /* check link is one same disk */
                        ip = (struct inode*)(s->param);
                        if(dp->i_dev != ip->i_dev) {

                                u.u_error = EXDEV;
                                return 1;
                        }










                        /* update link directory & update target inode */
                        dp->i_count++;




                        wdir(ip->i_number);
                        ip->i_nlink++;
                        ip->i_flag |= IUPD;
                        return 1;
                }



	}










	u.u_error = ENOENT;
	return 1;









}


/*
 * Return the next character from the
 * kernel string pointed at by dirp.
 */

Added v6/pair.c.





































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530

#include "param.h"
#include "systm.h"
#include "user.h"
#include "inode.h"
#include "file.h"
#include "buf.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
#define PIPEFS  1

/*
 * The sys-pipe entry.
 * Allocate an inode on the root device.
 * Allocate 2 file structures.
 * Put it all together with flags.
 */

static int ino = 64;
 
void
pair()
{
	register struct inode *ip, *pp;
	register struct file *rf, *wf;
	int r;

	pp = iget(0, ino++, PIPEFS);
	if(pp == NULL)
		return;
	ip = ialloc(rootdev);
	if(ip == NULL)
		goto out1;
	rf = falloc();
	if(rf == NULL) 
		goto out2;
	r = u.u_ar0[R0];
	wf = falloc();
	if(wf == NULL) {
		rf->f_count = 0;
		u.u_ofile[r] = NULL;
		goto out2;
	}
	u.u_ar0[R1] = u.u_ar0[R0];
	u.u_ar0[R0] = r;
	wf->f_flag  = FWRITE;
	wf->f_inode = pp;
	rf->f_flag  = FREAD;
	rf->f_inode = pp;
	pp->i_count = 2;
	pp->i_flag  = 0; /* unlock */

	pp->i_addr[0] = (int)ip;
	pp->i_addr[1] = 0; /* rd ptr */
	pp->i_addr[2] = 0; /* wr ptr */
	ip->i_flag  = IACC|IUPD;
	ip->i_mode  = IALLOC;
	return;

out2:	iput(ip);
out1:	iput(pp);
}

/*
 * Read call directed to a pipe.
 */
rdpair(pp)
	register struct inode *pp;
{
	register struct inode *ip = (struct inode *)(pp->i_addr[0]);

loop:
	/* Very conservative locking */
	plock(pp);

	/* If the head (read) has caught up with
	 * the tail (write), reset both to 0.
	 */
	if(pp->i_addr[1] == ip->i_size) {
		ip->i_size = 0;
		pp->i_addr[1] = 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(pp);
		if(pp->i_count < 2)
			return;
		ip->i_mode |= IREAD;
		sleep(ip+2, PPIPE);
		goto loop;
	}

	/* Read and return */
	u.u_offset = pp->i_addr[1];
	readi(ip);
	pp->i_addr[1] = u.u_offset;
	prele(pp);
}

/*
 * Write call directed to a pipe.
 */
wrpair(pp)
	register struct inode *pp;
{
	register struct inode *ip = (struct inode *)(pp->i_addr[0]);
	unsigned c;

	c = u.u_count;

loop:
	/* If all done, return */
	plock(pp);
	if(c == 0) {
		prele(pp);
		u.u_count = 0;
		return;
	}

	/* If there are not both read and
	 * write sides of the pipe active,
	 * return error and signal too.
	 */
	if(pp->i_count < 2) {
		prele(pp);
		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_size == PIPSIZ) {
		ip->i_mode |= IWRITE;
		prele(pp);
		sleep(ip+1, PPIPE);
		goto loop;
	}

	/* Write what is possible and
	 * loop back.
	 */
	u.u_offset = ip->i_size;
	u.u_count = min(c, (int)(PIPSIZ - u.u_offset));
	c -= u.u_count;
	writei(ip);
	prele(pp);
	if(ip->i_mode&IREAD) {
		ip->i_mode &= ~IREAD;
		wakeup(ip+2);
	}
	goto loop;
}

struct inode *
getpair(fstyp, dev, ino, ip)
	int fstyp, dev, ino;
	register struct inode *ip;
{
	ip->i_mode  = 0;
	ip->i_nlink = 0;
	ip->i_uid   = 1;
	ip->i_gid   = 1;
	ip->i_size  = 0;
	return(ip);
}

frepair(pp)
	struct inode *pp;
{
	register int n = pp->i_addr[0];
	
	if( n )
		iput((struct inode*)n);

}

/* ======= */

struct direct {
	int  d_ino;
	char d_name[14];
} names[2] = {
	{1, "."  },
	{1, ".." }
};

struct inode *ino1;

struct inode *
sfsget(fstyp, dev, ino, ip)
	int fstyp, dev, ino;
	register struct inode *ip;
{
printf("get %d,%d\n", ip, ino);
	if(ino==1) {
		ip->i_mode = IFDIR | 0555;	/* dir, read and search */
		ip->i_nlink = 2;		/* complete fake */
		ip->i_uid = ip->i_gid = 0;
		ip->i_size = sizeof(names);
		ino1 = ip;
		return(ip);
	}
	ip->i_mode  = 0400;
	ip->i_nlink = 0;
	ip->i_uid   = u.u_uid;
	ip->i_gid   = u.u_gid;
	ip->i_size  = 0;
	return(ip);
}


sfsput(ip)
	struct inode *ip;
{
	register struct inode *dp;

printf("put %d,%d,%d\n", ip, ip->i_number, (int)ip->i_size);
	if(ip->i_number != ROOTINO && ip->i_count == 1) {
		dp = ino1;
		if(dp == NULL)
			panic("sfsput");
		dp->i_size -= 16;
		dp->i_count--;
		iput(dp);
	}
}

sfsfree(ip)
	struct inode *ip;
{
}

struct buf *
getpage(dp, n)
	struct inode *dp;
	int n;
{
	register struct inode *ip;	
	register struct buf *bp;
	register char *cp;
	register int i = 2;

	bp = getblk(NODEV);
	cp = bp->b_addr;
	memcpy(cp, names, 32);
	cp += 32;

	for(ip = &inode[0]; ip < &inode[NINODE]; ip++) {
		if(ip->i_number < 2 || ip->i_fstyp != 2) continue;
printf("gp %d, %d\n", ip, ip->i_number);
		*((int*)cp) = ip->i_number;
		memcpy(cp+2, ip->i_addr, DIRSIZ);
		cp += 16;
		if(++i > 31)
			panic("getpage");
	}

	return bp;
}

sfsrd(ip)
	register struct inode *ip;
{
	register int i, n;
	struct buf *bp;
	
	if(ip->i_number != ROOTINO) {
		return;
	}
	if (u.u_offset < 0 || u.u_offset >= ip->i_size || u.u_count <= 0)
		return;

	bp = getpage();
	i = u.u_offset;
	n = ip->i_size;
	n = min(u.u_count,  n - i);
	iomove(bp->b_addr+i, n, B_READ);
	brelse(bp);
}

sfswr(ip)
	struct inode *ip;
{
	printf("wr %d,%d\n", ip, u.u_count);
	u.u_count = 0; /* rat hole */
}

struct mount *findmount();

int
sfsnam(func, flag, s)
	int (*func)();
	int flag;
	struct state *s;
{
	register char *cp, c = s->c;
	register struct inode *dp = s->dp;
	int dev, fstyp, ino, eo;
	char *p;
	static int ctr = 2;

cloop:
	if(c == '\0')
		return 0;
	if ((dp->i_mode & IFMT) != IFDIR)
		u.u_error = ENOTDIR;
	(void) access(dp, IEXEC);
	if (u.u_error)
		return 1;
	
	p = u.u_dirp;
	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)();
	s->c = c;

	if (u.u_dbuf[0]=='.' && u.u_dbuf[1]=='.' && u.u_dbuf[2]=='\0' &&
		dp->i_number == ROOTINO) {
		struct mount *mp = findmount(dp->i_fstyp, dp->i_dev);
		if(mp) {
			iput(dp);
			s->dp = dp = mp->m_inodp;
			dp->i_count++;
			plock(dp);
			s->c = u.u_dbuf[0];
			u.u_dirp = p;
			return 2;
		}
	}

	if( (ino = dsearch(dp, &eo, &getpage)) ) {
		dev   = dp->i_dev;
		fstyp = dp->i_fstyp;
		iput(dp);
		s->dp = iget(dev, ino, fstyp);
		goto cloop;
	}
	if(c == 0 && flag == NI_CREAT) {
		dp->i_size += 16;
		dp->i_count++;
		iput(dp);
		s->dp = dp = iget(0, ctr++, 2);
		memcpy(dp->i_addr, u.u_dbuf, DIRSIZ);
		dp->i_addr[7] = 0;
		/*dp->i_count++; /* HACK */
		return 0;
	}

	u.u_error = ENOENT;
	return 1;
}

#define PROCDEV 0

void suword();

sfsstat(ip, ub)
	struct inode *ip;
	register int *ub;
{
	register int i;
	register int *tp = (int*)(&time);
/* printf("stat %d,%d\n", ip, ip->i_number); */
	if(ip->i_number < 64) {
		suword(ub++, PROCDEV);
		suword(ub++, ip->i_number);
		suword(ub++, ip->i_mode);
		suword(ub++, (ip->i_nlink<<8)|ip->i_uid);
		suword(ub++, 0);
		suword(ub++, (int)(ip->i_size));
		for(i=0; i<8; ++i) suword(ub++, 0);
		suword(ub++, tp[0]);
		suword(ub++, tp[1]);
		suword(ub++, tp[0]);
		suword(ub++, tp[1]);
	}
	else
		u.u_error = ENOENT;
	u.u_ar0[R0] = 0;
}

struct inode *
sfsopn(ip, rw, fp)
	struct inode *ip;
	int rw;
	struct file *fp;
{
	register struct file *wf;
	register struct inode *ap, *pip;
	int i, w, r;

	printf("in sfs open\n");
	if(ip->i_number == 1)
		return ip;

        ap = iget(0, ino++, PIPEFS);
        if(ap == NULL)
                return ip;
        pip = ialloc(rootdev);
        if(pip == NULL)
                goto out1;
	ap->i_count = 2;
	ap->i_addr[0] = (int)pip;
	ap->i_addr[1] = 0; /* rd ptr */
	ap->i_flag  = 0; /* unlock */
	fp->f_inode = ap;
	fp->f_flag  = FREAD;

	r = u.u_ar0[R0];
	wf = falloc();
        if(wf == NULL) 
                goto out2;
	w = u.u_ar0[R0];
	u.u_ofile[w] = NULL;
	wf->f_flag  = FWRITE;
	wf->f_inode = ap;
	ip->i_addr[7] = (int)wf;
	
	/* wake up server, keep lock */
	wakeup(&ip->i_addr[8], PPIPE);
	while(ip->i_addr[7] == (int)ap)
		sleep(&ip->i_addr[7], PPIPE);
	u.u_ar0[R0] = r;
	iput(ip);
	return ap;

out2:	iput(pip);
out1:	iput(ap);
	return ip;
}

void
soaccept()
{
	register struct file *fp, *ap;
	register struct inode *ip;
	int i;

	fp = getf(u.u_arg[0]);
	if(fp == NULL)
		return;
	ip = fp->f_inode;
	if(ip->i_fstyp!=2) {
		u.u_error = EBADF;
		return;
	}
	/* wait for connection */
	while(ip->i_addr[7] == 0) {
		sleep(&ip->i_addr[8], PPIPE);
	}
	/* accept */
	ap = (struct file *)(ip->i_addr[7]);
	ip->i_addr[7] = 0;
	i = ufalloc();
	if( i >= 0 ) {
		u.u_ofile[i] = ap;
	}
	wakeup(&ip->i_addr[7], PPIPE);
}

#define MOUNTED 1

struct mount *allocmount();

prmount(fstyp, fdir, flag)
	int fstyp;
	char *fdir;
	int flag;	/* 0 = mount, 1 = unmount */
{
	struct inode *ip;
	struct mount *mp;
	extern int schar();

	if(flag)
		goto unmount;
	mp = allocmount(fstyp, PROCDEV);
	if(mp == NULL) {		/* duplicated mount */
		u.u_error = EBUSY;
		return;
	}
	mp->m_bufp = (struct buf *)MOUNTED;
	u.u_dirp = fdir;
	ip = namei(schar, NI_SEARCH);
	if(ip == NULL) {
		mp->m_bufp = NULL;
		return;
	}
	if(ip->i_count != 1 || (ip->i_mode & IFMT) != IFDIR) {
		mp->m_bufp = NULL;
		u.u_error = EBUSY;
		iput(ip);
		return;
	}
	mp->m_inodp = ip;
	ip->i_flag |= IMOUNT;
	prele(ip);
	return;

unmount:
	mp = findmount(fstyp, PROCDEV);
	if(mp == NULL)
		return;
	ip = mp->m_inodp;
	ip->i_flag &= ~IMOUNT;
	iput(ip);
	mp->m_bufp = NULL;
}

Added v6/proca.c.





































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
#include "param.h"
#include "systm.h"
#include "proc.h"
#include "inode.h"
#include "user.h"
#include "buf.h"
#include "reg.h"

/* inumber to pid */
#define PRMAGIC 64
#define PROCDEV 0
#define MOUNTED 1

struct direct {
	int	d_ino;
	char	d_name[14];
};

struct proc *
pfind(pid)
	int pid;
{
	register struct proc *p;

	for (p = &proc[0]; p < &proc[NPROC]; p++)
		if (p->p_pid == pid)
			return (p);
	return NULL;
}

prput(ip)
	struct inode *ip;
{
	struct proc *p;

	if(ip->i_number == ROOTINO)
		return;
	p = pfind(ip->i_number - PRMAGIC);
	if(p == 0) {
		printf("prput(%d)?\n", ip->i_number - PRMAGIC);
		return;
	}
}

struct inode *
prget(fstyp, dev, ino, ip)
	int dev;
	register struct inode *ip;
{
	register struct proc *p;
	if(ino == ROOTINO) {	/* fake up an inode */
		ip->i_mode = IFDIR | 0555;	/* dir, read and search */
		ip->i_nlink = 2;		/* complete fake */
		ip->i_uid = ip->i_gid = 0;
		ip->i_size = (NPROC + 2) * sizeof(struct direct);
		return(ip);
	}
	p = pfind(ino - PRMAGIC);
	if (p == 0) {
		iput(ip);
		u.u_error = ENOENT;
		return(0);
	}

	ip->i_mode  = 0400;		/* regular, r/w only by owner */
	ip->i_nlink = 1;
	ip->i_uid   = p->p_uid;
	ip->i_gid   = 1;		/* who cares */
	ip->i_size  = 0xe000;
	return(ip);
}

prfree(ip)
	struct inode *ip;
{}

prupdat(ip, tm)
	struct inode *ip;
	long *tm;
{}

#define SDSIZ	sizeof(struct direct)

int min();

prread(ip)
	struct inode *ip;
{
	static struct direct dotbuf[] = {
		{ ROOTINO, "."},
		{ ROOTINO, ".."}
	};
	struct direct dirbuf;
	register int i, n, j;
	int minproc, maxproc, modoff;
	struct proc *p;

	if (ip->i_number == ROOTINO) {	/* fake up . .. and the proc inodes */
		if (u.u_offset < 0 || u.u_offset >= ip->i_size ||
		    u.u_count <= 0)
			return;
		i = u.u_offset;
		if (i < 2*SDSIZ) {
			n = min(u.u_count, 2*SDSIZ - i);
			iomove((char*)&dotbuf[0] + i, n, B_READ);
			if (u.u_count <= 0 || u.u_error)
				return;
		}
		minproc = (i - 2*SDSIZ)/SDSIZ;
		maxproc = (i + u.u_count - 1)/SDSIZ;
		modoff  =  i % SDSIZ;
		for (j = 0; j < DIRSIZ; j++)
			dirbuf.d_name[j] = 0;
		for (i=minproc; i<min(maxproc, NPROC); i++) {
			if (n = proc[i].p_pid) {
				dirbuf.d_ino = n + PRMAGIC;
				for (j = 4; j >= 0; j--)
					dirbuf.d_name[j] = n%10 + '0', n /= 10;
			} else {
				dirbuf.d_ino = 0;
			}
			iomove((char*)&dirbuf + modoff,
			    min(u.u_count, SDSIZ - modoff), B_READ);
			if (u.u_count <= 0 || u.u_error)
				return;
			modoff = 0;
		}
	} else if (p = pfind(ip->i_number - PRMAGIC)) {
		;
	} else {
		u.u_error = ENOENT;
	}
}

prwrite(ip)
	struct inode *ip;
{
	register struct proc *p;
	if (ip->i_number == ROOTINO) {
		u.u_error = EISDIR;
	} else if (p = pfind(ip->i_number - PRMAGIC)) {
		printf("cannot write file\n");
	} else {
		u.u_error = ENOENT;
		return;
	}
}

prtrunc(ip)
	struct inode *ip;
{}

void suword();

prstat(ip, ub)
	struct inode *ip;
	register int *ub;
{
	struct proc *p = NULL;
	register int i;
	register int *tp = (int*)(&time);

	if(ip->i_number == ROOTINO || (p = pfind(ip->i_number - PRMAGIC))) {
		suword(ub++, PROCDEV);
		suword(ub++, ip->i_number);
		suword(ub++, ip->i_mode);
		suword(ub++, (ip->i_nlink<<8)|ip->i_uid);
		suword(ub++, 0);
		suword(ub++, (int)(ip->i_size));
		for(i=0; i<8; ++i) suword(ub++, 0);
		suword(ub++, tp[0]);
		suword(ub++, tp[1]);
		suword(ub++, tp[0]);
		suword(ub++, tp[1]);
	}
	else
		u.u_error = ENOENT;
	u.u_ar0[R0] = 0;
}

struct mount *findmount();

int
prnami(func, flag, s)
	int (*func)();
	int flag;
	struct state *s;
{
	register char *cp, c = s->c;
	register struct inode *dp = s->dp;
	register int n = 0;
	int dev, fstyp;
	register struct mount *mp;

	if ((dp->i_mode & IFMT) != IFDIR)
		u.u_error = ENOTDIR;
	(void) access(dp, IEXEC);
	if (flag!=NI_SEARCH)
		u.u_error = EPERM;
	if (u.u_error)
		return 1;
	
	cp = &u.u_dbuf[0];
	while(c!='/' && c!='\0' && u.u_error==0) {
		if(cp < &u.u_dbuf[DIRSIZ])
			*cp++ = c;
		c = (*func)();
	}
	*cp++ = '\0';
	while(c=='/') c = (*func)();
	s->c = c;


	cp = &u.u_dbuf[0];
	if (cp[0] == '.') {
		if (cp[1] == 0)
			return 2;
		if (cp[1] != '.' || cp[2])
			return (u.u_error = ENOENT), 1;
		mp = findmount(dp->i_fstyp, dp->i_dev);
		if (mp == NULL)
			panic("prnami");
		iput(dp);
		s->dp = dp = mp->m_inodp;
		dp->i_count++;
		plock(dp);
		return 2;
	}
	while ((c = *cp++)) {
		if(c < '0' || c > '9')
			return (u.u_error = ENOENT), 1;
		n = 10 * n + c - '0';
	}
	dev   = dp->i_dev;
	fstyp = dp->i_fstyp;
	iput(dp);
	s->dp = iget(dev, n + PRMAGIC, fstyp);
	return 0;
}

struct mount *allocmount();

prmount(fstyp, fdir, flag)
	int fstyp;
	char *fdir;
	int flag;	/* 0 = mount, 1 = unmount */
{
	struct inode *ip;
	struct mount *mp;
	extern int schar();

	if(flag)
		goto unmount;
	mp = allocmount(fstyp, PROCDEV);
	if(mp == NULL) {		/* duplicated mount */
		u.u_error = EBUSY;
		return;
	}
	mp->m_bufp = (struct buf *)MOUNTED;
	u.u_dirp = fdir;
	ip = namei(schar, NI_SEARCH);
	if(ip == NULL) {
		mp->m_bufp = NULL;
		return;
	}
	if(ip->i_count != 1 || (ip->i_mode & IFMT) != IFDIR) {
		mp->m_bufp = NULL;
		u.u_error = EBUSY;
		iput(ip);
		return;
	}
	mp->m_inodp = ip;
	ip->i_flag |= IMOUNT;
	prele(ip);
	return;

unmount:
	mp = findmount(fstyp, PROCDEV);
	if(mp == NULL)
		return;
	ip = mp->m_inodp;
	ip->i_flag &= ~IMOUNT;
	iput(ip);
	mp->m_bufp = NULL;
}

prioctl(ip, cmd, cmaddr)
	struct inode *ip;
	char* cmaddr;
{}

Changes to v6/rdwri.c.

17
18
19
20
21
22
23
24
25
26

27
28
29
30
31




32
33
34
35
36
37
38
..
67
68
69
70
71
72
73
74
75
76

77
78
79




80
81
82
83
84
85
86
 *	u_segflg	read to kernel/user
 */
void
readi(aip)
	struct inode *aip;
{
	struct buf *bp;
	int lbn, bn, on;
	register int 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 = u.u_offset >> 9;
................................................................................
 *	u_segflg	write to kernel/user
 */
void
writei(aip)
	struct inode *aip;
{
	struct buf *bp;
	int n, on;
	register int 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;








<
|

>





>
>
>
>







 







<


>



>
>
>
>







17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
..
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
 *	u_segflg	read to kernel/user
 */
void
readi(aip)
	struct inode *aip;
{
	struct buf *bp;

	register int dn, n, fstyp;
	register struct inode *ip;
	register int lbn, bn, on;

	ip = aip;
	if(u.u_count == 0)
		return;
	ip->i_flag |= IACC;
	if((fstyp = ip->i_fstyp)) {
		(*fstypsw[fstyp].t_read)(ip);
		return;
	}
	if((ip->i_mode&IFMT) == IFCHR) {
		(*cdevsw[ip->i_addr[0].d_major].d_read)(ip->i_addr[0]);
		return;
	}

	do {
		lbn = bn = u.u_offset >> 9;
................................................................................
 *	u_segflg	write to kernel/user
 */
void
writei(aip)
	struct inode *aip;
{
	struct buf *bp;

	register int dn, bn;
	register struct inode *ip;
	register int n, on, fstyp;

	ip = aip;
	ip->i_flag |= IACC|IUPD;
	if((fstyp = ip->i_fstyp)) {
		(*fstypsw[fstyp].t_write)(ip);
		return;
	}
	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;

Changes to v6/sig.c.

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
core()
{
	register s, *ip;
	extern int 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;
		u.u_base   = &u;
		u.u_count  = USIZE;







|
<
|
|
<
<
<
<







197
198
199
200
201
202
203
204

205
206




207
208
209
210
211
212
213
core()
{
	register s, *ip;
	extern int schar();

	u.u_error = 0;
	u.u_dirp = "core";
	ip = namei(&schar, NI_CREAT, 0666);

	if(u.u_error || 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;
		u.u_base   = &u;
		u.u_count  = USIZE;

Changes to v6/subr.c.

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134







135
136
137
138
139
140
141

/*
 * 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()
{
}








void *
memcpy (pto, pfrom, nbytes)
	void *pto, *pfrom;
	unsigned int nbytes;
{
	register char *to, *from;







<










>
>
>
>
>
>
>







117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

/*
 * 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()
{
}

nullopn(ip, rw)
	struct inode *ip;
	int rw;
{
	return ip;
}

void *
memcpy (pto, pfrom, nbytes)
	void *pto, *pfrom;
	unsigned int nbytes;
{
	register char *to, *from;

Changes to v6/sys1.c.

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
	extern int 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)







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
	extern int uchar();

	/*
	 * pick up file names
	 * and check various modes
	 * for execute permission
	 */
	ip = namei(&uchar, NI_SEARCH);
	if(ip == NULL)
		return;
	while(execnt >= NEXEC)
		sleep(&execnt, EXPRI);
	execnt++;
	bp = getblk(NODEV);
	if(access(ip, IEXEC) || (ip->i_mode&IFMT)!=0)

Changes to v6/sys2.c.

2
3
4
5
6
7
8

9
10
11
12
13
14
15
..
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
...
105
106
107
108
109
110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
...
143
144
145
146
147
148
149
150
151
152
153
154
155



156
157
158
159
160
161
162
163
164
165
166
167
168
...
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
...
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
#include "param.h"
#include "systm.h"
#include "user.h"
#include "reg.h"
#include "file.h"
#include "inode.h"
#include "proc.h"


/*
 * read system call
 */
void
read()
{
................................................................................
                if ((fp = falloc()) == NULL)
                        return;
                fp->f_flag   = (FNET|FREAD|FWRITE);
                fp->f_offset = (unsigned long)ucbp;
                fp->f_inode  = NULL;
                return;
        }
	ip = namei(&uchar, 0);
	if(ip == NULL)
		return;
	u.u_arg[1]++;
	open1(ip, u.u_arg[1], 0);
}

/*
................................................................................
 */
void
creat()
{
	register struct inode *ip;
	extern int 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.
................................................................................
				u.u_error = EISDIR;
		}
	}
	if(u.u_error)
		goto out;
	if(trf)
		itrunc(ip);
	prele(ip);
	if ((fp = falloc()) == NULL)
		goto out;
	fp->f_flag = mode&(FREAD|FWRITE);
	fp->f_inode = ip;
	i = u.u_ar0[R0];



	openi(ip, mode&FWRITE);
	if(u.u_error == 0)
		return;
	u.u_ofile[i] = NULL;
	fp->f_count--;

out:
	iput(ip);
}

/*
 * close system call
 */
................................................................................
 * link system call
 */
void
link()
{
	register struct inode *ip, *xp;
	extern int 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 = (char*) u.u_arg[1];
	xp = namei(&uchar, 1);
	if(xp != NULL) {
		u.u_error = EEXIST;
		iput(xp);
	}
	if(u.u_error)
		goto out;

	/* check link is one same disk */
	if(u.u_pdir->i_dev != ip->i_dev) {
		iput(u.u_pdir);
		u.u_error = EXDEV;
		goto out;
	}
	
	/* update link directory & update target inode */
	wdir(ip);
	ip->i_nlink++;
	ip->i_flag |= IUPD;

out:
	iput(ip);
	u.u_ar0[R0] = 0;
}

/*
 * mknod system call
................................................................................
void
mknod()
{
	register struct inode *ip;
	extern int 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.







>







 







|







 







|
<
|
|
<
<
<
>

|







 







<





>
>
>
|




<







 







<
|








<



|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|
<
|

<



<
<
<

<







2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
106
107
108
109
110
111
112
113

114
115



116
117
118
119
120
121
122
123
124
125
...
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155
156
157
158
159
160

161
162
163
164
165
166
167
...
236
237
238
239
240
241
242

243
244
245
246
247
248
249
250
251

252
253
254
255



















256
257
258
259
260
261
262
...
264
265
266
267
268
269
270
271

272
273

274
275
276



277

278
279
280
281
282
283
284
#include "param.h"
#include "systm.h"
#include "user.h"
#include "reg.h"
#include "file.h"
#include "inode.h"
#include "proc.h"
#include "conf.h"

/*
 * read system call
 */
void
read()
{
................................................................................
                if ((fp = falloc()) == NULL)
                        return;
                fp->f_flag   = (FNET|FREAD|FWRITE);
                fp->f_offset = (unsigned long)ucbp;
                fp->f_inode  = NULL;
                return;
        }
	ip = namei(&uchar, NI_SEARCH);
	if(ip == NULL)
		return;
	u.u_arg[1]++;
	open1(ip, u.u_arg[1], 0);
}

/*
................................................................................
 */
void
creat()
{
	register struct inode *ip;
	extern int uchar();

	ip = namei(&uchar, NI_CREAT, u.u_arg[1]&07777&(~ISVTX));

        if(u.u_error || ip==NULL)
                return;



	if(u.u_pdir)
		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.
................................................................................
				u.u_error = EISDIR;
		}
	}
	if(u.u_error)
		goto out;
	if(trf)
		itrunc(ip);

	if ((fp = falloc()) == NULL)
		goto out;
	fp->f_flag = mode&(FREAD|FWRITE);
	fp->f_inode = ip;
	i = u.u_ar0[R0];
	if(trf == 0)
		ip = (*fstypsw[ip->i_fstyp].t_open)(ip, mode&FWRITE, fp);
	prele(ip);
	/* openi(ip, mode&FWRITE); */
	if(u.u_error == 0)
		return;
	u.u_ofile[i] = NULL;
	fp->f_count--;

out:
	iput(ip);
}

/*
 * close system call
 */
................................................................................
 * link system call
 */
void
link()
{
	register struct inode *ip, *xp;
	extern int uchar();

	ip = namei(&uchar, NI_SEARCH);
	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 = (char*) u.u_arg[1];
	(void)namei(&uchar, NI_LINK, ip);



















out:
	iput(ip);
	u.u_ar0[R0] = 0;
}

/*
 * mknod system call
................................................................................
void
mknod()
{
	register struct inode *ip;
	extern int uchar();

	if(suser()) {
		ip = namei(&uchar, NI_MKNOD, u.u_arg[1]);

		if(u.u_error || ip==NULL)
			goto out;

	}
	if(u.u_error)
		return;



	ip->i_addr[0] = u.u_arg[2];

out:
	iput(ip);
}

/*
 * sleep system call
 * not to be confused with the sleep internal routine.

Changes to v6/sys3.c.

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59




60
61
62
63
64
65
66
...
103
104
105
106
107
108
109























110
111
112
113
114
115
116
117
118
119


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167














168
169
170
171
172
173
174
...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
...
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
 */
void
stat()
{
	register struct inode *ip;
	extern int 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.
 */
void
stat1(ip, ub)
	struct inode *ip;
	int *ub;
{
	register int i, *cp;
	register struct buf *bp;

	iupdat(ip, &time);




	bp = bread(ip->i_dev, (ip->i_number + 31) >> 4);
	cp = &(ip->i_dev);
	for(i=0; i<14; i++) {
		if(i==4) cp++; /* FIXME skip gid & filler for now */
		suword(ub++, *cp++);
	}
	cp = (int*) (bp->b_addr + 32 * ((ip->i_number + 31) & 017) + 24);
................................................................................
		closef(fp);
	if ( (fp = getf(i)) == NULL || (unsigned) j >= NOFILE)
		return;
	u.u_ar0[R0] = j;
	u.u_ofile[j] = fp;
	fp->f_count++;
}
























/*
 * the mount system call.
 */
void
smount()
{
	int d;
	register struct inode *ip;
	register struct mount *mp, *smp;


	extern int uchar();

	d = getmdev();
	if(u.u_error)
		return;
	u.u_dirp = (char*) 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 = (struct mount*) bread(d, 1);
	if(u.u_error) {
		brelse((struct buf*)mp);
		goto out1;
	}
	smp->m_inodp = ip;
	smp->m_dev = d;
	smp->m_bufp = getblk(NODEV);
	memcpy(smp->m_bufp->b_addr, ((struct buf*)mp)->b_addr, 512);
	smp = (struct mount*)smp->m_bufp->b_addr;
	((struct filsys*)smp)->s_ilock = 0;
	((struct filsys*)smp)->s_flock = 0;
	((struct filsys*)smp)->s_ronly = u.u_arg[2] & 1;
	brelse((struct buf*)mp);
	ip->i_flag |= IMOUNT;
	prele(ip);
	return;

out:
	u.u_error = EBUSY;
out1:
	iput(ip);
}















/*
 * the umount system call.
 */
void
sumount()
{
................................................................................
	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;
................................................................................
 */
getmdev()
{
	register int d;
	register struct inode *ip;
	extern int 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);
}







|












|
|

|



>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|
|
>
>






|




<
<
<
<
<
<
<
|
<





|

|



<

|
|
|
|
|
|









>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
<
<
|
|
|
<







 







|










33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159







160

161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
...
210
211
212
213
214
215
216
217


218
219
220

221
222
223
224
225
226
227
...
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
 */
void
stat()
{
	register struct inode *ip;
	extern int uchar();

	ip = namei(&uchar, NI_SEARCH);
	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.
 */
void
stat1(ip, ub)
	register struct inode *ip;
	register int *ub;
{
	register int i, *cp, fstyp;
	register struct buf *bp;

	iupdat(ip, &time);
	if((fstyp = ip->i_fstyp)) {
		(*fstypsw[fstyp].t_stat)(ip, ub);
		return;
	}
	bp = bread(ip->i_dev, (ip->i_number + 31) >> 4);
	cp = &(ip->i_dev);
	for(i=0; i<14; i++) {
		if(i==4) cp++; /* FIXME skip gid & filler for now */
		suword(ub++, *cp++);
	}
	cp = (int*) (bp->b_addr + 32 * ((ip->i_number + 31) & 017) + 24);
................................................................................
		closef(fp);
	if ( (fp = getf(i)) == NULL || (unsigned) j >= NOFILE)
		return;
	u.u_ar0[R0] = j;
	u.u_ofile[j] = fp;
	fp->f_count++;
}

/* get a free mount slot */
struct mount *
allocmount(fstyp, dev)
	int fstyp;
	int dev;
{
	register struct mount *mp, *smp;

	smp = NULL;
	for(mp = &mount[1]; mp < &mount[NMOUNT]; mp++) {
		if(mp->m_bufp == NULL) {
			if(smp == NULL)
				smp = mp;
		} else if(mp->m_dev == dev && mp->m_fstyp == fstyp)
			return NULL;	/* mounted twice */
	}
	if (smp != NULL) {
		smp->m_dev = dev;
		smp->m_fstyp = fstyp;
	}
	return smp;
}

/*
 * the mount system call.
 */
void
smount()
{
	int d;
	register struct inode  *ip;
	register struct mount  *smp;
	register struct filsys *fs;
	struct buf *bp;
	extern int uchar();

	d = getmdev();
	if(u.u_error)
		return;
	u.u_dirp = (char*) u.u_arg[1];
	ip = namei(&uchar, NI_SEARCH);
	if(ip == NULL)
		return;
	if(ip->i_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0)
		goto out;







	smp = allocmount(0, d);

	if(smp == NULL)
		goto out;
	(*bdevsw[d.d_major].d_open)(d, !u.u_arg[2]);
	if(u.u_error)
		goto out;
	bp = bread(d, 1);
	if(u.u_error) {
		brelse(bp);
		goto out1;
	}
	smp->m_inodp = ip;

	smp->m_bufp = getblk(NODEV);
	memcpy(smp->m_bufp->b_addr, bp->b_addr, 512);
	fs = (struct filsys*)smp->m_bufp->b_addr;
	fs->s_ilock = 0;
	fs->s_flock = 0;
	fs->s_ronly = u.u_arg[2] & 1;
	brelse(bp);
	ip->i_flag |= IMOUNT;
	prele(ip);
	return;

out:
	u.u_error = EBUSY;
out1:
	iput(ip);
}

/* find the mount slot assigned a particular device */
struct mount *
findmount(fstyp, dev)
        int fstyp;
        int dev;
{
        register struct mount *mp;

        for(mp = &mount[1]; mp < &mount[NMOUNT]; mp++)
                if(mp->m_bufp!=NULL && dev==mp->m_dev && fstyp==mp->m_fstyp)
                        return mp;
        return NULL;
}

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

	update();
	d = getmdev();
	if(u.u_error)
		return;
        if((mp = findmount(0, d))==NULL) {


		u.u_error = EINVAL;
		return;
        }

	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;
................................................................................
 */
getmdev()
{
	register int d;
	register struct inode *ip;
	extern int uchar();

	ip = namei(&uchar, NI_SEARCH);
	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);
}

Changes to v6/sys4.c.

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
		n = 0;
	u.u_procp->p_nice = n;
}

void
unlink()
{
	register struct inode *ip, *pp;
	extern int 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 -= DIRSIZ+2;
	u.u_base = (char*) &u.u_dent;
	u.u_count = DIRSIZ+2;
	u.u_dent.u_ino = 0;
	u.u_segflg++;
	writei(pp);
	u.u_segflg--;
	ip->i_nlink--;
	ip->i_flag |= IUPD;
	iput(ip);
out:
	iput(pp);
	u.u_ar0[R0] = 0;
}

void
chdir()
{
	register struct inode *ip;
	extern int uchar();

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







<


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









|







98
99
100
101
102
103
104

105
106
107




















108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
		n = 0;
	u.u_procp->p_nice = n;
}

void
unlink()
{

	extern int uchar();

	(void)namei(&uchar, NI_UNLINK);




















	u.u_ar0[R0] = 0;
}

void
chdir()
{
	register struct inode *ip;
	extern int uchar();

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

Changes to v6/sysent.c.

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
	1, &times,			/* 43 = times */
	4, &profil,			/* 44 = prof */
	3, &sysnet,			/* 45 = sysnet, was: tiu */
	1, &setgid,			/* 46 = setgid */
	0, &getgid,			/* 47 = getgid */
	2, &ssig,			/* 48 = sig */
	3, &ioctl,			/* 49 = ioctl */
	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 */
};







|
|













56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
	1, &times,			/* 43 = times */
	4, &profil,			/* 44 = prof */
	3, &sysnet,			/* 45 = sysnet, was: tiu */
	1, &setgid,			/* 46 = setgid */
	0, &getgid,			/* 47 = getgid */
	2, &ssig,			/* 48 = sig */
	3, &ioctl,			/* 49 = ioctl */
	0, &pair,			/* 50 = x */
	1, &soaccept,			/* 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 */
};

Changes to v6/systm.h.

16
17
18
19
20
21
22

23
24
25
26
27
28
29
..
94
95
96
97
98
99
100


101
 * Used to find the super block.
 */
struct	mount
{
	int		 m_dev;		/* device mounted */
	struct buf	*m_bufp;	/* pointer to superblock */
	struct inode	*m_inodp;	/* pointer to mounted on inode */

} mount[NMOUNT];

int	mpid;			/* generic for unique process id's */
char	runin;			/* scheduling flag: a process needs swapping in */
char	runout;			/* scheduling flag: a process needs swapping out */
char	runrun;			/* scheduling flag: schedule a higher prio process */
char	curpri;			/* more scheduling */
................................................................................
void profil();	
void nosys();	
void setgid();	
void getgid();	
void ssig();
void sysnet();
void ioctl();


#endif







>







 







>
>

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
95
96
97
98
99
100
101
102
103
104
 * Used to find the super block.
 */
struct	mount
{
	int		 m_dev;		/* device mounted */
	struct buf	*m_bufp;	/* pointer to superblock */
	struct inode	*m_inodp;	/* pointer to mounted on inode */
        int              m_fstyp;       /* filesystem type */
} mount[NMOUNT];

int	mpid;			/* generic for unique process id's */
char	runin;			/* scheduling flag: a process needs swapping in */
char	runout;			/* scheduling flag: a process needs swapping out */
char	runrun;			/* scheduling flag: schedule a higher prio process */
char	curpri;			/* more scheduling */
................................................................................
void profil();	
void nosys();	
void setgid();	
void getgid();	
void ssig();
void sysnet();
void ioctl();
void pair();
void soaccept();
#endif

Changes to v6/tty.c.

386
387
388
389
390
391
392

393
394
395
396
397
398
399
	n = u.u_count;
	u.u_offset += n;
	while (n--) {
		spl7();
		while (tp->t_outq.c_cc > TTHIWAT) {
			(*tp->t_start)(tp);
			sleep(&tp->t_outq, TTOPRI);

		}
		spl0();
		ttyoutput(u.u_segflg ? *base++ : fubyte(base++), tp);
	}
	u.u_count = 0;
	u.u_base = (char*) base;
	(*tp->t_start)(tp);







>







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
	n = u.u_count;
	u.u_offset += n;
	while (n--) {
		spl7();
		while (tp->t_outq.c_cc > TTHIWAT) {
			(*tp->t_start)(tp);
			sleep(&tp->t_outq, TTOPRI);
			spl7();
		}
		spl0();
		ttyoutput(u.u_segflg ? *base++ : fubyte(base++), tp);
	}
	u.u_count = 0;
	u.u_base = (char*) base;
	(*tp->t_start)(tp);

Changes to v6/tty.h.

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
	int	t_dev;		/* device name */
};

#define	TTIPRI	10
#define	TTOPRI	20

#define	CERASE	010		/* ^H */
#define	CBACKSP	030		/* <= */
#define	CEOT	004		/* ^D */
#define	CKILL	025		/* ^U */
#define	CQUIT	034		/* ^\ */
#define	CINTR	003		/* ^C */

/* limits */
#define	TTHIWAT	50







|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
	int	t_dev;		/* device name */
};

#define	TTIPRI	10
#define	TTOPRI	20

#define	CERASE	010		/* ^H */
#define	CBACKSP	127		/* <= */
#define	CEOT	004		/* ^D */
#define	CKILL	025		/* ^U */
#define	CQUIT	034		/* ^\ */
#define	CINTR	003		/* ^C */

/* limits */
#define	TTHIWAT	50