Changeset 04803bf in mainline for uspace/lib/c/generic/vfs/vfs.c
- Timestamp:
- 2011-03-21T22:00:17Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 143932e3
- Parents:
- b50b5af2 (diff), 7308e84 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/vfs/vfs.c
rb50b5af2 r04803bf 1 1 /* 2 * Copyright (c) 2008 Jakub Jermar 2 * Copyright (c) 2008 Jakub Jermar 3 3 * All rights reserved. 4 4 * … … 35 35 #include <vfs/vfs.h> 36 36 #include <vfs/canonify.h> 37 #include <macros.h> 37 38 #include <stdlib.h> 38 39 #include <unistd.h> … … 42 43 #include <sys/stat.h> 43 44 #include <sys/types.h> 44 #include <ipc/ipc.h>45 45 #include <ipc/services.h> 46 #include <ipc/ns.h> 46 47 #include <async.h> 47 #include <atomic.h> 48 #include <futex.h> 48 #include <fibril_synch.h> 49 49 #include <errno.h> 50 #include <string.h> 50 #include <assert.h> 51 #include <str.h> 51 52 #include <devmap.h> 52 53 #include <ipc/vfs.h> 53 54 #include <ipc/devmap.h> 54 55 56 static async_sess_t vfs_session; 57 58 static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex); 55 59 static int vfs_phone = -1; 56 static futex_t vfs_phone_futex = FUTEX_INITIALIZER; 57 static futex_t cwd_futex = FUTEX_INITIALIZER;58 59 DIR *cwd_dir = NULL;60 char *cwd_path = NULL;61 s ize_t cwd_size = 0;60 61 static FIBRIL_MUTEX_INITIALIZE(cwd_mutex); 62 63 static int cwd_fd = -1; 64 static char *cwd_path = NULL; 65 static size_t cwd_size = 0; 62 66 63 67 char *absolutize(const char *path, size_t *retlen) … … 65 69 char *ncwd_path; 66 70 char *ncwd_path_nc; 67 68 futex_down(&cwd_futex); 71 size_t total_size; 72 73 fibril_mutex_lock(&cwd_mutex); 69 74 size_t size = str_size(path); 70 75 if (*path != '/') { 71 76 if (!cwd_path) { 72 f utex_up(&cwd_futex);77 fibril_mutex_unlock(&cwd_mutex); 73 78 return NULL; 74 79 } 75 ncwd_path_nc = malloc(cwd_size + 1 + size + 1); 80 total_size = cwd_size + 1 + size + 1; 81 ncwd_path_nc = malloc(total_size); 76 82 if (!ncwd_path_nc) { 77 f utex_up(&cwd_futex);83 fibril_mutex_unlock(&cwd_mutex); 78 84 return NULL; 79 85 } 80 str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);86 str_cpy(ncwd_path_nc, total_size, cwd_path); 81 87 ncwd_path_nc[cwd_size] = '/'; 82 88 ncwd_path_nc[cwd_size + 1] = '\0'; 83 89 } else { 84 ncwd_path_nc = malloc(size + 1); 90 total_size = size + 1; 91 ncwd_path_nc = malloc(total_size); 85 92 if (!ncwd_path_nc) { 86 f utex_up(&cwd_futex);93 fibril_mutex_unlock(&cwd_mutex); 87 94 return NULL; 88 95 } 89 96 ncwd_path_nc[0] = '\0'; 90 97 } 91 str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);98 str_append(ncwd_path_nc, total_size, path); 92 99 ncwd_path = canonify(ncwd_path_nc, retlen); 93 100 if (!ncwd_path) { 94 f utex_up(&cwd_futex);101 fibril_mutex_unlock(&cwd_mutex); 95 102 free(ncwd_path_nc); 96 103 return NULL; … … 104 111 free(ncwd_path_nc); 105 112 if (!ncwd_path) { 106 f utex_up(&cwd_futex);113 fibril_mutex_unlock(&cwd_mutex); 107 114 return NULL; 108 115 } 109 f utex_up(&cwd_futex);116 fibril_mutex_unlock(&cwd_mutex); 110 117 return ncwd_path; 111 118 } 112 119 120 /** Connect to VFS service and create session. */ 113 121 static void vfs_connect(void) 114 122 { 115 123 while (vfs_phone < 0) 116 vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0); 117 } 118 119 int mount(const char *fs_name, const char *mp, const char *dev, 124 vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0); 125 126 async_session_create(&vfs_session, vfs_phone, 0); 127 } 128 129 /** Start an async exchange on the VFS session. 130 * 131 * @return New phone to be used during the exchange. 132 */ 133 static int vfs_exchange_begin(void) 134 { 135 fibril_mutex_lock(&vfs_phone_mutex); 136 if (vfs_phone < 0) 137 vfs_connect(); 138 fibril_mutex_unlock(&vfs_phone_mutex); 139 140 return async_exchange_begin(&vfs_session); 141 } 142 143 /** End an async exchange on the VFS session. 144 * 145 * @param phone Phone used during the exchange. 146 */ 147 static void vfs_exchange_end(int phone) 148 { 149 async_exchange_end(&vfs_session, phone); 150 } 151 152 int mount(const char *fs_name, const char *mp, const char *fqdn, 120 153 const char *opts, unsigned int flags) 121 154 { 122 int res; 123 ipcarg_t rc; 124 ipcarg_t rc_orig; 125 aid_t req; 126 dev_handle_t dev_handle; 127 128 res = devmap_device_get_handle(dev, &dev_handle, flags); 129 if (res != EOK) 155 int null_id = -1; 156 char null[DEVMAP_NAME_MAXLEN]; 157 158 if (str_cmp(fqdn, "") == 0) { 159 /* No device specified, create a fresh 160 null/%d device instead */ 161 null_id = devmap_null_create(); 162 163 if (null_id == -1) 164 return ENOMEM; 165 166 snprintf(null, DEVMAP_NAME_MAXLEN, "null/%d", null_id); 167 fqdn = null; 168 } 169 170 devmap_handle_t devmap_handle; 171 int res = devmap_device_get_handle(fqdn, &devmap_handle, flags); 172 if (res != EOK) { 173 if (null_id != -1) 174 devmap_null_destroy(null_id); 175 130 176 return res; 177 } 131 178 132 179 size_t mpa_size; 133 180 char *mpa = absolutize(mp, &mpa_size); 181 if (!mpa) { 182 if (null_id != -1) 183 devmap_null_destroy(null_id); 184 185 return ENOMEM; 186 } 187 188 int vfs_phone = vfs_exchange_begin(); 189 190 sysarg_t rc_orig; 191 aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL); 192 sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size); 193 if (rc != EOK) { 194 vfs_exchange_end(vfs_phone); 195 free(mpa); 196 async_wait_for(req, &rc_orig); 197 198 if (null_id != -1) 199 devmap_null_destroy(null_id); 200 201 if (rc_orig == EOK) 202 return (int) rc; 203 else 204 return (int) rc_orig; 205 } 206 207 rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts)); 208 if (rc != EOK) { 209 vfs_exchange_end(vfs_phone); 210 free(mpa); 211 async_wait_for(req, &rc_orig); 212 213 if (null_id != -1) 214 devmap_null_destroy(null_id); 215 216 if (rc_orig == EOK) 217 return (int) rc; 218 else 219 return (int) rc_orig; 220 } 221 222 rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name)); 223 if (rc != EOK) { 224 vfs_exchange_end(vfs_phone); 225 free(mpa); 226 async_wait_for(req, &rc_orig); 227 228 if (null_id != -1) 229 devmap_null_destroy(null_id); 230 231 if (rc_orig == EOK) 232 return (int) rc; 233 else 234 return (int) rc_orig; 235 } 236 237 /* Ask VFS whether it likes fs_name. */ 238 rc = async_req_0_0(vfs_phone, IPC_M_PING); 239 if (rc != EOK) { 240 vfs_exchange_end(vfs_phone); 241 free(mpa); 242 async_wait_for(req, &rc_orig); 243 244 if (null_id != -1) 245 devmap_null_destroy(null_id); 246 247 if (rc_orig == EOK) 248 return (int) rc; 249 else 250 return (int) rc_orig; 251 } 252 253 vfs_exchange_end(vfs_phone); 254 free(mpa); 255 async_wait_for(req, &rc); 256 257 if ((rc != EOK) && (null_id != -1)) 258 devmap_null_destroy(null_id); 259 260 return (int) rc; 261 } 262 263 int unmount(const char *mp) 264 { 265 sysarg_t rc; 266 sysarg_t rc_orig; 267 aid_t req; 268 size_t mpa_size; 269 char *mpa; 270 271 mpa = absolutize(mp, &mpa_size); 134 272 if (!mpa) 135 273 return ENOMEM; 136 274 137 futex_down(&vfs_phone_futex); 138 async_serialize_start(); 139 vfs_connect(); 140 141 req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL); 142 rc = ipc_data_write_start(vfs_phone, (void *) mpa, mpa_size); 143 if (rc != EOK) { 144 async_wait_for(req, &rc_orig); 145 async_serialize_end(); 146 futex_up(&vfs_phone_futex); 275 int vfs_phone = vfs_exchange_begin(); 276 277 req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL); 278 rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size); 279 if (rc != EOK) { 280 vfs_exchange_end(vfs_phone); 147 281 free(mpa); 148 if (rc_orig == EOK) 149 return (int) rc; 150 else 151 return (int) rc_orig; 152 } 153 154 rc = ipc_data_write_start(vfs_phone, (void *) opts, str_size(opts)); 155 if (rc != EOK) { 156 async_wait_for(req, &rc_orig); 157 async_serialize_end(); 158 futex_up(&vfs_phone_futex); 159 free(mpa); 160 if (rc_orig == EOK) 161 return (int) rc; 162 else 163 return (int) rc_orig; 164 } 165 166 rc = ipc_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name)); 167 if (rc != EOK) { 168 async_wait_for(req, &rc_orig); 169 async_serialize_end(); 170 futex_up(&vfs_phone_futex); 171 free(mpa); 172 if (rc_orig == EOK) 173 return (int) rc; 174 else 175 return (int) rc_orig; 176 } 177 178 /* Ask VFS whether it likes fs_name. */ 179 rc = async_req_0_0(vfs_phone, IPC_M_PING); 180 if (rc != EOK) { 181 async_wait_for(req, &rc_orig); 182 async_serialize_end(); 183 futex_up(&vfs_phone_futex); 184 free(mpa); 185 if (rc_orig == EOK) 186 return (int) rc; 187 else 188 return (int) rc_orig; 189 } 190 191 async_wait_for(req, &rc); 192 async_serialize_end(); 193 futex_up(&vfs_phone_futex); 282 async_wait_for(req, &rc_orig); 283 if (rc_orig == EOK) 284 return (int) rc; 285 else 286 return (int) rc_orig; 287 } 288 289 290 vfs_exchange_end(vfs_phone); 194 291 free(mpa); 292 async_wait_for(req, &rc); 195 293 196 294 return (int) rc; 197 295 } 198 296 199 static int _open(const char *path, int lflag, int oflag, ...) 200 { 201 ipcarg_t rc; 297 static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag) 298 { 299 int vfs_phone = vfs_exchange_begin(); 300 202 301 ipc_call_t answer; 302 aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer); 303 sysarg_t rc = async_data_write_start(vfs_phone, abs, abs_size); 304 305 if (rc != EOK) { 306 vfs_exchange_end(vfs_phone); 307 308 sysarg_t rc_orig; 309 async_wait_for(req, &rc_orig); 310 311 if (rc_orig == EOK) 312 return (int) rc; 313 else 314 return (int) rc_orig; 315 } 316 317 vfs_exchange_end(vfs_phone); 318 async_wait_for(req, &rc); 319 320 if (rc != EOK) 321 return (int) rc; 322 323 return (int) IPC_GET_ARG1(answer); 324 } 325 326 int open(const char *path, int oflag, ...) 327 { 328 size_t abs_size; 329 char *abs = absolutize(path, &abs_size); 330 if (!abs) 331 return ENOMEM; 332 333 int ret = open_internal(abs, abs_size, L_FILE, oflag); 334 free(abs); 335 336 return ret; 337 } 338 339 int open_node(fdi_node_t *node, int oflag) 340 { 341 int vfs_phone = vfs_exchange_begin(); 342 343 ipc_call_t answer; 344 aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle, 345 node->devmap_handle, node->index, oflag, &answer); 346 347 vfs_exchange_end(vfs_phone); 348 349 sysarg_t rc; 350 async_wait_for(req, &rc); 351 352 if (rc != EOK) 353 return (int) rc; 354 355 return (int) IPC_GET_ARG1(answer); 356 } 357 358 int close(int fildes) 359 { 360 sysarg_t rc; 361 362 int vfs_phone = vfs_exchange_begin(); 363 364 rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes); 365 366 vfs_exchange_end(vfs_phone); 367 368 return (int)rc; 369 } 370 371 ssize_t read(int fildes, void *buf, size_t nbyte) 372 { 373 sysarg_t rc; 374 ipc_call_t answer; 375 aid_t req; 376 377 int vfs_phone = vfs_exchange_begin(); 378 379 req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer); 380 rc = async_data_read_start(vfs_phone, (void *)buf, nbyte); 381 if (rc != EOK) { 382 vfs_exchange_end(vfs_phone); 383 384 sysarg_t rc_orig; 385 async_wait_for(req, &rc_orig); 386 387 if (rc_orig == EOK) 388 return (ssize_t) rc; 389 else 390 return (ssize_t) rc_orig; 391 } 392 vfs_exchange_end(vfs_phone); 393 async_wait_for(req, &rc); 394 if (rc == EOK) 395 return (ssize_t) IPC_GET_ARG1(answer); 396 else 397 return rc; 398 } 399 400 ssize_t write(int fildes, const void *buf, size_t nbyte) 401 { 402 sysarg_t rc; 403 ipc_call_t answer; 404 aid_t req; 405 406 int vfs_phone = vfs_exchange_begin(); 407 408 req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer); 409 rc = async_data_write_start(vfs_phone, (void *)buf, nbyte); 410 if (rc != EOK) { 411 vfs_exchange_end(vfs_phone); 412 413 sysarg_t rc_orig; 414 async_wait_for(req, &rc_orig); 415 416 if (rc_orig == EOK) 417 return (ssize_t) rc; 418 else 419 return (ssize_t) rc_orig; 420 } 421 vfs_exchange_end(vfs_phone); 422 async_wait_for(req, &rc); 423 if (rc == EOK) 424 return (ssize_t) IPC_GET_ARG1(answer); 425 else 426 return -1; 427 } 428 429 int fsync(int fildes) 430 { 431 int vfs_phone = vfs_exchange_begin(); 432 433 sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes); 434 435 vfs_exchange_end(vfs_phone); 436 437 return (int) rc; 438 } 439 440 off64_t lseek(int fildes, off64_t offset, int whence) 441 { 442 int vfs_phone = vfs_exchange_begin(); 443 444 sysarg_t newoff_lo; 445 sysarg_t newoff_hi; 446 sysarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes, 447 LOWER32(offset), UPPER32(offset), whence, 448 &newoff_lo, &newoff_hi); 449 450 vfs_exchange_end(vfs_phone); 451 452 if (rc != EOK) 453 return (off64_t) -1; 454 455 return (off64_t) MERGE_LOUP32(newoff_lo, newoff_hi); 456 } 457 458 int ftruncate(int fildes, aoff64_t length) 459 { 460 sysarg_t rc; 461 462 int vfs_phone = vfs_exchange_begin(); 463 464 rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes, 465 LOWER32(length), UPPER32(length)); 466 vfs_exchange_end(vfs_phone); 467 468 return (int) rc; 469 } 470 471 int fstat(int fildes, struct stat *stat) 472 { 473 sysarg_t rc; 474 aid_t req; 475 476 int vfs_phone = vfs_exchange_begin(); 477 478 req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL); 479 rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat)); 480 if (rc != EOK) { 481 vfs_exchange_end(vfs_phone); 482 483 sysarg_t rc_orig; 484 async_wait_for(req, &rc_orig); 485 486 if (rc_orig == EOK) 487 return (ssize_t) rc; 488 else 489 return (ssize_t) rc_orig; 490 } 491 vfs_exchange_end(vfs_phone); 492 async_wait_for(req, &rc); 493 494 return rc; 495 } 496 497 int stat(const char *path, struct stat *stat) 498 { 499 sysarg_t rc; 500 sysarg_t rc_orig; 203 501 aid_t req; 204 502 … … 208 506 return ENOMEM; 209 507 210 futex_down(&vfs_phone_futex); 211 async_serialize_start(); 212 vfs_connect(); 213 214 req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer); 215 rc = ipc_data_write_start(vfs_phone, pa, pa_size); 216 if (rc != EOK) { 217 ipcarg_t rc_orig; 218 219 async_wait_for(req, &rc_orig); 220 async_serialize_end(); 221 futex_up(&vfs_phone_futex); 508 int vfs_phone = vfs_exchange_begin(); 509 510 req = async_send_0(vfs_phone, VFS_IN_STAT, NULL); 511 rc = async_data_write_start(vfs_phone, pa, pa_size); 512 if (rc != EOK) { 513 vfs_exchange_end(vfs_phone); 222 514 free(pa); 223 if (rc_orig == EOK) 224 return (int) rc; 225 else 226 return (int) rc_orig; 227 } 228 async_wait_for(req, &rc); 229 async_serialize_end(); 230 futex_up(&vfs_phone_futex); 515 async_wait_for(req, &rc_orig); 516 if (rc_orig == EOK) 517 return (int) rc; 518 else 519 return (int) rc_orig; 520 } 521 rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat)); 522 if (rc != EOK) { 523 vfs_exchange_end(vfs_phone); 524 free(pa); 525 async_wait_for(req, &rc_orig); 526 if (rc_orig == EOK) 527 return (int) rc; 528 else 529 return (int) rc_orig; 530 } 531 vfs_exchange_end(vfs_phone); 231 532 free(pa); 232 233 if (rc != EOK) 234 return (int) rc; 235 236 return (int) IPC_GET_ARG1(answer); 237 } 238 239 int open(const char *path, int oflag, ...) 240 { 241 return _open(path, L_FILE, oflag); 242 } 243 244 int open_node(fdi_node_t *node, int oflag) 245 { 246 futex_down(&vfs_phone_futex); 247 async_serialize_start(); 248 vfs_connect(); 249 250 ipc_call_t answer; 251 aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle, 252 node->dev_handle, node->index, oflag, &answer); 253 254 ipcarg_t rc; 255 async_wait_for(req, &rc); 256 async_serialize_end(); 257 futex_up(&vfs_phone_futex); 258 259 if (rc != EOK) 260 return (int) rc; 261 262 return (int) IPC_GET_ARG1(answer); 263 } 264 265 int close(int fildes) 266 { 267 ipcarg_t rc; 268 269 futex_down(&vfs_phone_futex); 270 async_serialize_start(); 271 vfs_connect(); 272 273 rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes); 274 275 async_serialize_end(); 276 futex_up(&vfs_phone_futex); 277 278 return (int)rc; 279 } 280 281 ssize_t read(int fildes, void *buf, size_t nbyte) 282 { 283 ipcarg_t rc; 284 ipc_call_t answer; 285 aid_t req; 286 287 futex_down(&vfs_phone_futex); 288 async_serialize_start(); 289 vfs_connect(); 290 291 req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer); 292 rc = ipc_data_read_start(vfs_phone, (void *)buf, nbyte); 293 if (rc != EOK) { 294 ipcarg_t rc_orig; 295 296 async_wait_for(req, &rc_orig); 297 async_serialize_end(); 298 futex_up(&vfs_phone_futex); 299 if (rc_orig == EOK) 300 return (ssize_t) rc; 301 else 302 return (ssize_t) rc_orig; 303 } 304 async_wait_for(req, &rc); 305 async_serialize_end(); 306 futex_up(&vfs_phone_futex); 307 if (rc == EOK) 308 return (ssize_t) IPC_GET_ARG1(answer); 309 else 310 return rc; 311 } 312 313 ssize_t write(int fildes, const void *buf, size_t nbyte) 314 { 315 ipcarg_t rc; 316 ipc_call_t answer; 317 aid_t req; 318 319 futex_down(&vfs_phone_futex); 320 async_serialize_start(); 321 vfs_connect(); 322 323 req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer); 324 rc = ipc_data_write_start(vfs_phone, (void *)buf, nbyte); 325 if (rc != EOK) { 326 ipcarg_t rc_orig; 327 328 async_wait_for(req, &rc_orig); 329 async_serialize_end(); 330 futex_up(&vfs_phone_futex); 331 if (rc_orig == EOK) 332 return (ssize_t) rc; 333 else 334 return (ssize_t) rc_orig; 335 } 336 async_wait_for(req, &rc); 337 async_serialize_end(); 338 futex_up(&vfs_phone_futex); 339 if (rc == EOK) 340 return (ssize_t) IPC_GET_ARG1(answer); 341 else 342 return -1; 343 } 344 345 int fsync(int fildes) 346 { 347 futex_down(&vfs_phone_futex); 348 async_serialize_start(); 349 vfs_connect(); 350 351 ipcarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes); 352 353 async_serialize_end(); 354 futex_up(&vfs_phone_futex); 355 356 return (int) rc; 357 } 358 359 off_t lseek(int fildes, off_t offset, int whence) 360 { 361 ipcarg_t rc; 362 363 futex_down(&vfs_phone_futex); 364 async_serialize_start(); 365 vfs_connect(); 366 367 ipcarg_t newoffs; 368 rc = async_req_3_1(vfs_phone, VFS_IN_SEEK, fildes, offset, whence, 369 &newoffs); 370 371 async_serialize_end(); 372 futex_up(&vfs_phone_futex); 373 374 if (rc != EOK) 375 return (off_t) -1; 376 377 return (off_t) newoffs; 378 } 379 380 int ftruncate(int fildes, off_t length) 381 { 382 ipcarg_t rc; 383 384 futex_down(&vfs_phone_futex); 385 async_serialize_start(); 386 vfs_connect(); 387 388 rc = async_req_2_0(vfs_phone, VFS_IN_TRUNCATE, fildes, length); 389 async_serialize_end(); 390 futex_up(&vfs_phone_futex); 391 return (int) rc; 392 } 393 394 int fstat(int fildes, struct stat *stat) 395 { 396 ipcarg_t rc; 397 aid_t req; 398 399 futex_down(&vfs_phone_futex); 400 async_serialize_start(); 401 vfs_connect(); 402 403 req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL); 404 rc = ipc_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat)); 405 if (rc != EOK) { 406 ipcarg_t rc_orig; 407 408 async_wait_for(req, &rc_orig); 409 async_serialize_end(); 410 futex_up(&vfs_phone_futex); 411 if (rc_orig == EOK) 412 return (ssize_t) rc; 413 else 414 return (ssize_t) rc_orig; 415 } 416 async_wait_for(req, &rc); 417 async_serialize_end(); 418 futex_up(&vfs_phone_futex); 419 533 async_wait_for(req, &rc); 420 534 return rc; 421 535 } 422 536 423 int stat(const char *path, struct stat *stat) 424 { 425 ipcarg_t rc; 426 ipcarg_t rc_orig; 537 DIR *opendir(const char *dirname) 538 { 539 DIR *dirp = malloc(sizeof(DIR)); 540 if (!dirp) 541 return NULL; 542 543 size_t abs_size; 544 char *abs = absolutize(dirname, &abs_size); 545 if (!abs) { 546 free(dirp); 547 return NULL; 548 } 549 550 int ret = open_internal(abs, abs_size, L_DIRECTORY, 0); 551 free(abs); 552 553 if (ret < 0) { 554 free(dirp); 555 return NULL; 556 } 557 558 dirp->fd = ret; 559 return dirp; 560 } 561 562 struct dirent *readdir(DIR *dirp) 563 { 564 ssize_t len = read(dirp->fd, &dirp->res.d_name[0], NAME_MAX + 1); 565 if (len <= 0) 566 return NULL; 567 return &dirp->res; 568 } 569 570 void rewinddir(DIR *dirp) 571 { 572 (void) lseek(dirp->fd, 0, SEEK_SET); 573 } 574 575 int closedir(DIR *dirp) 576 { 577 (void) close(dirp->fd); 578 free(dirp); 579 return 0; 580 } 581 582 int mkdir(const char *path, mode_t mode) 583 { 584 sysarg_t rc; 427 585 aid_t req; 428 586 … … 432 590 return ENOMEM; 433 591 434 futex_down(&vfs_phone_futex); 435 async_serialize_start(); 436 vfs_connect(); 437 438 req = async_send_0(vfs_phone, VFS_IN_STAT, NULL); 439 rc = ipc_data_write_start(vfs_phone, pa, pa_size); 440 if (rc != EOK) { 441 async_wait_for(req, &rc_orig); 442 async_serialize_end(); 443 futex_up(&vfs_phone_futex); 592 int vfs_phone = vfs_exchange_begin(); 593 594 req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL); 595 rc = async_data_write_start(vfs_phone, pa, pa_size); 596 if (rc != EOK) { 597 vfs_exchange_end(vfs_phone); 444 598 free(pa); 445 if (rc_orig == EOK) 446 return (int) rc; 447 else 448 return (int) rc_orig; 449 } 450 rc = ipc_data_read_start(vfs_phone, stat, sizeof(struct stat)); 451 if (rc != EOK) { 452 async_wait_for(req, &rc_orig); 453 async_serialize_end(); 454 futex_up(&vfs_phone_futex); 455 free(pa); 456 if (rc_orig == EOK) 457 return (int) rc; 458 else 459 return (int) rc_orig; 460 } 461 async_wait_for(req, &rc); 462 async_serialize_end(); 463 futex_up(&vfs_phone_futex); 599 600 sysarg_t rc_orig; 601 async_wait_for(req, &rc_orig); 602 603 if (rc_orig == EOK) 604 return (int) rc; 605 else 606 return (int) rc_orig; 607 } 608 vfs_exchange_end(vfs_phone); 464 609 free(pa); 610 async_wait_for(req, &rc); 465 611 return rc; 466 612 } 467 613 468 DIR *opendir(const char *dirname) 469 { 470 DIR *dirp = malloc(sizeof(DIR)); 471 if (!dirp) 472 return NULL; 473 dirp->fd = _open(dirname, L_DIRECTORY, 0); 474 if (dirp->fd < 0) { 475 free(dirp); 476 return NULL; 477 } 478 return dirp; 479 } 480 481 struct dirent *readdir(DIR *dirp) 482 { 483 ssize_t len = read(dirp->fd, &dirp->res.d_name[0], NAME_MAX + 1); 484 if (len <= 0) 485 return NULL; 486 return &dirp->res; 487 } 488 489 void rewinddir(DIR *dirp) 490 { 491 (void) lseek(dirp->fd, 0, SEEK_SET); 492 } 493 494 int closedir(DIR *dirp) 495 { 496 (void) close(dirp->fd); 497 free(dirp); 498 return 0; 499 } 500 501 int mkdir(const char *path, mode_t mode) 502 { 503 ipcarg_t rc; 614 static int _unlink(const char *path, int lflag) 615 { 616 sysarg_t rc; 504 617 aid_t req; 505 618 … … 508 621 if (!pa) 509 622 return ENOMEM; 510 511 futex_down(&vfs_phone_futex); 512 async_serialize_start(); 513 vfs_connect(); 514 515 req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL); 516 rc = ipc_data_write_start(vfs_phone, pa, pa_size); 517 if (rc != EOK) { 518 ipcarg_t rc_orig; 519 520 async_wait_for(req, &rc_orig); 521 async_serialize_end(); 522 futex_up(&vfs_phone_futex); 623 624 int vfs_phone = vfs_exchange_begin(); 625 626 req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL); 627 rc = async_data_write_start(vfs_phone, pa, pa_size); 628 if (rc != EOK) { 629 vfs_exchange_end(vfs_phone); 523 630 free(pa); 524 if (rc_orig == EOK) 525 return (int) rc; 526 else 527 return (int) rc_orig; 528 } 529 async_wait_for(req, &rc); 530 async_serialize_end(); 531 futex_up(&vfs_phone_futex); 631 632 sysarg_t rc_orig; 633 async_wait_for(req, &rc_orig); 634 635 if (rc_orig == EOK) 636 return (int) rc; 637 else 638 return (int) rc_orig; 639 } 640 vfs_exchange_end(vfs_phone); 532 641 free(pa); 642 async_wait_for(req, &rc); 533 643 return rc; 534 644 } 535 645 536 static int _unlink(const char *path, int lflag)537 {538 ipcarg_t rc;539 aid_t req;540 541 size_t pa_size;542 char *pa = absolutize(path, &pa_size);543 if (!pa)544 return ENOMEM;545 546 futex_down(&vfs_phone_futex);547 async_serialize_start();548 vfs_connect();549 550 req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);551 rc = ipc_data_write_start(vfs_phone, pa, pa_size);552 if (rc != EOK) {553 ipcarg_t rc_orig;554 555 async_wait_for(req, &rc_orig);556 async_serialize_end();557 futex_up(&vfs_phone_futex);558 free(pa);559 if (rc_orig == EOK)560 return (int) rc;561 else562 return (int) rc_orig;563 }564 async_wait_for(req, &rc);565 async_serialize_end();566 futex_up(&vfs_phone_futex);567 free(pa);568 return rc;569 }570 571 646 int unlink(const char *path) 572 647 { … … 581 656 int rename(const char *old, const char *new) 582 657 { 583 ipcarg_t rc;584 ipcarg_t rc_orig;658 sysarg_t rc; 659 sysarg_t rc_orig; 585 660 aid_t req; 586 661 … … 597 672 } 598 673 599 futex_down(&vfs_phone_futex); 600 async_serialize_start(); 601 vfs_connect(); 674 int vfs_phone = vfs_exchange_begin(); 602 675 603 676 req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL); 604 rc = ipc_data_write_start(vfs_phone, olda, olda_size); 605 if (rc != EOK) { 606 async_wait_for(req, &rc_orig); 607 async_serialize_end(); 608 futex_up(&vfs_phone_futex); 677 rc = async_data_write_start(vfs_phone, olda, olda_size); 678 if (rc != EOK) { 679 vfs_exchange_end(vfs_phone); 609 680 free(olda); 610 681 free(newa); 611 if (rc_orig == EOK) 612 return (int) rc; 613 else 614 return (int) rc_orig; 615 } 616 rc = ipc_data_write_start(vfs_phone, newa, newa_size); 617 if (rc != EOK) { 618 async_wait_for(req, &rc_orig); 619 async_serialize_end(); 620 futex_up(&vfs_phone_futex); 682 async_wait_for(req, &rc_orig); 683 if (rc_orig == EOK) 684 return (int) rc; 685 else 686 return (int) rc_orig; 687 } 688 rc = async_data_write_start(vfs_phone, newa, newa_size); 689 if (rc != EOK) { 690 vfs_exchange_end(vfs_phone); 621 691 free(olda); 622 692 free(newa); 623 if (rc_orig == EOK) 624 return (int) rc; 625 else 626 return (int) rc_orig; 627 } 628 async_wait_for(req, &rc); 629 async_serialize_end(); 630 futex_up(&vfs_phone_futex); 693 async_wait_for(req, &rc_orig); 694 if (rc_orig == EOK) 695 return (int) rc; 696 else 697 return (int) rc_orig; 698 } 699 vfs_exchange_end(vfs_phone); 631 700 free(olda); 632 701 free(newa); 702 async_wait_for(req, &rc); 633 703 return rc; 634 704 } … … 636 706 int chdir(const char *path) 637 707 { 638 size_t pa_size;639 char * pa = absolutize(path, &pa_size);640 if (! pa)708 size_t abs_size; 709 char *abs = absolutize(path, &abs_size); 710 if (!abs) 641 711 return ENOMEM; 642 643 DIR *d = opendir(pa); 644 if (!d) { 645 free(pa); 712 713 int fd = open_internal(abs, abs_size, L_DIRECTORY, O_DESC); 714 715 if (fd < 0) { 716 free(abs); 646 717 return ENOENT; 647 718 } 648 649 futex_down(&cwd_futex); 650 if (cwd_dir) { 651 closedir(cwd_dir); 652 cwd_dir = NULL; 653 free(cwd_path); 654 cwd_path = NULL; 655 cwd_size = 0; 656 } 657 cwd_dir = d; 658 cwd_path = pa; 659 cwd_size = pa_size; 660 futex_up(&cwd_futex); 719 720 fibril_mutex_lock(&cwd_mutex); 721 722 if (cwd_fd >= 0) 723 close(cwd_fd); 724 725 726 if (cwd_path) 727 free(cwd_path); 728 729 cwd_fd = fd; 730 cwd_path = abs; 731 cwd_size = abs_size; 732 733 fibril_mutex_unlock(&cwd_mutex); 661 734 return EOK; 662 735 } … … 664 737 char *getcwd(char *buf, size_t size) 665 738 { 666 if ( !size)739 if (size == 0) 667 740 return NULL; 668 futex_down(&cwd_futex); 669 if (size < cwd_size + 1) { 670 futex_up(&cwd_futex); 741 742 fibril_mutex_lock(&cwd_mutex); 743 744 if ((cwd_size == 0) || (size < cwd_size + 1)) { 745 fibril_mutex_unlock(&cwd_mutex); 671 746 return NULL; 672 747 } 748 673 749 str_cpy(buf, size, cwd_path); 674 futex_up(&cwd_futex); 750 fibril_mutex_unlock(&cwd_mutex); 751 675 752 return buf; 676 753 } … … 683 760 rc = fstat(fildes, &stat); 684 761 685 if (!stat.dev fs_stat.device)762 if (!stat.device) 686 763 return -1; 687 764 688 return devmap_device_connect(stat.dev fs_stat.device, 0);765 return devmap_device_connect(stat.device, 0); 689 766 } 690 767 … … 698 775 if (rc == EOK) { 699 776 node->fs_handle = stat.fs_handle; 700 node->dev _handle = stat.dev_handle;777 node->devmap_handle = stat.devmap_handle; 701 778 node->index = stat.index; 702 779 } 703 780 704 781 return rc; 782 } 783 784 int dup2(int oldfd, int newfd) 785 { 786 int vfs_phone = vfs_exchange_begin(); 787 788 sysarg_t ret; 789 sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret); 790 791 vfs_exchange_end(vfs_phone); 792 793 if (rc == EOK) 794 return (int) ret; 795 796 return (int) rc; 705 797 } 706 798
Note:
See TracChangeset
for help on using the changeset viewer.