! Open a file * * @param[in,out] r newlib reentrancy struct * @param[out] fileStruct Pointer to file struct to fill in * @param[in] path Path to open * @param[in] flags Open flags from open(2) * @param[in] mode Permissions to set on create * * @returns 0 for success * @returns -1 for error */
| 485 | * @returns -1 for error |
| 486 | */ |
| 487 | static int |
| 488 | archive_open(struct _reent *r, |
| 489 | void *fileStruct, |
| 490 | const char *path, |
| 491 | int flags, |
| 492 | int mode) |
| 493 | { |
| 494 | Handle fd; |
| 495 | Result rc; |
| 496 | u32 archive_flags = 0; |
| 497 | u32 attributes = 0; |
| 498 | FS_Path fs_path; |
| 499 | archive_fsdevice *device = r->deviceData; |
| 500 | |
| 501 | fs_path = archive_utf16path(r, path, &device); |
| 502 | if(fs_path.data == NULL) |
| 503 | return -1; |
| 504 | |
| 505 | /* get pointer to our data */ |
| 506 | archive_file_t *file = (archive_file_t*)fileStruct; |
| 507 | |
| 508 | /* check access mode */ |
| 509 | switch(flags & O_ACCMODE) |
| 510 | { |
| 511 | /* read-only: do not allow O_APPEND */ |
| 512 | case O_RDONLY: |
| 513 | archive_flags |= FS_OPEN_READ; |
| 514 | if(flags & O_APPEND) |
| 515 | { |
| 516 | r->_errno = EINVAL; |
| 517 | return -1; |
| 518 | } |
| 519 | break; |
| 520 | |
| 521 | /* write-only */ |
| 522 | case O_WRONLY: |
| 523 | archive_flags |= FS_OPEN_WRITE; |
| 524 | break; |
| 525 | |
| 526 | /* read and write */ |
| 527 | case O_RDWR: |
| 528 | archive_flags |= (FS_OPEN_READ | FS_OPEN_WRITE); |
| 529 | break; |
| 530 | |
| 531 | /* an invalid option was supplied */ |
| 532 | default: |
| 533 | r->_errno = EINVAL; |
| 534 | return -1; |
| 535 | } |
| 536 | |
| 537 | /* ExtData is weird and there's no good way to support writing to it through standard interfaces */ |
| 538 | if (device->is_extdata && ((flags & O_ACCMODE) != O_RDONLY || (flags & O_CREAT))) |
| 539 | { |
| 540 | r->_errno = ENOTSUP; |
| 541 | return -1; |
| 542 | } |
| 543 | |
| 544 | /* create file */ |
nothing calls this directly
no test coverage detected