openblt

a hobby OS from the late 90s
git clone http://frotz.net/git/openblt.git
Log | Files | Refs | LICENSE

vfs.c (6805B)


      1 /* Copyright 1999, Sidney Cammeresi. All rights reserved.
      2 ** Distributed under the terms of the OpenBLT License
      3 */
      4 
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <dirent.h>
      9 #include <errno.h>
     10 #include <unistd.h>
     11 #include <sys/stat.h>
     12 #include <blt/os.h>
     13 #include <blt/syscall.h>
     14 #include <blt/namer.h>
     15 #include <blt/fdl.h>
     16 #include <blt/libsyms.h>
     17 #include <blt/vfs.h>
     18 
     19 static int vfs_public_port, vfs_local_port, vfs_remote_port, filename_area;
     20 static char *nameptr;
     21 
     22 static void __vfs_openconn (int src_port, int filename_area);
     23 ssize_t _vfs_read (void *cookie, void *buf, size_t count);
     24 int _vfs_close (void *cookie);
     25 
     26 static fdl_type vfs_fdl_handler = { "vfs", _vfs_read, NULL, NULL, _vfs_close };
     27 
     28 weak_alias (_opendir, opendir)
     29 weak_alias (_readdir, readdir)
     30 weak_alias (_closedir, closedir)
     31 weak_alias (_open, open)
     32 weak_alias (_stat, stat)
     33 weak_alias (_mkdir, mkdir)
     34 
     35 void __libc_init_vfs (void)
     36 {
     37 	vfs_public_port = namer_find ("vfs", 1);
     38 	vfs_local_port = port_create (vfs_public_port,"vfs_public_port");
     39 
     40 	filename_area = area_create (0x1000, 0, (void **) &nameptr, 0);
     41 	__vfs_openconn (vfs_local_port, filename_area);
     42 }
     43 
     44 init_info __init_posix_vfs = {
     45 	&__libc_init_vfs,
     46 	3
     47 };
     48 
     49 void __libc_fini_vfs (void)
     50 {
     51 }
     52 
     53 static void __vfs_openconn (int src_port, int filename_area)
     54 {
     55 	msg_hdr_t mh;
     56 	vfs_cmd_t vc;
     57 	vfs_res_t vr;
     58 
     59 	vc.cmd = VFS_OPENCONN;
     60 	vc.data[0] = filename_area;
     61 
     62 	mh.src = vfs_local_port;
     63 	mh.dst = vfs_public_port;
     64 	mh.data = &vc;
     65 	mh.size = sizeof (vc);
     66 	old_port_send (&mh);
     67 
     68 	mh.src = 0; /* XXX */
     69 	mh.dst = vfs_local_port;
     70 	mh.data = &vr;
     71 	mh.size = sizeof (vr);
     72 	old_port_recv (&mh);
     73 
     74 	if (vr.status != VFS_OK)
     75 	{
     76 		_printf ("libc: couldn't open connection to vfs\n");
     77 		vfs_local_port = vfs_remote_port = -1;
     78 	}
     79 	vfs_remote_port = vr.data[0];
     80 }
     81 
     82 DIR *_opendir (const char *name)
     83 {
     84 	int area;
     85 	void *ptr;
     86 	msg_hdr_t msg;
     87 	vfs_cmd_t vc;
     88 	vfs_res_t vr;
     89 	DIR *dirp;
     90 
     91 	strlcpy (nameptr, name, BLT_MAX_NAME_LENGTH);
     92 	area = area_create (0x2000, 0, &ptr, 0);
     93 
     94 	vc.cmd = VFS_OPENDIR;
     95 	vc.data[0] = 0;
     96 	vc.data[1] = area;
     97 	vc.data[2] = 0;
     98 	vc.data[3] = 0x2000;
     99 	msg.src = vfs_local_port;
    100 	msg.dst = vfs_remote_port;
    101 	msg.data = &vc;
    102 	msg.size = sizeof (vfs_cmd_t);
    103 	old_port_send (&msg);
    104 
    105 	msg.src = vfs_remote_port;
    106 	msg.dst = vfs_local_port;
    107 	msg.data = &vr;
    108 	msg.size = sizeof (vfs_res_t);
    109 	old_port_recv (&msg);
    110 
    111 	if (vr.status != VFS_OK)
    112 	{
    113 		errno = vr.errno;
    114 		return NULL;
    115 	}
    116 	//_printf ("libc: opendir got fd %d\n", vr.data[0]);
    117 	dirp = malloc (sizeof (DIR));
    118 	dirp->fd = vr.data[0];
    119 	dirp->hoffset = 0;
    120 	dirp->head = ptr;
    121 	dirp->current = ptr;
    122 	dirp->more = vr.data[2];
    123 	dirp->len = vr.data[1];
    124 	dirp->left = dirp->len;
    125 	return dirp;
    126 }
    127 
    128 struct dirent *_readdir (DIR *dirp)
    129 {
    130 	if (dirp == NULL)
    131 		return NULL;
    132 	else
    133 		return (dirp->left-- > 0) ? dirp->current++ : NULL;
    134 }
    135 
    136 int _closedir (DIR *dirp)
    137 {
    138 	msg_hdr_t msg;
    139 	vfs_cmd_t vc;
    140 	vfs_res_t vr;
    141 
    142 	if (dirp == NULL)
    143 	{
    144 		errno = EBADF;
    145 		return -1;
    146 	}
    147 	vc.cmd = VFS_CLOSEDIR;
    148 	vc.data[0] = dirp->fd;
    149 	msg.src = vfs_local_port;
    150 	msg.dst = vfs_remote_port;
    151 	msg.data = &vc;
    152 	msg.size = sizeof (vfs_cmd_t);
    153 	old_port_send (&msg);
    154 
    155 	msg.src = vfs_remote_port;
    156 	msg.dst = vfs_local_port;
    157 	msg.data = &vr;
    158 	msg.size = sizeof (vfs_res_t);
    159 	old_port_recv (&msg);
    160 
    161 	errno = vr.errno;
    162 	return (vr.status == VFS_OK) ? 0 : 1;
    163 }
    164 
    165 int _open (const char *path, int flags, mode_t mode)
    166 {
    167 	int i, area;
    168 	void *ptr;
    169 	msg_hdr_t msg;
    170 	vfs_cmd_t vc;
    171 	vfs_res_t vr;
    172 	vfs_fd *fd;
    173 
    174 	strlcpy (nameptr, path, BLT_MAX_NAME_LENGTH);
    175 	area = area_create (0x2000, 0, &ptr, 0);
    176 
    177 	vc.cmd = VFS_OPEN;
    178 	vc.data[0] = 0;
    179 	vc.data[1] = area;
    180 	vc.data[2] = 0;
    181 	vc.data[3] = 0x2000;
    182 	msg.src = vfs_local_port;
    183 	msg.dst = vfs_remote_port;
    184 	msg.data = &vc;
    185 	msg.size = sizeof (vfs_cmd_t);
    186 	old_port_send (&msg);
    187 
    188 	msg.src = vfs_remote_port;
    189 	msg.dst = vfs_local_port;
    190 	msg.data = &vr;
    191 	msg.size = sizeof (vfs_res_t);
    192 	old_port_recv (&msg);
    193 
    194 	if (vr.status != VFS_OK)
    195 	{
    196 		errno = vr.errno;
    197 		return -1;
    198 	}
    199 	//_printf ("libc: open got %d %d %d\n", vr.data[0], vr.data[1], vr.data[2]);
    200 	fd = malloc (sizeof (vfs_fd));
    201 	i = _fdl_alloc_descriptor (&vfs_fdl_handler, fd);
    202 	fd->buf = ptr;
    203 	fd->offset = 0;
    204 	fd->srv_fd = vr.data[0];
    205 	fd->length = vr.data[1];
    206 	fd->more = vr.data[2];
    207 	return i;
    208 }
    209 
    210 int _vfs_close (void *cookie)
    211 {
    212 	msg_hdr_t mh;
    213 	vfs_cmd_t vc;
    214 	vfs_res_t vr;
    215 	vfs_fd *vfd;
    216 
    217 	vfd = cookie;
    218 	vc.cmd = VFS_CLOSE;
    219 	vc.data[0] = vfd->srv_fd;
    220 	mh.src = vfs_local_port;
    221 	mh.dst = vfs_remote_port;
    222 	mh.data = &vc;
    223 	mh.size = sizeof (vfs_cmd_t);
    224 	old_port_send (&mh);
    225 
    226 	mh.src = vfs_remote_port;
    227 	mh.dst = vfs_local_port;
    228 	mh.data = &vr;
    229 	mh.size = sizeof (vfs_res_t);
    230 	old_port_recv (&mh);
    231 
    232 	if (vr.status != VFS_OK)
    233 	{
    234 		errno = vr.errno;
    235 		return -1;
    236 	}
    237 	return 0;
    238 }
    239 
    240 ssize_t _vfs_read (void *cookie, void *buf, size_t count)
    241 {
    242 	int i, len;
    243 	msg_hdr_t mh;
    244 	vfs_cmd_t vc;
    245 	vfs_res_t vr;
    246 	register vfs_fd *vfd;
    247 
    248 	vfd = cookie;
    249 	vc.cmd = VFS_READ;
    250 	vc.data[0] = vfd->srv_fd;
    251 	vc.data[1] = count;
    252 	mh.src = vfs_local_port;
    253 	mh.dst = vfs_remote_port;
    254 	mh.data = &vc;
    255 	mh.size = sizeof (vfs_cmd_t);
    256 	old_port_send (&mh);
    257 
    258 	mh.src = 0;
    259 	mh.dst = vfs_local_port;
    260 	mh.data = &vr;
    261 	mh.size = sizeof (vfs_res_t);
    262 	old_port_recv (&mh);
    263 	len = vr.data[0];
    264 	if (!len)
    265 		return errno = 0;
    266 
    267 	if (len < 0x1000)
    268 	{
    269 		mh.data = buf;
    270 		mh.size = count;
    271 		old_port_recv (&mh);
    272 		errno = vr.errno;
    273 		return len;
    274 	}
    275 	else
    276 	{
    277 		for (i = 0; len > 0x1000; i += 0x1000, len -= 0x1000)
    278 		{
    279 			mh.data = (char *) buf + i;
    280 			mh.size = 0x1000;
    281 			old_port_recv (&mh);
    282 		}
    283 		mh.data = (char *) buf + i;
    284 		mh.size = len;
    285 		old_port_recv (&mh);
    286 		errno = vr.errno;
    287 		return i + len;
    288 	}
    289 }
    290 
    291 int _stat (const char *filename, struct stat *buf)
    292 {
    293 	msg_hdr_t msg;
    294 	vfs_cmd_t vc;
    295 	vfs_res_t *vr;
    296 
    297 	strlcpy (nameptr, filename, BLT_MAX_NAME_LENGTH);
    298 	vc.cmd = VFS_RSTAT;
    299 	vc.data[0] = 0;
    300 	msg.src = vfs_local_port;
    301 	msg.dst = vfs_remote_port;
    302 	msg.data = &vc;
    303 	msg.size = sizeof (vfs_cmd_t);
    304 	old_port_send (&msg);
    305 
    306 	vr = malloc (sizeof (vfs_res_t) + sizeof (struct stat));
    307 	msg.dst = vfs_local_port;
    308 	msg.data = vr;
    309 	msg.size = sizeof (vfs_res_t) + sizeof (struct stat);
    310 	old_port_recv (&msg);
    311 
    312 	if (vr->status == VFS_OK)
    313 	{
    314 		memcpy (buf, (void *) vr + sizeof (vfs_res_t), sizeof (struct stat));
    315 		return 0;
    316 	}
    317 	else
    318 	{
    319 		errno = vr->errno;
    320 		return -1;
    321 	}
    322 }
    323 
    324 int _mkdir (const char *path, mode_t mode)
    325 {
    326 	msg_hdr_t mh;
    327 	vfs_cmd_t vc;
    328 	vfs_res_t vr;
    329 
    330 	strlcpy (nameptr, path, BLT_MAX_NAME_LENGTH);
    331 	vc.cmd = VFS_MKDIR;
    332 	vc.data[0] = 0;
    333 	vc.data[1] = mode;
    334 	mh.src = vfs_local_port;
    335 	mh.dst = vfs_remote_port;
    336 	mh.data = &vc;
    337 	mh.size = sizeof (vfs_cmd_t);
    338 	old_port_send (&mh);
    339 
    340 	mh.src = vfs_remote_port;
    341 	mh.dst = vfs_local_port;
    342 	mh.data = &vr;
    343 	mh.size = sizeof (vfs_res_t);
    344 	old_port_recv (&mh);
    345 
    346 	if (vr.status != VFS_OK)
    347 	{
    348 		errno = vr.errno;
    349 		return -1;
    350 	}
    351 	return 0;
    352 }
    353