xref: /inferno-os/os/port/devroot.c (revision ecc9caba0e344ed50c05ee8156b2734f4d76e463)
1  #include	"u.h"
2  #include	"../port/lib.h"
3  #include	"mem.h"
4  #include	"dat.h"
5  #include	"fns.h"
6  #include	"../port/error.h"
7  
8  extern Rootdata rootdata[];
9  extern Dirtab roottab[];
10  extern int	rootmaxq;
11  
12  static Chan*
13  rootattach(char *spec)
14  {
15  	int i;
16  	ulong len;
17  	Rootdata *r;
18  
19  	if(*spec)
20  		error(Ebadspec);
21  	for (i = 0; i < rootmaxq; i++){
22  		r = &rootdata[i];
23  		if (r->sizep){
24  			len = *r->sizep;
25  			r->size = len;
26  			roottab[i].length = len;
27  		}
28  	}
29  	return devattach('/', spec);
30  }
31  
32  static int
33  rootgen(Chan *c, char *name, Dirtab *tab, int nd, int s, Dir *dp)
34  {
35  	int p, i;
36  	Rootdata *r;
37  
38  	if(s == DEVDOTDOT){
39  		p = rootdata[c->qid.path].dotdot;
40  		c->qid.path = p;
41  		c->qid.type = QTDIR;
42  		name = "#/";
43  		if(p != 0){
44  			for(i = 0; i < rootmaxq; i++)
45  				if(roottab[i].qid.path == c->qid.path){
46  					name = roottab[i].name;
47  					break;
48  				}
49  		}
50  		devdir(c, c->qid, name, 0, eve, 0555, dp);
51  		return 1;
52  	}
53  	if(name != nil){
54  		isdir(c);
55  		r = &rootdata[(int)c->qid.path];
56  		tab = r->ptr;
57  		for(i=0; i<r->size; i++, tab++)
58  			if(strcmp(tab->name, name) == 0){
59  				devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
60  				return 1;
61  			}
62  		return -1;
63  	}
64  	if(s >= nd)
65  		return -1;
66  	tab += s;
67  	devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
68  	return 1;
69  }
70  
71  static Walkqid*
72  rootwalk(Chan *c, Chan *nc, char **name, int nname)
73  {
74  	ulong p;
75  
76  	p = c->qid.path;
77  	if(nname == 0)
78  		p = rootdata[p].dotdot;
79  	return devwalk(c, nc, name, nname, rootdata[p].ptr, rootdata[p].size, rootgen);
80  }
81  
82  static int
83  rootstat(Chan *c, uchar *dp, int n)
84  {
85  	int p;
86  
87  	p = rootdata[c->qid.path].dotdot;
88  	return devstat(c, dp, n, rootdata[p].ptr, rootdata[p].size, rootgen);
89  }
90  
91  static Chan*
92  rootopen(Chan *c, int omode)
93  {
94  	int p;
95  
96  	p = rootdata[c->qid.path].dotdot;
97  	return devopen(c, omode, rootdata[p].ptr, rootdata[p].size, rootgen);
98  }
99  
100  /*
101   * sysremove() knows this is a nop
102   */
103  static void
104  rootclose(Chan*)
105  {
106  }
107  
108  static long
109  rootread(Chan *c, void *buf, long n, vlong offset)
110  {
111  	ulong p, len;
112  	uchar *data;
113  
114  	p = c->qid.path;
115  	if(c->qid.type & QTDIR)
116  		return devdirread(c, buf, n, rootdata[p].ptr, rootdata[p].size, rootgen);
117  	len = rootdata[p].size;
118  	if(offset < 0 || offset >= len)
119  		return 0;
120  	if(offset+n > len)
121  		n = len - offset;
122  	data = rootdata[p].ptr;
123  	memmove(buf, data+offset, n);
124  	return n;
125  }
126  
127  static long
128  rootwrite(Chan*, void*, long, vlong)
129  {
130  	error(Eperm);
131  	return 0;
132  }
133  
134  Dev rootdevtab = {
135  	'/',
136  	"root",
137  
138  	devreset,
139  	devinit,
140  	devshutdown,
141  	rootattach,
142  	rootwalk,
143  	rootstat,
144  	rootopen,
145  	devcreate,
146  	rootclose,
147  	rootread,
148  	devbread,
149  	rootwrite,
150  	devbwrite,
151  	devremove,
152  	devwstat,
153  };
154