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