2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <sys/types.h>
31 enum { DT_CHAR
,DT_BLOCK
} type
;
38 #define getnew_devid() (nextdevid++)
41 * Gets ListID by DevID
45 int getlid_devid(int devid
) {
46 struct devlist_item
*dev
;
48 for (i
=0;(dev
= llist_get(devlist
,i
));i
++) {
49 if (dev
->id
==devid
) return i
;
56 * @param name Device name
59 struct devlist_item
*getdev_name(char *name
) {
60 struct devlist_item
*dev
;
63 for (i
=0;(dev
= llist_get(devlist
,i
));i
++) {
64 if (strcmp(dev
->name
,name
)==0) return dev
;
71 * @param path Path to file
75 int devfs_open(const char *path
,struct fuse_file_info
*fi
) {
76 struct devlist_item
*dev
= getdev_name((char*)path
+1);
77 if (dev
!=NULL
) return 0;
83 * @param path Path to file
87 int devfs_close(const char *path
,struct fuse_file_info
*fi
) {
93 * @param path Path to file
94 * @param buf Buffer to store read data in
95 * @param count How many bytes to read
96 * @param offset Offset to start at
98 * @return How many bytes read (-Errorcode)
100 int devfs_read(const char *path
,char *buf
,size_t count
,off_t offset
,struct fuse_file_info
*fi
) {
101 struct devlist_item
*dev
= getdev_name((char*)path
+1);
104 asprintf(&func
,"devfs_read_%x",dev
->owner
);
105 int ret
= rpc_call(func
,0,dev
->id
,count
,offset
);
106 memcpy(buf
,dev
->shmbuf
,count
);
115 * @param path Path to file
116 * @param buf Buffer to get data from
117 * @param count How many bytes to write
118 * @param offset Offset to start at
119 * @param fi File info
120 * @return How many bytes written (-Errorcode)
122 int devfs_write(const char *path
,const char *buf
,size_t count
,off_t offset
,struct fuse_file_info
*fi
) {
123 struct devlist_item
*dev
= getdev_name((char*)path
+1);
126 asprintf(&func
,"devfs_write_%x",dev
->owner
);
127 memcpy(dev
->shmbuf
,buf
,count
);
128 int ret
= rpc_call(func
,0,dev
->id
,count
,offset
);
137 * @param path Path to dir
138 * @param buf Buffer for dir entries
139 * @param filler Filler function
140 * @param off Dir offset
141 * @param fi File info
142 * @return 0=success (-Errorcode)
144 int devfs_readdir(const char *path
,void *buf
,fuse_fill_dir_t filler
,off_t off
,struct fuse_file_info
*fi
) {
145 if (strcmp(path
,"/")==0) {
147 struct devlist_item
*dev
;
148 filler(buf
,".",NULL
,0);
149 filler(buf
,"..",NULL
,0);
150 for (i
=0;(dev
= llist_get(devlist
,i
));i
++) filler(buf
,dev
->name
,NULL
,0);
157 * Gets informations about files
158 * @param path Path to file
159 * @param stbuf Buffer to store informations in
160 * @return 0=success (-Errorcode)
162 int devfs_getattr(const char *path
,struct stat
*stbuf
) {
163 struct devlist_item
*dev
;
164 memset(stbuf
,0,sizeof(struct stat
));
165 if (strcmp(path
,"/") == 0) {
166 stbuf
->st_mode
= S_IFDIR
|0755;
169 else if ((dev
= getdev_name((char*)path
+1))!=NULL
) {
170 stbuf
->st_mode
= (dev
->type
==DT_BLOCK
?S_IFBLK
:S_IFCHR
)|0744;
179 * Creates a new device
180 * @param name Device name
183 int devfs_createdev(char *name
,int shmid
) {
184 int devid
= getnew_devid();
185 if (devid
>=0 && getdev_name(name
)==NULL
) {
186 struct devlist_item
*new = malloc(sizeof(struct devlist_item
));
188 new->name
= strdup(name
);
189 new->owner
= rpc_curpid
;
190 new->shmbuf
= shmat(shmid
,NULL
,0);
191 llist_push(devlist
,new);
195 fprintf(stderr
,"devfs: Could not create device: %s\n",name
);
203 * @return 0=success; -1=failure
205 int devfs_removedev(int id
) {
206 struct devlist_item
*dev
= llist_get(devlist
,getlid_devid(id
));
207 if (dev
!=NULL
&& dev
->owner
==rpc_curpid
) {
208 llist_remove(devlist
,getlid_devid(id
));
219 * @param argc Number of arguments
220 * @param argv Values of arguments
221 * @return Return value
223 int main(int argc
,char *argv
[]) {
224 devlist
= llist_create();
227 rpc_func(devfs_createdev
,"$i",NAME_MAX
+sizeof(int));
228 rpc_func(devfs_removedev
,"i",sizeof(int));
230 struct fuse_operations devfs_oper
= {
232 .release
= devfs_close
,
234 .write
= devfs_write
,
235 .readdir
= devfs_readdir
,
236 .getattr
= devfs_getattr
241 char *fake_argv
[2] = { "devfs","/dev" };
242 fuse_main(fake_argc
,fake_argv
,&devfs_oper
,NULL
);