1 /* 2 * Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <fs_query.h> 8 9 #include <stdlib.h> 10 #include <string.h> 11 #include <fcntl.h> 12 #include <errno.h> 13 14 #include "syscalls.h" 15 16 17 // for the DIR structure 18 #define BUFFER_SIZE 2048 19 20 21 static DIR * 22 open_query_etc(dev_t device, const char *query, 23 uint32 flags, port_id port, int32 token) 24 { 25 if (device < 0 || query == NULL || query[0] == '\0') { 26 errno = B_BAD_VALUE; 27 return NULL; 28 } 29 30 // open 31 int fd = _kern_open_query(device, query, strlen(query), flags, port, token); 32 if (fd < 0) { 33 errno = fd; 34 return NULL; 35 } 36 37 // allocate a DIR 38 DIR *dir = (DIR *)malloc(BUFFER_SIZE); 39 if (!dir) { 40 _kern_close(fd); 41 errno = B_NO_MEMORY; 42 return NULL; 43 } 44 dir->fd = fd; 45 return dir; 46 } 47 48 49 DIR * 50 fs_open_query(dev_t device, const char *query, uint32 flags) 51 { 52 return open_query_etc(device, query, flags, -1, -1); 53 } 54 55 56 DIR * 57 fs_open_live_query(dev_t device, const char *query, 58 uint32 flags, port_id port, int32 token) 59 { 60 // check parameters 61 if (port < 0) { 62 errno = B_BAD_VALUE; 63 return NULL; 64 } 65 66 return open_query_etc(device, query, flags | B_LIVE_QUERY, port, token); 67 } 68 69 70 int 71 fs_close_query(DIR *dir) 72 { 73 if (dir == NULL) { 74 errno = B_BAD_VALUE; 75 return -1; 76 } 77 78 int fd = dir->fd; 79 free(dir); 80 return _kern_close(fd); 81 } 82 83 84 struct dirent * 85 fs_read_query(DIR *dir) 86 { 87 // check parameters 88 if (dir == NULL) { 89 errno = B_BAD_VALUE; 90 return NULL; 91 } 92 93 // read 94 int32 bufferSize = BUFFER_SIZE - ((uint8 *)&dir->ent - (uint8 *)dir); 95 ssize_t result = _kern_read_dir(dir->fd, &dir->ent, bufferSize, 1); 96 if (result < 0) { 97 errno = result; 98 return NULL; 99 } 100 if (result == 0) { 101 errno = B_ENTRY_NOT_FOUND; 102 return NULL; 103 } 104 return &dir->ent; 105 } 106 107 108 status_t 109 get_path_for_dirent(struct dirent *dent, char *buffer, size_t length) 110 { 111 if (dent == NULL || buffer == NULL) 112 return B_BAD_VALUE; 113 114 return _kern_entry_ref_to_path(dent->d_pdev, dent->d_pino, dent->d_name, 115 buffer, length); 116 } 117 118