Changeset 04803bf in mainline for uspace/lib/c/generic
- 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. - Location:
- uspace/lib/c/generic
- Files:
-
- 32 added
- 38 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/adt/hash_table.c
rb50b5af2 r04803bf 42 42 #include <malloc.h> 43 43 #include <assert.h> 44 #include <stdio.h> 45 #include <string.h> 44 #include <str.h> 46 45 47 46 /** Create chained hash table. 48 47 * 49 * @param h Hash table structure. Will be initialized by this call. 50 * @param m Number of hash table buckets. 51 * @param max_keys Maximal number of keys needed to identify an item. 52 * @param op Hash table operations structure. 53 * @return True on success 48 * @param h Hash table structure. Will be initialized by this call. 49 * @param m Number of hash table buckets. 50 * @param max_keys Maximal number of keys needed to identify an item. 51 * @param op Hash table operations structure. 52 * 53 * @return True on success 54 * 54 55 */ 55 56 int hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys, 56 57 hash_table_operations_t *op) 57 58 { 58 hash_count_t i;59 60 59 assert(h); 61 60 assert(op && op->hash && op->compare); … … 63 62 64 63 h->entry = malloc(m * sizeof(link_t)); 65 if (!h->entry) { 66 printf("cannot allocate memory for hash table\n"); 64 if (!h->entry) 67 65 return false; 68 }66 69 67 memset((void *) h->entry, 0, m * sizeof(link_t)); 70 68 69 hash_count_t i; 71 70 for (i = 0; i < m; i++) 72 71 list_initialize(&h->entry[i]); … … 75 74 h->max_keys = max_keys; 76 75 h->op = op; 76 77 77 return true; 78 78 } … … 80 80 /** Destroy a hash table instance. 81 81 * 82 * @param h Hash table to be destroyed. 82 * @param h Hash table to be destroyed. 83 * 83 84 */ 84 85 void hash_table_destroy(hash_table_t *h) … … 86 87 assert(h); 87 88 assert(h->entry); 89 88 90 free(h->entry); 89 91 } … … 91 93 /** Insert item into a hash table. 92 94 * 93 * @param h 94 * @param key 95 * @param item 95 * @param h Hash table. 96 * @param key Array of all keys necessary to compute hash index. 97 * @param item Item to be inserted into the hash table. 96 98 */ 97 99 void hash_table_insert(hash_table_t *h, unsigned long key[], link_t *item) 98 100 { 99 hash_index_t chain;100 101 101 assert(item); 102 102 assert(h && h->op && h->op->hash && h->op->compare); 103 104 chain = h->op->hash(key);103 104 hash_index_t chain = h->op->hash(key); 105 105 assert(chain < h->entries); 106 106 … … 110 110 /** Search hash table for an item matching keys. 111 111 * 112 * @param h Hash table. 113 * @param key Array of all keys needed to compute hash index. 114 * 115 * @return Matching item on success, NULL if there is no such item. 112 * @param h Hash table. 113 * @param key Array of all keys needed to compute hash index. 114 * 115 * @return Matching item on success, NULL if there is no such item. 116 * 116 117 */ 117 118 link_t *hash_table_find(hash_table_t *h, unsigned long key[]) 118 119 { 120 assert(h && h->op && h->op->hash && h->op->compare); 121 122 hash_index_t chain = h->op->hash(key); 123 assert(chain < h->entries); 124 119 125 link_t *cur; 120 hash_index_t chain;121 122 assert(h && h->op && h->op->hash && h->op->compare);123 124 chain = h->op->hash(key);125 assert(chain < h->entries);126 127 126 for (cur = h->entry[chain].next; cur != &h->entry[chain]; 128 127 cur = cur->next) { … … 142 141 * For each removed item, h->remove_callback() is called. 143 142 * 144 * @param h Hash table. 145 * @param key Array of keys that will be compared against items of 146 * the hash table. 147 * @param keys Number of keys in the 'key' array. 143 * @param h Hash table. 144 * @param key Array of keys that will be compared against items of 145 * the hash table. 146 * @param keys Number of keys in the 'key' array. 147 * 148 148 */ 149 149 void hash_table_remove(hash_table_t *h, unsigned long key[], hash_count_t keys) 150 150 { 151 hash_index_t chain;152 link_t *cur;153 154 151 assert(h && h->op && h->op->hash && h->op->compare && 155 152 h->op->remove_callback); 156 153 assert(keys <= h->max_keys); 157 154 155 link_t *cur; 156 158 157 if (keys == h->max_keys) { 159 160 158 /* 161 159 * All keys are known, hash_table_find() can be used to find the 162 160 * entry. 163 161 */ 164 162 165 163 cur = hash_table_find(h, key); 166 164 if (cur) { … … 168 166 h->op->remove_callback(cur); 169 167 } 168 170 169 return; 171 170 } … … 175 174 * Any partially matching entries are to be removed. 176 175 */ 176 hash_index_t chain; 177 177 for (chain = 0; chain < h->entries; chain++) { 178 178 for (cur = h->entry[chain].next; cur != &h->entry[chain]; … … 193 193 } 194 194 195 /** Apply fucntion to all items in hash table. 196 * 197 * @param h Hash table. 198 * @param f Function to be applied. 199 * @param arg Argument to be passed to the function. 200 * 201 */ 202 void hash_table_apply(hash_table_t *h, void (*f)(link_t *, void *), void *arg) 203 { 204 hash_index_t bucket; 205 link_t *cur; 206 207 for (bucket = 0; bucket < h->entries; bucket++) { 208 for (cur = h->entry[bucket].next; cur != &h->entry[bucket]; 209 cur = cur->next) { 210 f(cur, arg); 211 } 212 } 213 } 214 195 215 /** @} 196 216 */ -
uspace/lib/c/generic/as.c
rb50b5af2 r04803bf 40 40 #include <bitops.h> 41 41 #include <malloc.h> 42 43 /** Last position allocated by as_get_mappable_page */ 44 static uintptr_t last_allocated = 0; 42 #include "private/libc.h" 45 43 46 44 /** Create address space area. … … 103 101 } 104 102 105 /** Return pointer to some unmapped area, where fits new as_area103 /** Return pointer to unmapped address space area 106 104 * 107 105 * @param size Requested size of the allocation. 108 106 * 109 * @return pointer to the beginning107 * @return Pointer to the beginning of unmapped address space area. 110 108 * 111 109 */ 112 110 void *as_get_mappable_page(size_t size) 113 111 { 114 if (size == 0) 115 return NULL; 116 117 size_t sz = 1 << (fnzb(size - 1) + 1); 118 if (last_allocated == 0) 119 last_allocated = get_max_heap_addr(); 120 121 /* 122 * Make sure we allocate from naturally aligned address. 123 */ 124 uintptr_t res = ALIGN_UP(last_allocated, sz); 125 last_allocated = res + ALIGN_UP(size, PAGE_SIZE); 126 127 return ((void *) res); 112 return (void *) __SYSCALL2(SYS_AS_GET_UNMAPPED_AREA, 113 (sysarg_t) __entry, (sysarg_t) size); 128 114 } 129 115 -
uspace/lib/c/generic/cap.c
rb50b5af2 r04803bf 31 31 */ 32 32 /** 33 * @file 34 * @brief 33 * @file cap.c 34 * @brief Functions to grant/revoke capabilities to/from a task. 35 35 */ 36 36 … … 38 38 #include <task.h> 39 39 #include <libc.h> 40 #include <kernel/syscall/sysarg64.h>41 40 42 41 /** Grant capabilities to a task. 43 42 * 44 * @param id Destination task ID.43 * @param id Destination task ID. 45 44 * @param caps Capabilities to grant. 46 45 * 47 46 * @return Zero on success or a value from @ref errno.h on failure. 47 * 48 48 */ 49 49 int cap_grant(task_id_t id, unsigned int caps) 50 50 { 51 sysarg64_t arg; 51 #ifdef __32_BITS__ 52 sysarg64_t arg = (sysarg64_t) id; 53 return __SYSCALL2(SYS_CAP_GRANT, (sysarg_t) &arg, (sysarg_t) caps); 54 #endif 52 55 53 arg.value = (unsigned long long) id; 54 55 return __SYSCALL2(SYS_CAP_GRANT, (sysarg_t) &arg, (sysarg_t) caps); 56 #ifdef __64_BITS__ 57 return __SYSCALL2(SYS_CAP_GRANT, (sysarg_t) id, (sysarg_t) caps); 58 #endif 56 59 } 57 60 58 61 /** Revoke capabilities from a task. 59 62 * 60 * @param id Destination task ID.63 * @param id Destination task ID. 61 64 * @param caps Capabilities to revoke. 62 65 * 63 66 * @return Zero on success or a value from @ref errno.h on failure. 67 * 64 68 */ 65 69 int cap_revoke(task_id_t id, unsigned int caps) 66 70 { 67 sysarg64_t arg; 71 #ifdef __32_BITS__ 72 sysarg64_t arg = (sysarg64_t) id; 73 return __SYSCALL2(SYS_CAP_REVOKE, (sysarg_t) &arg, (sysarg_t) caps); 74 #endif 68 75 69 arg.value = (unsigned long long) id; 70 71 return __SYSCALL2(SYS_CAP_REVOKE, (sysarg_t) &arg, (sysarg_t) caps); 76 #ifdef __64_BITS__ 77 return __SYSCALL2(SYS_CAP_REVOKE, (sysarg_t) id, (sysarg_t) caps); 78 #endif 72 79 } 73 80 -
uspace/lib/c/generic/ddi.c
rb50b5af2 r04803bf 96 96 } 97 97 98 /** Interrupt control99 *100 * @param enable 1 - enable interrupts, 0 - disable interrupts101 */102 int preemption_control(int enable)103 {104 return __SYSCALL1(SYS_PREEMPT_CONTROL, (sysarg_t) enable);105 }106 107 98 /** Enable PIO for specified I/O range. 108 99 * … … 136 127 } 137 128 129 /** Register IRQ notification. 130 * 131 * @param inr IRQ number. 132 * @param devno Device number of the device generating inr. 133 * @param method Use this method for notifying me. 134 * @param ucode Top-half pseudocode handler. 135 * 136 * @return Value returned by the kernel. 137 * 138 */ 139 int register_irq(int inr, int devno, int method, irq_code_t *ucode) 140 { 141 return __SYSCALL4(SYS_REGISTER_IRQ, inr, devno, method, 142 (sysarg_t) ucode); 143 } 144 145 /** Unregister IRQ notification. 146 * 147 * @param inr IRQ number. 148 * @param devno Device number of the device generating inr. 149 * 150 * @return Value returned by the kernel. 151 * 152 */ 153 int unregister_irq(int inr, int devno) 154 { 155 return __SYSCALL2(SYS_UNREGISTER_IRQ, inr, devno); 156 } 157 138 158 /** @} 139 159 */ -
uspace/lib/c/generic/event.c
rb50b5af2 r04803bf 35 35 */ 36 36 /** @file 37 */ 37 */ 38 38 39 39 #include <libc.h> 40 40 #include <event.h> 41 41 #include <kernel/ipc/event_types.h> 42 #include <ipc/ipc.h>43 42 44 43 /** Subscribe for event notifications. … … 49 48 * @return Value returned by the kernel. 50 49 */ 51 int event_subscribe(event_type_t e, ipcarg_t method)50 int event_subscribe(event_type_t e, sysarg_t method) 52 51 { 53 52 return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) e, (sysarg_t) method); -
uspace/lib/c/generic/fibril.c
rb50b5af2 r04803bf 41 41 #include <unistd.h> 42 42 #include <stdio.h> 43 #include <arch/barrier.h> 43 44 #include <libarch/faddr.h> 44 45 #include <futex.h> … … 47 48 48 49 #ifndef FIBRIL_INITIAL_STACK_PAGES_NO 49 #define FIBRIL_INITIAL_STACK_PAGES_NO150 #define FIBRIL_INITIAL_STACK_PAGES_NO 1 50 51 #endif 51 52 52 53 /** 53 * This futex serializes access to ready_list, serialized_list and manager_list. 54 */ 54 * This futex serializes access to ready_list, 55 * serialized_list and manager_list. 56 */ 55 57 static atomic_t fibril_futex = FUTEX_INITIALIZER; 56 58 … … 59 61 static LIST_INITIALIZE(manager_list); 60 62 61 static void fibril_main(void);62 63 63 /** Number of threads that are executing a manager fibril. */ 64 64 static int threads_in_manager; 65 /** Number of threads that are executing a manager fibril and are serialized. */ 66 static int serialized_threads; /* Protected by async_futex */ 65 66 /** 67 * Number of threads that are executing a manager fibril 68 * and are serialized. Protected by async_futex. 69 */ 70 static int serialized_threads; 71 67 72 /** Fibril-local count of serialization. If > 0, we must not preempt */ 68 73 static fibril_local int serialization_count; 69 70 /** Setup fibril information into TCB structure */71 fibril_t *fibril_setup(void)72 {73 fibril_t *f;74 tcb_t *tcb;75 76 tcb = __make_tls();77 if (!tcb)78 return NULL;79 80 f = malloc(sizeof(fibril_t));81 if (!f) {82 __free_tls(tcb);83 return NULL;84 }85 86 tcb->fibril_data = f;87 f->tcb = tcb;88 89 f->func = NULL;90 f->arg = NULL;91 f->stack = NULL;92 f->clean_after_me = NULL;93 f->retval = 0;94 f->flags = 0;95 96 return f;97 }98 99 void fibril_teardown(fibril_t *f)100 {101 __free_tls(f->tcb);102 free(f);103 }104 74 105 75 /** Function that spans the whole life-cycle of a fibril. … … 108 78 * the fibril logic is called. After its return, the return value is saved. 109 79 * The fibril then switches to another fibril, which cleans up after it. 110 */ 111 void fibril_main(void) 112 { 113 fibril_t *f = __tcb_get()->fibril_data; 114 80 * 81 */ 82 static void fibril_main(void) 83 { 84 fibril_t *fibril = __tcb_get()->fibril_data; 85 115 86 /* Call the implementing function. */ 116 f ->retval = f->func(f->arg);117 87 fibril->retval = fibril->func(fibril->arg); 88 118 89 fibril_switch(FIBRIL_FROM_DEAD); 119 /* not reached */ 90 /* Not reached */ 91 } 92 93 /** Setup fibril information into TCB structure 94 * 95 */ 96 fibril_t *fibril_setup(void) 97 { 98 tcb_t *tcb = __make_tls(); 99 if (!tcb) 100 return NULL; 101 102 fibril_t *fibril = malloc(sizeof(fibril_t)); 103 if (!fibril) { 104 __free_tls(tcb); 105 return NULL; 106 } 107 108 tcb->fibril_data = fibril; 109 fibril->tcb = tcb; 110 111 fibril->func = NULL; 112 fibril->arg = NULL; 113 fibril->stack = NULL; 114 fibril->clean_after_me = NULL; 115 fibril->retval = 0; 116 fibril->flags = 0; 117 118 fibril->waits_for = NULL; 119 120 return fibril; 121 } 122 123 void fibril_teardown(fibril_t *fibril) 124 { 125 __free_tls(fibril->tcb); 126 free(fibril); 120 127 } 121 128 … … 125 132 * held. 126 133 * 127 * @param stype Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER, 128 * FIBRIL_FROM_MANAGER, FIBRIL_FROM_DEAD. The parameter 129 * describes the circumstances of the switch. 130 * @return Return 0 if there is no ready fibril, 131 * return 1 otherwise. 134 * @param stype Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER, 135 * FIBRIL_FROM_MANAGER, FIBRIL_FROM_DEAD. The parameter 136 * describes the circumstances of the switch. 137 * 138 * @return 0 if there is no ready fibril, 139 * @return 1 otherwise. 140 * 132 141 */ 133 142 int fibril_switch(fibril_switch_type_t stype) 134 143 { 135 fibril_t *srcf, *dstf;136 144 int retval = 0; 137 145 138 146 futex_down(&fibril_futex); 139 147 140 148 if (stype == FIBRIL_PREEMPT && list_empty(&ready_list)) 141 149 goto ret_0; 142 150 143 151 if (stype == FIBRIL_FROM_MANAGER) { 144 if ( list_empty(&ready_list) && list_empty(&serialized_list))152 if ((list_empty(&ready_list)) && (list_empty(&serialized_list))) 145 153 goto ret_0; 154 146 155 /* 147 156 * Do not preempt if there is not enough threads to run the 148 157 * ready fibrils which are not serialized. 149 158 */ 150 if ( list_empty(&serialized_list) &&151 threads_in_manager <= serialized_threads) {159 if ((list_empty(&serialized_list)) && 160 (threads_in_manager <= serialized_threads)) { 152 161 goto ret_0; 153 162 } 154 163 } 164 155 165 /* If we are going to manager and none exists, create it */ 156 if ( stype == FIBRIL_TO_MANAGER || stype == FIBRIL_FROM_DEAD) {166 if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) { 157 167 while (list_empty(&manager_list)) { 158 168 futex_up(&fibril_futex); … … 162 172 } 163 173 164 srcf = __tcb_get()->fibril_data;174 fibril_t *srcf = __tcb_get()->fibril_data; 165 175 if (stype != FIBRIL_FROM_DEAD) { 176 166 177 /* Save current state */ 167 178 if (!context_save(&srcf->ctx)) { 168 179 if (serialization_count) 169 180 srcf->flags &= ~FIBRIL_SERIALIZED; 181 170 182 if (srcf->clean_after_me) { 171 183 /* … … 173 185 * restored context here. 174 186 */ 175 void *stack = srcf->clean_after_me->stack; 187 void *stack = srcf->clean_after_me->stack; 176 188 if (stack) { 177 189 /* … … 188 200 srcf->clean_after_me = NULL; 189 201 } 202 190 203 return 1; /* futex_up already done here */ 191 204 } 192 205 193 206 /* Save myself to the correct run list */ 194 207 if (stype == FIBRIL_PREEMPT) … … 197 210 list_append(&srcf->link, &manager_list); 198 211 threads_in_manager--; 199 } else { 212 } else { 200 213 /* 201 214 * If stype == FIBRIL_TO_MANAGER, don't put ourselves to … … 207 220 208 221 /* Choose a new fibril to run */ 209 if (stype == FIBRIL_TO_MANAGER || stype == FIBRIL_FROM_DEAD) { 222 fibril_t *dstf; 223 if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) { 210 224 dstf = list_get_instance(manager_list.next, fibril_t, link); 211 225 if (serialization_count && stype == FIBRIL_TO_MANAGER) { … … 214 228 } 215 229 threads_in_manager++; 216 230 217 231 if (stype == FIBRIL_FROM_DEAD) 218 232 dstf->clean_after_me = srcf; … … 228 242 } 229 243 list_remove(&dstf->link); 230 244 231 245 futex_up(&fibril_futex); 232 246 context_restore(&dstf->ctx); 233 247 /* not reached */ 234 248 235 249 ret_0: 236 250 futex_up(&fibril_futex); … … 240 254 /** Create a new fibril. 241 255 * 242 * @param func Implementing function of the new fibril. 243 * @param arg Argument to pass to func. 244 * 245 * @return Return 0 on failure or TLS of the new fibril. 256 * @param func Implementing function of the new fibril. 257 * @param arg Argument to pass to func. 258 * 259 * @return 0 on failure or TLS of the new fibril. 260 * 246 261 */ 247 262 fid_t fibril_create(int (*func)(void *), void *arg) 248 263 { 249 fibril_t *f ;250 251 f = fibril_setup();252 if ( !f)264 fibril_t *fibril; 265 266 fibril = fibril_setup(); 267 if (fibril == NULL) 253 268 return 0; 254 f->stack = (char *) malloc(FIBRIL_INITIAL_STACK_PAGES_NO * 255 getpagesize()); 256 if (!f->stack) { 257 fibril_teardown(f); 269 270 fibril->stack = 271 (char *) malloc(FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize()); 272 if (!fibril->stack) { 273 fibril_teardown(fibril); 258 274 return 0; 259 275 } 260 276 261 f ->func = func;262 f ->arg = arg;263 264 context_save(&f ->ctx);265 context_set(&f ->ctx, FADDR(fibril_main), f->stack,266 FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize(), f ->tcb);267 268 return (fid_t) f ;277 fibril->func = func; 278 fibril->arg = arg; 279 280 context_save(&fibril->ctx); 281 context_set(&fibril->ctx, FADDR(fibril_main), fibril->stack, 282 FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize(), fibril->tcb); 283 284 return (fid_t) fibril; 269 285 } 270 286 271 287 /** Add a fibril to the ready list. 272 288 * 273 * @param fid Pointer to the fibril structure of the fibril to be 274 * added. 289 * @param fid Pointer to the fibril structure of the fibril to be 290 * added. 291 * 275 292 */ 276 293 void fibril_add_ready(fid_t fid) 277 294 { 278 fibril_t *f; 279 280 f = (fibril_t *) fid; 295 fibril_t *fibril = (fibril_t *) fid; 296 281 297 futex_down(&fibril_futex); 282 if ((f->flags & FIBRIL_SERIALIZED)) 283 list_append(&f->link, &serialized_list); 298 299 if ((fibril->flags & FIBRIL_SERIALIZED)) 300 list_append(&fibril->link, &serialized_list); 284 301 else 285 list_append(&f->link, &ready_list); 302 list_append(&fibril->link, &ready_list); 303 286 304 futex_up(&fibril_futex); 287 305 } … … 289 307 /** Add a fibril to the manager list. 290 308 * 291 * @param fid Pointer to the fibril structure of the fibril to be 292 * added. 309 * @param fid Pointer to the fibril structure of the fibril to be 310 * added. 311 * 293 312 */ 294 313 void fibril_add_manager(fid_t fid) 295 314 { 296 fibril_t *f; 297 298 f = (fibril_t *) fid; 299 315 fibril_t *fibril = (fibril_t *) fid; 316 300 317 futex_down(&fibril_futex); 301 list_append(&f ->link, &manager_list);318 list_append(&fibril->link, &manager_list); 302 319 futex_up(&fibril_futex); 303 320 } … … 307 324 { 308 325 futex_down(&fibril_futex); 309 if (list_empty(&manager_list)) { 310 futex_up(&fibril_futex); 311 return; 312 } 313 list_remove(manager_list.next); 326 327 if (!list_empty(&manager_list)) 328 list_remove(manager_list.next); 329 314 330 futex_up(&fibril_futex); 315 331 } … … 345 361 } 346 362 363 int fibril_get_sercount(void) 364 { 365 return serialization_count; 366 } 367 347 368 /** @} 348 369 */ -
uspace/lib/c/generic/getopt.c
rb50b5af2 r04803bf 38 38 #include <getopt.h> 39 39 #include <stdlib.h> 40 #include <str ing.h>40 #include <str.h> 41 41 42 42 /* HelenOS Port : We're incorporating only the modern getopt_long with wrappers -
uspace/lib/c/generic/io/asprintf.c
rb50b5af2 r04803bf 37 37 #include <stdio.h> 38 38 #include <stdlib.h> 39 #include <str ing.h>39 #include <str.h> 40 40 #include <io/printf_core.h> 41 41 … … 61 61 int asprintf(char **strp, const char *fmt, ...) 62 62 { 63 struct printf_specps = {63 printf_spec_t ps = { 64 64 asprintf_str_write, 65 65 asprintf_wstr_write, -
uspace/lib/c/generic/io/console.c
rb50b5af2 r04803bf 45 45 } 46 46 47 int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols)47 int console_get_size(int phone, sysarg_t *cols, sysarg_t *rows) 48 48 { 49 return async_req_0_2(phone, CONSOLE_GET_SIZE, rows, cols);49 return async_req_0_2(phone, CONSOLE_GET_SIZE, cols, rows); 50 50 } 51 51 52 void console_set_style(int phone, int style)52 void console_set_style(int phone, uint8_t style) 53 53 { 54 54 async_msg_1(phone, CONSOLE_SET_STYLE, style); 55 55 } 56 56 57 void console_set_color(int phone, int fg_color, int bg_color, int flags) 57 void console_set_color(int phone, uint8_t fg_color, uint8_t bg_color, 58 uint8_t flags) 58 59 { 59 60 async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags); 60 61 } 61 62 62 void console_set_rgb_color(int phone, int fg_color, int bg_color)63 void console_set_rgb_color(int phone, uint32_t fg_color, uint32_t bg_color) 63 64 { 64 65 async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color); … … 67 68 void console_cursor_visibility(int phone, bool show) 68 69 { 69 async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, show != false);70 async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, (show != false)); 70 71 } 71 72 72 int console_get_color_cap(int phone, int *ccap)73 int console_get_color_cap(int phone, sysarg_t *ccap) 73 74 { 74 ipcarg_t ccap_tmp; 75 int rc; 76 77 rc = async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, &ccap_tmp); 78 *ccap = ccap_tmp; 79 80 return rc; 75 return async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, ccap); 81 76 } 82 77 … … 86 81 } 87 82 88 void console_goto(int phone, ipcarg_t row, ipcarg_t col)83 int console_get_pos(int phone, sysarg_t *col, sysarg_t *row) 89 84 { 90 async_msg_2(phone, CONSOLE_GOTO, row, col); 85 return async_req_0_2(phone, CONSOLE_GET_POS, col, row); 86 } 87 88 void console_set_pos(int phone, sysarg_t col, sysarg_t row) 89 { 90 async_msg_2(phone, CONSOLE_GOTO, col, row); 91 91 } 92 92 93 93 bool console_get_event(int phone, console_event_t *event) 94 94 { 95 ipcarg_t type;96 ipcarg_t key;97 ipcarg_t mods;98 ipcarg_t c;95 sysarg_t type; 96 sysarg_t key; 97 sysarg_t mods; 98 sysarg_t c; 99 99 100 100 int rc = async_req_0_4(phone, CONSOLE_GET_EVENT, &type, &key, &mods, &c); -
uspace/lib/c/generic/io/io.c
rb50b5af2 r04803bf 37 37 #include <fcntl.h> 38 38 #include <assert.h> 39 #include <str ing.h>39 #include <str.h> 40 40 #include <errno.h> 41 41 #include <bool.h> 42 42 #include <malloc.h> 43 #include <async.h> 43 44 #include <io/klog.h> 44 45 #include <vfs/vfs.h> 45 46 #include <ipc/devmap.h> 46 47 #include <adt/list.h> 47 48 #include "../private/io.h" 49 50 static void _ffillbuf(FILE *stream); 48 51 static void _fflushbuf(FILE *stream); 49 52 … … 57 60 .buf = NULL, 58 61 .buf_size = 0, 59 .buf_head = NULL 62 .buf_head = NULL, 63 .buf_tail = NULL, 64 .buf_state = _bs_empty 60 65 }; 61 66 … … 69 74 .buf = NULL, 70 75 .buf_size = BUFSIZ, 71 .buf_head = NULL 76 .buf_head = NULL, 77 .buf_tail = NULL, 78 .buf_state = _bs_empty 72 79 }; 73 80 … … 81 88 .buf = NULL, 82 89 .buf_size = 0, 83 .buf_head = NULL 90 .buf_head = NULL, 91 .buf_tail = NULL, 92 .buf_state = _bs_empty 84 93 }; 85 94 … … 179 188 stream->buf_size = size; 180 189 stream->buf_head = stream->buf; 190 stream->buf_tail = stream->buf; 191 stream->buf_state = _bs_empty; 181 192 } 182 193 … … 210 221 211 222 stream->buf_head = stream->buf; 223 stream->buf_tail = stream->buf; 212 224 return 0; 213 225 } … … 243 255 stream->klog = false; 244 256 stream->phone = -1; 257 stream->need_sync = false; 245 258 _setvbuf(stream); 246 259 … … 264 277 stream->klog = false; 265 278 stream->phone = -1; 279 stream->need_sync = false; 266 280 _setvbuf(stream); 267 281 … … 295 309 stream->klog = false; 296 310 stream->phone = -1; 311 stream->need_sync = false; 297 312 _setvbuf(stream); 298 313 … … 309 324 310 325 if (stream->phone >= 0) 311 ipc_hangup(stream->phone);326 async_hangup(stream->phone); 312 327 313 328 if (stream->fd >= 0) … … 331 346 } 332 347 333 /** Read from a stream .348 /** Read from a stream (unbuffered). 334 349 * 335 350 * @param buf Destination buffer. … … 337 352 * @param nmemb Number of records to read. 338 353 * @param stream Pointer to the stream. 339 * 340 */ 341 size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream) 342 { 343 size_t left = size * nmemb; 344 size_t done = 0; 345 346 /* Make sure no data is pending write. */ 347 _fflushbuf(stream); 354 */ 355 static size_t _fread(void *buf, size_t size, size_t nmemb, FILE *stream) 356 { 357 size_t left, done; 358 359 if (size == 0 || nmemb == 0) 360 return 0; 361 362 left = size * nmemb; 363 done = 0; 348 364 349 365 while ((left > 0) && (!stream->error) && (!stream->eof)) { … … 363 379 } 364 380 381 /** Write to a stream (unbuffered). 382 * 383 * @param buf Source buffer. 384 * @param size Size of each record. 385 * @param nmemb Number of records to write. 386 * @param stream Pointer to the stream. 387 */ 365 388 static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream) 366 389 { 367 size_t left = size * nmemb; 368 size_t done = 0; 369 390 size_t left; 391 size_t done; 392 393 if (size == 0 || nmemb == 0) 394 return 0; 395 396 left = size * nmemb; 397 done = 0; 398 370 399 while ((left > 0) && (!stream->error)) { 371 400 ssize_t wr; … … 383 412 } 384 413 } 414 415 if (done > 0) 416 stream->need_sync = true; 385 417 386 418 return (done / size); 387 419 } 388 420 389 /** Drain stream buffer, do not sync stream. */ 421 /** Read some data in stream buffer. */ 422 static void _ffillbuf(FILE *stream) 423 { 424 ssize_t rc; 425 426 stream->buf_head = stream->buf_tail = stream->buf; 427 428 rc = read(stream->fd, stream->buf, stream->buf_size); 429 if (rc < 0) { 430 stream->error = true; 431 return; 432 } 433 434 if (rc == 0) { 435 stream->eof = true; 436 return; 437 } 438 439 stream->buf_head += rc; 440 stream->buf_state = _bs_read; 441 } 442 443 /** Write out stream buffer, do not sync stream. */ 390 444 static void _fflushbuf(FILE *stream) 391 445 { 392 446 size_t bytes_used; 393 447 394 448 if ((!stream->buf) || (stream->btype == _IONBF) || (stream->error)) 395 449 return; 396 397 bytes_used = stream->buf_head - stream->buf ;450 451 bytes_used = stream->buf_head - stream->buf_tail; 398 452 if (bytes_used == 0) 399 453 return; 400 401 (void) _fwrite(stream->buf, 1, bytes_used, stream); 454 455 /* If buffer has prefetched read data, we need to seek back. */ 456 if (stream->buf_state == _bs_read) 457 lseek(stream->fd, - (ssize_t) bytes_used, SEEK_CUR); 458 459 /* If buffer has unwritten data, we need to write them out. */ 460 if (stream->buf_state == _bs_write) 461 (void) _fwrite(stream->buf_tail, 1, bytes_used, stream); 462 402 463 stream->buf_head = stream->buf; 403 } 464 stream->buf_tail = stream->buf; 465 stream->buf_state = _bs_empty; 466 } 467 468 /** Read from a stream. 469 * 470 * @param dest Destination buffer. 471 * @param size Size of each record. 472 * @param nmemb Number of records to read. 473 * @param stream Pointer to the stream. 474 * 475 */ 476 size_t fread(void *dest, size_t size, size_t nmemb, FILE *stream) 477 { 478 uint8_t *dp; 479 size_t bytes_left; 480 size_t now; 481 size_t data_avail; 482 size_t total_read; 483 size_t i; 484 485 if (size == 0 || nmemb == 0) 486 return 0; 487 488 /* If not buffered stream, read in directly. */ 489 if (stream->btype == _IONBF) { 490 now = _fread(dest, size, nmemb, stream); 491 return now; 492 } 493 494 /* Make sure no data is pending write. */ 495 if (stream->buf_state == _bs_write) 496 _fflushbuf(stream); 497 498 /* Perform lazy allocation of stream buffer. */ 499 if (stream->buf == NULL) { 500 if (_fallocbuf(stream) != 0) 501 return 0; /* Errno set by _fallocbuf(). */ 502 } 503 504 bytes_left = size * nmemb; 505 total_read = 0; 506 dp = (uint8_t *) dest; 507 508 while ((!stream->error) && (!stream->eof) && (bytes_left > 0)) { 509 if (stream->buf_head == stream->buf_tail) 510 _ffillbuf(stream); 511 512 if (stream->error || stream->eof) 513 break; 514 515 data_avail = stream->buf_head - stream->buf_tail; 516 517 if (bytes_left > data_avail) 518 now = data_avail; 519 else 520 now = bytes_left; 521 522 for (i = 0; i < now; i++) { 523 dp[i] = stream->buf_tail[i]; 524 } 525 526 dp += now; 527 stream->buf_tail += now; 528 bytes_left -= now; 529 total_read += now; 530 } 531 532 return (total_read / size); 533 } 534 404 535 405 536 /** Write to a stream. … … 421 552 uint8_t b; 422 553 bool need_flush; 423 554 555 if (size == 0 || nmemb == 0) 556 return 0; 557 424 558 /* If not buffered stream, write out directly. */ 425 559 if (stream->btype == _IONBF) { … … 428 562 return now; 429 563 } 430 564 565 /* Make sure buffer contains no prefetched data. */ 566 if (stream->buf_state == _bs_read) 567 _fflushbuf(stream); 568 569 431 570 /* Perform lazy allocation of stream buffer. */ 432 571 if (stream->buf == NULL) { … … 468 607 } 469 608 609 if (total_written > 0) 610 stream->buf_state = _bs_write; 611 470 612 if (need_flush) 471 613 fflush(stream); … … 480 622 481 623 if (chr_encode(c, buf, &sz, STR_BOUNDS(1)) == EOK) { 482 size_t wr = fwrite(buf, sz, 1, stream);624 size_t wr = fwrite(buf, 1, sz, stream); 483 625 484 626 if (wr < sz) … … 522 664 } 523 665 666 char *fgets(char *str, int size, FILE *stream) 667 { 668 int c; 669 int idx; 670 671 idx = 0; 672 while (idx < size - 1) { 673 c = fgetc(stream); 674 if (c == EOF) 675 break; 676 677 str[idx++] = c; 678 679 if (c == '\n') 680 break; 681 } 682 683 if (ferror(stream)) 684 return NULL; 685 686 if (idx == 0) 687 return NULL; 688 689 str[idx] = '\0'; 690 return str; 691 } 692 524 693 int getchar(void) 525 694 { … … 527 696 } 528 697 529 int fseek(FILE *stream, long offset, int origin) 530 { 531 off_t rc = lseek(stream->fd, offset, origin); 532 if (rc == (off_t) (-1)) { 533 /* errno has been set by lseek. */ 698 int fseek(FILE *stream, off64_t offset, int whence) 699 { 700 off64_t rc; 701 702 _fflushbuf(stream); 703 704 rc = lseek(stream->fd, offset, whence); 705 if (rc == (off64_t) (-1)) { 706 /* errno has been set by lseek64. */ 534 707 return -1; 535 708 } 536 709 537 710 stream->eof = false; 538 539 711 return 0; 712 } 713 714 off64_t ftell(FILE *stream) 715 { 716 return lseek(stream->fd, 0, SEEK_CUR); 540 717 } 541 718 … … 554 731 } 555 732 556 if (stream->fd >= 0) 733 if (stream->fd >= 0 && stream->need_sync) { 734 /** 735 * Better than syncing always, but probably still not the 736 * right thing to do. 737 */ 738 stream->need_sync = false; 557 739 return fsync(stream->fd); 740 } 558 741 559 742 return ENOENT; … … 568 751 { 569 752 return stream->error; 753 } 754 755 void clearerr(FILE *stream) 756 { 757 stream->eof = false; 758 stream->error = false; 759 } 760 761 int fileno(FILE *stream) 762 { 763 if (stream->klog) { 764 errno = EBADF; 765 return -1; 766 } 767 768 return stream->fd; 570 769 } 571 770 -
uspace/lib/c/generic/io/klog.c
rb50b5af2 r04803bf 35 35 36 36 #include <libc.h> 37 #include <str ing.h>37 #include <str.h> 38 38 #include <sys/types.h> 39 39 #include <unistd.h> … … 42 42 size_t klog_write(const void *buf, size_t size) 43 43 { 44 return (size_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size); 44 ssize_t ret = (ssize_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size); 45 46 if (ret >= 0) 47 return (size_t) ret; 48 49 return 0; 45 50 } 46 51 47 52 void klog_update(void) 48 53 { 49 (void) __SYSCALL3(SYS_KLOG, 1, NULL, 0);54 (void) __SYSCALL3(SYS_KLOG, 1, (uintptr_t) NULL, 0); 50 55 } 51 56 -
uspace/lib/c/generic/io/printf_core.c
rb50b5af2 r04803bf 41 41 #include <io/printf_core.h> 42 42 #include <ctype.h> 43 #include <str ing.h>43 #include <str.h> 44 44 45 45 /** show prefixes 0x or 0 */ 46 46 #define __PRINTF_FLAG_PREFIX 0x00000001 47 47 48 /** signed / unsigned number */ 48 49 #define __PRINTF_FLAG_SIGNED 0x00000002 50 49 51 /** print leading zeroes */ 50 52 #define __PRINTF_FLAG_ZEROPADDED 0x00000004 53 51 54 /** align to left */ 52 55 #define __PRINTF_FLAG_LEFTALIGNED 0x00000010 56 53 57 /** always show + sign */ 54 58 #define __PRINTF_FLAG_SHOWPLUS 0x00000020 59 55 60 /** print space instead of plus */ 56 61 #define __PRINTF_FLAG_SPACESIGN 0x00000040 62 57 63 /** show big characters */ 58 64 #define __PRINTF_FLAG_BIGCHARS 0x00000080 65 59 66 /** number has - sign */ 60 67 #define __PRINTF_FLAG_NEGATIVE 0x00000100 … … 75 82 PrintfQualifierLong, 76 83 PrintfQualifierLongLong, 77 PrintfQualifierPointer 84 PrintfQualifierPointer, 85 PrintfQualifierSize 78 86 } qualifier_t; 79 87 80 static c har nullstr[]= "(NULL)";81 static c har digits_small[]= "0123456789abcdef";82 static c har digits_big[]= "0123456789ABCDEF";83 static c har invalch = U_SPECIAL;88 static const char *nullstr = "(NULL)"; 89 static const char *digits_small = "0123456789abcdef"; 90 static const char *digits_big = "0123456789ABCDEF"; 91 static const char invalch = U_SPECIAL; 84 92 85 93 /** Print one or more characters without adding newline. … … 253 261 if (str == NULL) 254 262 return printf_putstr(nullstr, ps); 255 263 256 264 /* Print leading spaces. */ 257 265 size_t strw = str_length(str); 258 266 if (precision == 0) 259 267 precision = strw; 260 268 261 269 /* Left padding */ 262 270 size_t counter = 0; … … 268 276 } 269 277 } 270 278 271 279 /* Part of @a str fitting into the alloted space. */ 272 280 int retval; … … 350 358 uint32_t flags, printf_spec_t *ps) 351 359 { 352 c har *digits;360 const char *digits; 353 361 if (flags & __PRINTF_FLAG_BIGCHARS) 354 362 digits = digits_big; … … 383 391 */ 384 392 if (flags & __PRINTF_FLAG_PREFIX) { 385 switch (base) {393 switch (base) { 386 394 case 2: 387 395 /* Binary formating is not standard, but usefull */ … … 447 455 /* Print prefix */ 448 456 if (flags & __PRINTF_FLAG_PREFIX) { 449 switch (base) {457 switch (base) { 450 458 case 2: 451 459 /* Binary formating is not standard, but usefull */ … … 545 553 * - "" Signed or unsigned int (default value).@n 546 554 * - "l" Signed or unsigned long int.@n 547 * If conversion is "c", the character is w char_t (wide character).@n555 * If conversion is "c", the character is wint_t (wide character).@n 548 556 * If conversion is "s", the string is wchar_t * (wide string).@n 549 557 * - "ll" Signed or unsigned long long int.@n 558 * - "z" Signed or unsigned ssize_t or site_t.@n 550 559 * 551 560 * CONVERSION:@n … … 562 571 * 563 572 * - P, p Print value of a pointer. Void * value is expected and it is 564 * printed in hexadecimal notation with prefix (as with \%#X / \%#x 565 * for 32-bit or \%#X / \%#x for 64-bit long pointers). 573 * printed in hexadecimal notation with prefix (as with 574 * \%#0.8X / \%#0.8x for 32-bit or \%#0.16lX / \%#0.16lx for 64-bit 575 * long pointers). 566 576 * 567 577 * - b Print value as unsigned binary number. Prefix is not printed by … … 728 738 } 729 739 break; 740 case 'z': 741 qualifier = PrintfQualifierSize; 742 i = nxt; 743 uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 744 break; 730 745 default: 731 746 /* Default type */ … … 755 770 case 'c': 756 771 if (qualifier == PrintfQualifierLong) 757 retval = print_wchar(va_arg(ap, w char_t), width, flags, ps);772 retval = print_wchar(va_arg(ap, wint_t), width, flags, ps); 758 773 else 759 774 retval = print_char(va_arg(ap, unsigned int), width, flags, ps); … … 776 791 case 'p': 777 792 flags |= __PRINTF_FLAG_PREFIX; 793 flags |= __PRINTF_FLAG_ZEROPADDED; 778 794 base = 16; 779 795 qualifier = PrintfQualifierPointer; … … 838 854 case PrintfQualifierPointer: 839 855 size = sizeof(void *); 840 number = (uint64_t) (unsigned long) va_arg(ap, void *); 856 precision = size << 1; 857 number = (uint64_t) (uintptr_t) va_arg(ap, void *); 858 break; 859 case PrintfQualifierSize: 860 size = sizeof(size_t); 861 number = (uint64_t) va_arg(ap, size_t); 841 862 break; 842 863 default: -
uspace/lib/c/generic/io/screenbuffer.c
rb50b5af2 r04803bf 33 33 */ 34 34 35 #include <screenbuffer.h>36 35 #include <io/style.h> 36 #include <io/screenbuffer.h> 37 37 #include <malloc.h> 38 38 #include <unistd.h> … … 67 67 * 68 68 */ 69 screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, size_t size_x, size_t size_y) 69 screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, sysarg_t size_x, 70 sysarg_t size_y) 70 71 { 71 72 scr->buffer = (keyfield_t *) malloc(sizeof(keyfield_t) * size_x * size_y); … … 109 110 * 110 111 */ 111 void screenbuffer_clear_line(screenbuffer_t *scr, s ize_t line)112 void screenbuffer_clear_line(screenbuffer_t *scr, sysarg_t line) 112 113 { 113 s ize_t x;114 sysarg_t x; 114 115 115 116 for (x = 0; x < scr->size_x; x++) { … … 140 141 * 141 142 */ 142 void screenbuffer_goto(screenbuffer_t *scr, s ize_t x, size_t y)143 void screenbuffer_goto(screenbuffer_t *scr, sysarg_t x, sysarg_t y) 143 144 { 144 145 scr->position_x = x % scr->size_x; … … 166 167 * 167 168 */ 168 void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color, uint8_t bg_color, uint8_t flags) 169 void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color, 170 uint8_t bg_color, uint8_t flags) 169 171 { 170 172 scr->attrs.t = at_idx; … … 181 183 * 182 184 */ 183 void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color, uint32_t bg_color) 185 void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color, 186 uint32_t bg_color) 184 187 { 185 188 scr->attrs.t = at_rgb; -
uspace/lib/c/generic/io/vprintf.c
rb50b5af2 r04803bf 37 37 #include <unistd.h> 38 38 #include <io/printf_core.h> 39 #include <f utex.h>39 #include <fibril_synch.h> 40 40 #include <async.h> 41 #include <str ing.h>41 #include <str.h> 42 42 43 static atomic_t printf_futex = FUTEX_INITIALIZER;43 static FIBRIL_MUTEX_INITIALIZE(printf_mutex); 44 44 45 45 static int vprintf_str_write(const char *str, size_t size, void *stream) … … 76 76 int vfprintf(FILE *stream, const char *fmt, va_list ap) 77 77 { 78 struct printf_specps = {78 printf_spec_t ps = { 79 79 vprintf_str_write, 80 80 vprintf_wstr_write, … … 85 85 * Prevent other threads to execute printf_core() 86 86 */ 87 futex_down(&printf_futex); 88 89 /* 90 * Prevent other fibrils of the same thread 91 * to execute printf_core() 92 */ 93 async_serialize_start(); 87 fibril_mutex_lock(&printf_mutex); 94 88 95 89 int ret = printf_core(fmt, &ps, ap); 96 90 97 async_serialize_end(); 98 futex_up(&printf_futex); 91 fibril_mutex_unlock(&printf_mutex); 99 92 100 93 return ret; -
uspace/lib/c/generic/io/vsnprintf.c
rb50b5af2 r04803bf 35 35 #include <stdarg.h> 36 36 #include <stdio.h> 37 #include <str ing.h>37 #include <str.h> 38 38 #include <io/printf_core.h> 39 39 #include <errno.h> -
uspace/lib/c/generic/libc.c
rb50b5af2 r04803bf 42 42 43 43 #include <libc.h> 44 #include <stdio.h> 45 #include <unistd.h> 46 #include <malloc.h> 44 #include <stdlib.h> 47 45 #include <tls.h> 48 #include <thread.h>49 46 #include <fibril.h> 50 #include <ipc/ipc.h> 51 #include <async.h> 52 #include <as.h> 47 #include <task.h> 53 48 #include <loader/pcb.h> 49 #include "private/libc.h" 50 #include "private/async.h" 51 #include "private/async_sess.h" 52 #include "private/malloc.h" 53 #include "private/io.h" 54 54 55 55 /* From librtld. */ 56 56 #include <rtld.h> 57 #include <string.h>57 //#include <string.h> 58 58 59 extern int main(int argc, char *argv[]); 60 61 void _exit(int status) 62 { 63 thread_exit(status); 64 } 59 static bool env_setup = false; 65 60 66 61 void __main(void *pcb_ptr) 67 62 { 68 int retval; 69 70 __heap_init(); 63 /* Initialize user task run-time environment */ 64 __malloc_init(); 71 65 __async_init(); 66 __async_sess_init(); 67 72 68 fibril_t *fibril = fibril_setup(); 69 if (fibril == NULL) 70 abort(); 71 73 72 __tcb_set(fibril->tcb); 74 73 75 74 /* Save the PCB pointer */ 76 75 __pcb = (pcb_t *) pcb_ptr; 76 77 /* The basic run-time environment is setup */ 78 env_setup = true; 77 79 78 80 int argc; … … 84 86 } 85 87 #endif 86 88 /* 89 * Get command line arguments and initialize 90 * standard input and output 91 */ 87 92 if (__pcb == NULL) { 88 93 argc = 0; … … 93 98 argv = __pcb->argv; 94 99 __stdio_init(__pcb->filc, __pcb->filv); 100 (void) chdir(__pcb->cwd); 95 101 } 96 102 97 retval = main(argc, argv); 98 99 __stdio_done(); 100 (void) task_retval(retval); 103 /* 104 * Run main() and set task return value 105 * according the result 106 */ 107 int retval = main(argc, argv); 108 exit(retval); 101 109 } 102 110 103 void __exit(void)111 void exit(int status) 104 112 { 105 fibril_teardown(__tcb_get()->fibril_data); 106 _exit(0); 113 if (env_setup) { 114 __stdio_done(); 115 task_retval(status); 116 fibril_teardown(__tcb_get()->fibril_data); 117 } 118 119 __SYSCALL1(SYS_TASK_EXIT, false); 120 121 /* Unreachable */ 122 while (1); 123 } 124 125 void abort(void) 126 { 127 __SYSCALL1(SYS_TASK_EXIT, true); 128 129 /* Unreachable */ 130 while (1); 107 131 } 108 132 -
uspace/lib/c/generic/loader.c
rb50b5af2 r04803bf 33 33 */ 34 34 35 #include <ipc/ipc.h>36 35 #include <ipc/loader.h> 37 36 #include <ipc/services.h> 37 #include <ipc/ns.h> 38 38 #include <libc.h> 39 39 #include <task.h> 40 #include <str ing.h>40 #include <str.h> 41 41 #include <stdlib.h> 42 42 #include <async.h> … … 63 63 loader_t *loader_connect(void) 64 64 { 65 int phone_id = ipc_connect_me_to_blocking(PHONE_NS,SERVICE_LOAD, 0, 0);65 int phone_id = service_connect_blocking(SERVICE_LOAD, 0, 0); 66 66 if (phone_id < 0) 67 67 return NULL; … … 90 90 ipc_call_t answer; 91 91 aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer); 92 int rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t)); 93 if (rc != EOK) { 94 async_wait_for(req, NULL); 95 return rc; 96 } 97 98 ipcarg_t retval; 92 int rc = async_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t)); 93 if (rc != EOK) { 94 async_wait_for(req, NULL); 95 return rc; 96 } 97 98 sysarg_t retval; 99 async_wait_for(req, &retval); 100 return (int) retval; 101 } 102 103 /** Set current working directory for the loaded task. 104 * 105 * Sets the current working directory for the loaded task. 106 * 107 * @param ldr Loader connection structure. 108 * 109 * @return Zero on success or negative error code. 110 * 111 */ 112 int loader_set_cwd(loader_t *ldr) 113 { 114 char *cwd; 115 size_t len; 116 117 cwd = (char *) malloc(MAX_PATH_LEN + 1); 118 if (!cwd) 119 return ENOMEM; 120 if (!getcwd(cwd, MAX_PATH_LEN + 1)) 121 str_cpy(cwd, MAX_PATH_LEN + 1, "/"); 122 len = str_length(cwd); 123 124 ipc_call_t answer; 125 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_CWD, &answer); 126 int rc = async_data_write_start(ldr->phone_id, cwd, len); 127 free(cwd); 128 if (rc != EOK) { 129 async_wait_for(req, NULL); 130 return rc; 131 } 132 133 sysarg_t retval; 99 134 async_wait_for(req, &retval); 100 135 return (int) retval; … … 123 158 ipc_call_t answer; 124 159 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer); 125 int rc = ipc_data_write_start(ldr->phone_id, (void *) pa, pa_len); 126 if (rc != EOK) { 160 int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len); 161 if (rc != EOK) { 162 free(pa); 127 163 async_wait_for(req, NULL); 128 164 return rc; … … 131 167 free(pa); 132 168 133 ipcarg_t retval;169 sysarg_t retval; 134 170 async_wait_for(req, &retval); 135 171 return (int) retval; … … 148 184 * 149 185 */ 150 int loader_set_args(loader_t *ldr, c har *const argv[])186 int loader_set_args(loader_t *ldr, const char *const argv[]) 151 187 { 152 188 /* … … 154 190 * compute size of the buffer needed. 155 191 */ 156 c har *const *ap = argv;192 const char *const *ap = argv; 157 193 size_t buffer_size = 0; 158 194 while (*ap != NULL) { … … 178 214 ipc_call_t answer; 179 215 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer); 180 ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size);216 sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size); 181 217 if (rc != EOK) { 182 218 async_wait_for(req, NULL); … … 232 268 ipc_call_t answer; 233 269 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer); 234 ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) files_buf,270 sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) files_buf, 235 271 count * sizeof(fdi_node_t)); 236 272 if (rc != EOK) { … … 284 320 return rc; 285 321 286 ipc_hangup(ldr->phone_id);322 async_hangup(ldr->phone_id); 287 323 ldr->phone_id = 0; 288 324 return EOK; … … 302 338 void loader_abort(loader_t *ldr) 303 339 { 304 ipc_hangup(ldr->phone_id);340 async_hangup(ldr->phone_id); 305 341 ldr->phone_id = 0; 306 342 } -
uspace/lib/c/generic/mem.c
rb50b5af2 r04803bf 222 222 /** Compare two memory areas. 223 223 * 224 * @param s1 Pointer to the first area to compare. 225 * @param s2 Pointer to the second area to compare. 226 * @param len Size of the first area in bytes. Both areas must have 227 * the same length. 228 * @return If len is 0, return zero. If the areas match, return 229 * zero. Otherwise return non-zero. 230 */ 231 int bcmp(const char *s1, const char *s2, size_t len) 232 { 233 for (; len && *s1++ == *s2++; len--) 234 ; 224 * @param s1 Pointer to the first area to compare. 225 * @param s2 Pointer to the second area to compare. 226 * @param len Size of the first area in bytes. Both areas must have 227 * the same length. 228 * 229 * @return If len is 0, return zero. If the areas match, return 230 * zero. Otherwise return non-zero. 231 * 232 */ 233 int bcmp(const void *s1, const void *s2, size_t len) 234 { 235 uint8_t *u1 = (uint8_t *) s1; 236 uint8_t *u2 = (uint8_t *) s2; 237 238 for (; (len != 0) && (*u1++ == *u2++); len--); 239 235 240 return len; 236 241 } -
uspace/lib/c/generic/mman.c
rb50b5af2 r04803bf 39 39 40 40 void *mmap(void *start, size_t length, int prot, int flags, int fd, 41 off_t offset)41 aoff64_t offset) 42 42 { 43 43 if (!start) -
uspace/lib/c/generic/private/async_sess.h
rb50b5af2 r04803bf 1 1 /* 2 * Copyright (c) 20 05Martin Decky2 * Copyright (c) 2011 Martin Decky 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup amd64debug29 /** @addtogroup libc 30 30 * @{ 31 31 */ … … 33 33 */ 34 34 35 #ifndef KERN_ia32_DEBUG_H_36 #define KERN_ia32_DEBUG_H_35 #ifndef LIBC_PRIVATE_ASYNC_SESS_H_ 36 #define LIBC_PRIVATE_ASYNC_SESS_H_ 37 37 38 #include <arch/asm.h> 39 40 #define HERE get_ip() 38 extern void __async_sess_init(void); 41 39 42 40 #endif -
uspace/lib/c/generic/private/libc.h
rb50b5af2 r04803bf 1 1 /* 2 * Copyright (c) 20 06 Jakub Jermar2 * Copyright (c) 2011 Martin Decky 3 3 * All rights reserved. 4 4 * … … 31 31 */ 32 32 /** @file 33 */ 33 */ 34 34 35 #include <libc.h> 36 #include <sysinfo.h> 37 #include <string.h> 35 #ifndef LIBC_PRIVATE_LIBC_H_ 36 #define LIBC_PRIVATE_LIBC_H_ 38 37 39 sysarg_t sysinfo_value(char *name) 40 { 41 return __SYSCALL2(SYS_SYSINFO_VALUE, (sysarg_t ) name, 42 (sysarg_t) str_size(name)); 43 } 38 extern void __entry(void); 39 extern void __main(void *) __attribute__((noreturn)); 40 extern int main(int, char *[]); 41 42 #endif 44 43 45 44 /** @} -
uspace/lib/c/generic/str.c
rb50b5af2 r04803bf 34 34 */ 35 35 36 #include <str ing.h>36 #include <str.h> 37 37 #include <stdlib.h> 38 38 #include <assert.h> 39 #include < limits.h>39 #include <stdint.h> 40 40 #include <ctype.h> 41 41 #include <malloc.h> … … 43 43 #include <align.h> 44 44 #include <mem.h> 45 #include <str ing.h>45 #include <str.h> 46 46 47 47 /** Byte mask consisting of lowest @n bits (out of 8) */ … … 471 471 * null-terminated and containing only complete characters. 472 472 * 473 * @param d stDestination buffer.473 * @param dest Destination buffer. 474 474 * @param count Size of the destination buffer (must be > 0). 475 475 * @param src Source string. … … 477 477 void str_cpy(char *dest, size_t size, const char *src) 478 478 { 479 wchar_t ch;480 size_t src_off;481 size_t dest_off;482 483 479 /* There must be space for a null terminator in the buffer. */ 484 480 assert(size > 0); 485 481 486 src_off = 0; 487 dest_off = 0; 488 482 size_t src_off = 0; 483 size_t dest_off = 0; 484 485 wchar_t ch; 489 486 while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) { 490 487 if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) 491 488 break; 492 489 } 493 490 494 491 dest[dest_off] = '\0'; 495 492 } … … 505 502 * have to be null-terminated. 506 503 * 507 * @param d stDestination buffer.504 * @param dest Destination buffer. 508 505 * @param count Size of the destination buffer (must be > 0). 509 506 * @param src Source string. 510 * @param n 507 * @param n Maximum number of bytes to read from @a src. 511 508 */ 512 509 void str_ncpy(char *dest, size_t size, const char *src, size_t n) 513 510 { 514 wchar_t ch;515 size_t src_off;516 size_t dest_off;517 518 511 /* There must be space for a null terminator in the buffer. */ 519 512 assert(size > 0); 520 513 521 src_off = 0; 522 dest_off = 0; 523 514 size_t src_off = 0; 515 size_t dest_off = 0; 516 517 wchar_t ch; 524 518 while ((ch = str_decode(src, &src_off, n)) != 0) { 525 519 if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) 526 520 break; 527 521 } 528 522 529 523 dest[dest_off] = '\0'; 530 524 } … … 537 531 * null-terminated and containing only complete characters. 538 532 * 539 * @param d st Destination buffer.533 * @param dest Destination buffer. 540 534 * @param count Size of the destination buffer. 541 535 * @param src Source string. … … 549 543 } 550 544 551 /** Copy NULL-terminated wide string to string 552 * 553 * Copy source wide string @a src to destination buffer @a dst. 554 * No more than @a size bytes are written. NULL-terminator is always 555 * written after the last succesfully copied character (i.e. if the 556 * destination buffer is has at least 1 byte, it will be always 557 * NULL-terminated). 558 * 559 * @param src Source wide string. 560 * @param dst Destination buffer. 561 * @param count Size of the destination buffer. 562 * 563 */ 564 void wstr_nstr(char *dst, const wchar_t *src, size_t size) 565 { 566 /* No space for the NULL-terminator in the buffer */ 567 if (size == 0) 568 return; 569 545 /** Convert wide string to string. 546 * 547 * Convert wide string @a src to string. The output is written to the buffer 548 * specified by @a dest and @a size. @a size must be non-zero and the string 549 * written will always be well-formed. 550 * 551 * @param dest Destination buffer. 552 * @param size Size of the destination buffer. 553 * @param src Source wide string. 554 */ 555 void wstr_to_str(char *dest, size_t size, const wchar_t *src) 556 { 570 557 wchar_t ch; 571 size_t src_idx = 0; 572 size_t dst_off = 0; 573 558 size_t src_idx; 559 size_t dest_off; 560 561 /* There must be space for a null terminator in the buffer. */ 562 assert(size > 0); 563 564 src_idx = 0; 565 dest_off = 0; 566 574 567 while ((ch = src[src_idx++]) != 0) { 575 if (chr_encode(ch, d st, &dst_off, size) != EOK)568 if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) 576 569 break; 577 570 } 578 579 if (dst_off >= size) 580 dst[size - 1] = 0; 581 else 582 dst[dst_off] = 0; 571 572 dest[dest_off] = '\0'; 573 } 574 575 /** Convert wide string to new string. 576 * 577 * Convert wide string @a src to string. Space for the new string is allocated 578 * on the heap. 579 * 580 * @param src Source wide string. 581 * @return New string. 582 */ 583 char *wstr_to_astr(const wchar_t *src) 584 { 585 char dbuf[STR_BOUNDS(1)]; 586 char *str; 587 wchar_t ch; 588 589 size_t src_idx; 590 size_t dest_off; 591 size_t dest_size; 592 593 /* Compute size of encoded string. */ 594 595 src_idx = 0; 596 dest_size = 0; 597 598 while ((ch = src[src_idx++]) != 0) { 599 dest_off = 0; 600 if (chr_encode(ch, dbuf, &dest_off, STR_BOUNDS(1)) != EOK) 601 break; 602 dest_size += dest_off; 603 } 604 605 str = malloc(dest_size + 1); 606 if (str == NULL) 607 return NULL; 608 609 /* Encode string. */ 610 611 src_idx = 0; 612 dest_off = 0; 613 614 while ((ch = src[src_idx++]) != 0) { 615 if (chr_encode(ch, str, &dest_off, dest_size) != EOK) 616 break; 617 } 618 619 str[dest_size] = '\0'; 620 return str; 621 } 622 623 624 /** Convert string to wide string. 625 * 626 * Convert string @a src to wide string. The output is written to the 627 * buffer specified by @a dest and @a dlen. @a dlen must be non-zero 628 * and the wide string written will always be null-terminated. 629 * 630 * @param dest Destination buffer. 631 * @param dlen Length of destination buffer (number of wchars). 632 * @param src Source string. 633 */ 634 void str_to_wstr(wchar_t *dest, size_t dlen, const char *src) 635 { 636 size_t offset; 637 size_t di; 638 wchar_t c; 639 640 assert(dlen > 0); 641 642 offset = 0; 643 di = 0; 644 645 do { 646 if (di >= dlen - 1) 647 break; 648 649 c = str_decode(src, &offset, STR_NO_LIMIT); 650 dest[di++] = c; 651 } while (c != '\0'); 652 653 dest[dlen - 1] = '\0'; 583 654 } 584 655 … … 819 890 } 820 891 892 /** Duplicate string. 893 * 894 * Allocate a new string and copy characters from the source 895 * string into it. The duplicate string is allocated via sleeping 896 * malloc(), thus this function can sleep in no memory conditions. 897 * 898 * The allocation cannot fail and the return value is always 899 * a valid pointer. The duplicate string is always a well-formed 900 * null-terminated UTF-8 string, but it can differ from the source 901 * string on the byte level. 902 * 903 * @param src Source string. 904 * 905 * @return Duplicate string. 906 * 907 */ 908 char *str_dup(const char *src) 909 { 910 size_t size = str_size(src) + 1; 911 char *dest = (char *) malloc(size); 912 if (dest == NULL) 913 return (char *) NULL; 914 915 str_cpy(dest, size, src); 916 return dest; 917 } 918 919 /** Duplicate string with size limit. 920 * 921 * Allocate a new string and copy up to @max_size bytes from the source 922 * string into it. The duplicate string is allocated via sleeping 923 * malloc(), thus this function can sleep in no memory conditions. 924 * No more than @max_size + 1 bytes is allocated, but if the size 925 * occupied by the source string is smaller than @max_size + 1, 926 * less is allocated. 927 * 928 * The allocation cannot fail and the return value is always 929 * a valid pointer. The duplicate string is always a well-formed 930 * null-terminated UTF-8 string, but it can differ from the source 931 * string on the byte level. 932 * 933 * @param src Source string. 934 * @param n Maximum number of bytes to duplicate. 935 * 936 * @return Duplicate string. 937 * 938 */ 939 char *str_ndup(const char *src, size_t n) 940 { 941 size_t size = str_size(src); 942 if (size > n) 943 size = n; 944 945 char *dest = (char *) malloc(size + 1); 946 if (dest == NULL) 947 return (char *) NULL; 948 949 str_ncpy(dest, size + 1, src, size); 950 return dest; 951 } 952 821 953 822 954 /** Convert initial part of string to unsigned long according to given base. … … 843 975 } 844 976 845 char *str_dup(const char *src)846 {847 size_t size = str_size(src);848 void *dest = malloc(size + 1);849 850 if (dest == NULL)851 return (char *) NULL;852 853 return (char *) memcpy(dest, src, size + 1);854 }855 856 977 char *strtok(char *s, const char *delim) 857 978 { … … 886 1007 } 887 1008 1009 /** Convert string to uint64_t (internal variant). 1010 * 1011 * @param nptr Pointer to string. 1012 * @param endptr Pointer to the first invalid character is stored here. 1013 * @param base Zero or number between 2 and 36 inclusive. 1014 * @param neg Indication of unary minus is stored here. 1015 * @apram result Result of the conversion. 1016 * 1017 * @return EOK if conversion was successful. 1018 * 1019 */ 1020 static int str_uint(const char *nptr, char **endptr, unsigned int base, 1021 bool *neg, uint64_t *result) 1022 { 1023 assert(endptr != NULL); 1024 assert(neg != NULL); 1025 assert(result != NULL); 1026 1027 *neg = false; 1028 const char *str = nptr; 1029 1030 /* Ignore leading whitespace */ 1031 while (isspace(*str)) 1032 str++; 1033 1034 if (*str == '-') { 1035 *neg = true; 1036 str++; 1037 } else if (*str == '+') 1038 str++; 1039 1040 if (base == 0) { 1041 /* Decode base if not specified */ 1042 base = 10; 1043 1044 if (*str == '0') { 1045 base = 8; 1046 str++; 1047 1048 switch (*str) { 1049 case 'b': 1050 case 'B': 1051 base = 2; 1052 str++; 1053 break; 1054 case 'o': 1055 case 'O': 1056 base = 8; 1057 str++; 1058 break; 1059 case 'd': 1060 case 'D': 1061 case 't': 1062 case 'T': 1063 base = 10; 1064 str++; 1065 break; 1066 case 'x': 1067 case 'X': 1068 base = 16; 1069 str++; 1070 break; 1071 default: 1072 str--; 1073 } 1074 } 1075 } else { 1076 /* Check base range */ 1077 if ((base < 2) || (base > 36)) { 1078 *endptr = (char *) str; 1079 return EINVAL; 1080 } 1081 } 1082 1083 *result = 0; 1084 const char *startstr = str; 1085 1086 while (*str != 0) { 1087 unsigned int digit; 1088 1089 if ((*str >= 'a') && (*str <= 'z')) 1090 digit = *str - 'a' + 10; 1091 else if ((*str >= 'A') && (*str <= 'Z')) 1092 digit = *str - 'A' + 10; 1093 else if ((*str >= '0') && (*str <= '9')) 1094 digit = *str - '0'; 1095 else 1096 break; 1097 1098 if (digit >= base) 1099 break; 1100 1101 uint64_t prev = *result; 1102 *result = (*result) * base + digit; 1103 1104 if (*result < prev) { 1105 /* Overflow */ 1106 *endptr = (char *) str; 1107 return EOVERFLOW; 1108 } 1109 1110 str++; 1111 } 1112 1113 if (str == startstr) { 1114 /* 1115 * No digits were decoded => first invalid character is 1116 * the first character of the string. 1117 */ 1118 str = nptr; 1119 } 1120 1121 *endptr = (char *) str; 1122 1123 if (str == nptr) 1124 return EINVAL; 1125 1126 return EOK; 1127 } 1128 1129 /** Convert string to uint64_t. 1130 * 1131 * @param nptr Pointer to string. 1132 * @param endptr If not NULL, pointer to the first invalid character 1133 * is stored here. 1134 * @param base Zero or number between 2 and 36 inclusive. 1135 * @param strict Do not allow any trailing characters. 1136 * @param result Result of the conversion. 1137 * 1138 * @return EOK if conversion was successful. 1139 * 1140 */ 1141 int str_uint64(const char *nptr, char **endptr, unsigned int base, 1142 bool strict, uint64_t *result) 1143 { 1144 assert(result != NULL); 1145 1146 bool neg; 1147 char *lendptr; 1148 int ret = str_uint(nptr, &lendptr, base, &neg, result); 1149 1150 if (endptr != NULL) 1151 *endptr = (char *) lendptr; 1152 1153 if (ret != EOK) 1154 return ret; 1155 1156 /* Do not allow negative values */ 1157 if (neg) 1158 return EINVAL; 1159 1160 /* Check whether we are at the end of 1161 the string in strict mode */ 1162 if ((strict) && (*lendptr != 0)) 1163 return EINVAL; 1164 1165 return EOK; 1166 } 1167 1168 /** Convert string to size_t. 1169 * 1170 * @param nptr Pointer to string. 1171 * @param endptr If not NULL, pointer to the first invalid character 1172 * is stored here. 1173 * @param base Zero or number between 2 and 36 inclusive. 1174 * @param strict Do not allow any trailing characters. 1175 * @param result Result of the conversion. 1176 * 1177 * @return EOK if conversion was successful. 1178 * 1179 */ 1180 int str_size_t(const char *nptr, char **endptr, unsigned int base, 1181 bool strict, size_t *result) 1182 { 1183 assert(result != NULL); 1184 1185 bool neg; 1186 char *lendptr; 1187 uint64_t res; 1188 int ret = str_uint(nptr, &lendptr, base, &neg, &res); 1189 1190 if (endptr != NULL) 1191 *endptr = (char *) lendptr; 1192 1193 if (ret != EOK) 1194 return ret; 1195 1196 /* Do not allow negative values */ 1197 if (neg) 1198 return EINVAL; 1199 1200 /* Check whether we are at the end of 1201 the string in strict mode */ 1202 if ((strict) && (*lendptr != 0)) 1203 return EINVAL; 1204 1205 /* Check for overflow */ 1206 size_t _res = (size_t) res; 1207 if (_res != res) 1208 return EOVERFLOW; 1209 1210 *result = _res; 1211 1212 return EOK; 1213 } 1214 1215 void order_suffix(const uint64_t val, uint64_t *rv, char *suffix) 1216 { 1217 if (val > 10000000000000000000ULL) { 1218 *rv = val / 1000000000000000000ULL; 1219 *suffix = 'Z'; 1220 } else if (val > 1000000000000000000ULL) { 1221 *rv = val / 1000000000000000ULL; 1222 *suffix = 'E'; 1223 } else if (val > 1000000000000000ULL) { 1224 *rv = val / 1000000000000ULL; 1225 *suffix = 'T'; 1226 } else if (val > 1000000000000ULL) { 1227 *rv = val / 1000000000ULL; 1228 *suffix = 'G'; 1229 } else if (val > 1000000000ULL) { 1230 *rv = val / 1000000ULL; 1231 *suffix = 'M'; 1232 } else if (val > 1000000ULL) { 1233 *rv = val / 1000ULL; 1234 *suffix = 'k'; 1235 } else { 1236 *rv = val; 1237 *suffix = ' '; 1238 } 1239 } 1240 888 1241 /** @} 889 1242 */ -
uspace/lib/c/generic/task.c
rb50b5af2 r04803bf 39 39 #include <errno.h> 40 40 #include <loader/loader.h> 41 #include <string.h> 41 #include <stdarg.h> 42 #include <str.h> 42 43 #include <ipc/ns.h> 43 44 #include <macros.h> … … 46 47 task_id_t task_get_id(void) 47 48 { 49 #ifdef __32_BITS__ 48 50 task_id_t task_id; 49 51 (void) __SYSCALL1(SYS_TASK_GET_ID, (sysarg_t) &task_id); 50 52 51 53 return task_id; 54 #endif /* __32_BITS__ */ 55 56 #ifdef __64_BITS__ 57 return (task_id_t) __SYSCALL0(SYS_TASK_GET_ID); 58 #endif /* __64_BITS__ */ 52 59 } 53 60 … … 58 65 * 59 66 * @return Zero on success or negative error code. 60 *61 67 */ 62 68 int task_set_name(const char *name) … … 65 71 } 66 72 73 /** Kill a task. 74 * 75 * @param task_id ID of task to kill. 76 * 77 * @return Zero on success or negative error code. 78 */ 79 80 int task_kill(task_id_t task_id) 81 { 82 return (int) __SYSCALL1(SYS_TASK_KILL, (sysarg_t) &task_id); 83 } 84 67 85 /** Create a new task by running an executable from the filesystem. 68 86 * 69 87 * This is really just a convenience wrapper over the more complicated 70 * loader API. 71 * 72 * @param path pathname of the binary to execute 73 * @param argv command-line arguments 74 * 75 * @return ID of the newly created task or zero on error. 76 * 77 */ 78 task_id_t task_spawn(const char *path, char *const args[]) 79 { 88 * loader API. Arguments are passed as a null-terminated array of strings. 89 * 90 * @param id If not NULL, the ID of the task is stored here on success. 91 * @param path Pathname of the binary to execute. 92 * @param argv Command-line arguments. 93 * 94 * @return Zero on success or negative error code. 95 */ 96 int task_spawnv(task_id_t *id, const char *path, const char *const args[]) 97 { 98 loader_t *ldr; 99 task_id_t task_id; 100 int rc; 101 80 102 /* Connect to a program loader. */ 81 l oader_t *ldr = loader_connect();103 ldr = loader_connect(); 82 104 if (ldr == NULL) 83 return 0;105 return EREFUSED; 84 106 85 107 /* Get task ID. */ 86 task_id_t task_id; 87 int rc = loader_get_task_id(ldr, &task_id); 108 rc = loader_get_task_id(ldr, &task_id); 109 if (rc != EOK) 110 goto error; 111 112 /* Send spawner's current working directory. */ 113 rc = loader_set_cwd(ldr); 88 114 if (rc != EOK) 89 115 goto error; … … 98 124 if (rc != EOK) 99 125 goto error; 100 101 126 102 127 /* Send default files */ … … 139 164 /* Success */ 140 165 free(ldr); 141 return task_id; 166 167 if (id != NULL) 168 *id = task_id; 169 170 return EOK; 142 171 143 172 error: … … 145 174 loader_abort(ldr); 146 175 free(ldr); 147 148 return 0; 176 return rc; 177 } 178 179 /** Create a new task by running an executable from the filesystem. 180 * 181 * This is really just a convenience wrapper over the more complicated 182 * loader API. Arguments are passed as a null-terminated list of arguments. 183 * 184 * @param id If not NULL, the ID of the task is stored here on success. 185 * @param path Pathname of the binary to execute. 186 * @param ... Command-line arguments. 187 * 188 * @return Zero on success or negative error code. 189 */ 190 int task_spawnl(task_id_t *task_id, const char *path, ...) 191 { 192 va_list ap; 193 int rc, cnt; 194 const char *arg; 195 const char **arglist; 196 197 /* Count the number of arguments. */ 198 cnt = 0; 199 va_start(ap, path); 200 do { 201 arg = va_arg(ap, const char *); 202 cnt++; 203 } while (arg != NULL); 204 va_end(ap); 205 206 /* Allocate argument list. */ 207 arglist = malloc(cnt * sizeof(const char *)); 208 if (arglist == NULL) 209 return ENOMEM; 210 211 /* Fill in arguments. */ 212 cnt = 0; 213 va_start(ap, path); 214 do { 215 arg = va_arg(ap, const char *); 216 arglist[cnt++] = arg; 217 } while (arg != NULL); 218 va_end(ap); 219 220 /* Spawn task. */ 221 rc = task_spawnv(task_id, path, arglist); 222 223 /* Free argument list. */ 224 free(arglist); 225 return rc; 149 226 } 150 227 151 228 int task_wait(task_id_t id, task_exit_t *texit, int *retval) 152 229 { 153 ipcarg_t te, rv;230 sysarg_t te, rv; 154 231 int rc; 155 232 -
uspace/lib/c/generic/thread.c
rb50b5af2 r04803bf 31 31 */ 32 32 /** @file 33 */ 33 */ 34 34 35 35 #include <thread.h> … … 39 39 #include <kernel/proc/uarg.h> 40 40 #include <fibril.h> 41 #include <str ing.h>41 #include <str.h> 42 42 #include <async.h> 43 #include "private/thread.h" 43 44 44 45 #ifndef THREAD_INITIAL_STACK_PAGES_NO … … 50 51 * This function is called from __thread_entry() and is used 51 52 * to call the thread's implementing function and perform cleanup 52 * and exit when thread returns back. Do not call this function 53 * directly. 53 * and exit when thread returns back. 54 54 * 55 55 * @param uarg Pointer to userspace argument structure. 56 * 56 57 */ 57 58 void __thread_main(uspace_arg_t *uarg) 58 59 { 59 fibril_t *f; 60 61 f = fibril_setup(); 62 __tcb_set(f->tcb); 63 60 fibril_t *fibril = fibril_setup(); 61 if (fibril == NULL) 62 thread_exit(0); 63 64 __tcb_set(fibril->tcb); 65 64 66 uarg->uspace_thread_function(uarg->uspace_thread_arg); 65 /* XXX: we cannot free the userspace stack while running on it */ 66 // free(uarg->uspace_stack); 67 // free(uarg); 68 67 /* XXX: we cannot free the userspace stack while running on it 68 free(uarg->uspace_stack); 69 free(uarg); 70 */ 71 69 72 /* If there is a manager, destroy it */ 70 73 async_destroy_manager(); 71 fibril_teardown(f );72 74 fibril_teardown(fibril); 75 73 76 thread_exit(0); 74 77 } … … 86 89 * @return Zero on success or a code from @ref errno.h on failure. 87 90 */ 88 int thread_create(void (* function)(void *), void *arg, c har *name,91 int thread_create(void (* function)(void *), void *arg, const char *name, 89 92 thread_id_t *tid) 90 93 { … … 127 130 * 128 131 * @param status Exit status. Currently not used. 132 * 129 133 */ 130 134 void thread_exit(int status) 131 135 { 132 136 __SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status); 133 for (;;) 134 ; 137 138 /* Unreachable */ 139 while (1); 135 140 } 136 141 -
uspace/lib/c/generic/time.c
rb50b5af2 r04803bf 31 31 */ 32 32 /** @file 33 */ 33 */ 34 34 35 35 #include <sys/time.h> 36 #include <unistd.h> 37 #include <ipc/ipc.h> 38 #include <stdio.h> 36 #include <time.h> 37 #include <bool.h> 39 38 #include <arch/barrier.h> 40 #include <unistd.h> 41 #include <atomic.h> 42 #include <futex.h> 43 #include <sysinfo.h> 44 #include <ipc/services.h> 45 39 #include <macros.h> 40 #include <errno.h> 46 41 #include <sysinfo.h> 47 42 #include <as.h> 48 43 #include <ddi.h> 49 50 #include <time.h> 51 52 /* Pointers to public variables with time */ 44 #include <libc.h> 45 46 /** Pointer to kernel shared variables with time */ 53 47 struct { 54 48 volatile sysarg_t seconds1; … … 59 53 /** Add microseconds to given timeval. 60 54 * 61 * @param tv Destination timeval. 62 * @param usecs Number of microseconds to add. 55 * @param tv Destination timeval. 56 * @param usecs Number of microseconds to add. 57 * 63 58 */ 64 59 void tv_add(struct timeval *tv, suseconds_t usecs) … … 66 61 tv->tv_sec += usecs / 1000000; 67 62 tv->tv_usec += usecs % 1000000; 63 68 64 if (tv->tv_usec > 1000000) { 69 65 tv->tv_sec++; … … 74 70 /** Subtract two timevals. 75 71 * 76 * @param tv1 First timeval. 77 * @param tv2 Second timeval. 78 * 79 * @return Return difference between tv1 and tv2 (tv1 - tv2) in 80 * microseconds. 72 * @param tv1 First timeval. 73 * @param tv2 Second timeval. 74 * 75 * @return Difference between tv1 and tv2 (tv1 - tv2) in 76 * microseconds. 77 * 81 78 */ 82 79 suseconds_t tv_sub(struct timeval *tv1, struct timeval *tv2) 83 80 { 84 suseconds_t result; 85 86 result = tv1->tv_usec - tv2->tv_usec; 87 result += (tv1->tv_sec - tv2->tv_sec) * 1000000; 88 89 return result; 81 return (tv1->tv_usec - tv2->tv_usec) + 82 ((tv1->tv_sec - tv2->tv_sec) * 1000000); 90 83 } 91 84 92 85 /** Decide if one timeval is greater than the other. 93 86 * 94 * @param t1 First timeval. 95 * @param t2 Second timeval. 96 * 97 * @return Return true tv1 is greater than tv2. Otherwise return 98 * false. 87 * @param t1 First timeval. 88 * @param t2 Second timeval. 89 * 90 * @return True if tv1 is greater than tv2. 91 * @return False otherwise. 92 * 99 93 */ 100 94 int tv_gt(struct timeval *tv1, struct timeval *tv2) 101 95 { 102 96 if (tv1->tv_sec > tv2->tv_sec) 103 return 1; 104 if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec > tv2->tv_usec) 105 return 1; 106 return 0; 97 return true; 98 99 if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec > tv2->tv_usec)) 100 return true; 101 102 return false; 107 103 } 108 104 109 105 /** Decide if one timeval is greater than or equal to the other. 110 106 * 111 * @param tv1 First timeval. 112 * @param tv2 Second timeval. 113 * 114 * @return Return true if tv1 is greater than or equal to tv2. 115 * Otherwise return false. 107 * @param tv1 First timeval. 108 * @param tv2 Second timeval. 109 * 110 * @return True if tv1 is greater than or equal to tv2. 111 * @return False otherwise. 112 * 116 113 */ 117 114 int tv_gteq(struct timeval *tv1, struct timeval *tv2) 118 115 { 119 116 if (tv1->tv_sec > tv2->tv_sec) 120 return 1; 121 if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec >= tv2->tv_usec) 122 return 1; 123 return 0; 124 } 125 126 127 /** POSIX gettimeofday 128 * 129 * The time variables are memory mapped(RO) from kernel, which updates 130 * them periodically. As it is impossible to read 2 values atomically, we 131 * use a trick: First read a seconds, then read microseconds, then 132 * read seconds again. If a second elapsed in the meantime, set it to zero. 133 * This provides assurance, that at least the 134 * sequence of subsequent gettimeofday calls is ordered. 117 return true; 118 119 if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec >= tv2->tv_usec)) 120 return true; 121 122 return false; 123 } 124 125 /** Get time of day 126 * 127 * The time variables are memory mapped (read-only) from kernel which 128 * updates them periodically. 129 * 130 * As it is impossible to read 2 values atomically, we use a trick: 131 * First we read the seconds, then we read the microseconds, then we 132 * read the seconds again. If a second elapsed in the meantime, set 133 * the microseconds to zero. 134 * 135 * This assures that the values returned by two subsequent calls 136 * to gettimeofday() are monotonous. 137 * 135 138 */ 136 139 int gettimeofday(struct timeval *tv, struct timezone *tz) 137 140 { 138 void *mapping; 139 sysarg_t s1, s2; 140 int rights; 141 int res; 142 143 if (!ktime) { 144 mapping = as_get_mappable_page(PAGE_SIZE); 145 /* Get the mapping of kernel clock */ 146 res = ipc_share_in_start_1_1(PHONE_NS, mapping, PAGE_SIZE, 147 SERVICE_MEM_REALTIME, &rights); 148 if (res) { 149 printf("Failed to initialize timeofday memarea\n"); 150 printf("Address was 0x%x\n", (unsigned)mapping); 151 _exit(1); 141 if (ktime == NULL) { 142 uintptr_t faddr; 143 int rc = sysinfo_get_value("clock.faddr", &faddr); 144 if (rc != EOK) { 145 errno = rc; 146 return -1; 152 147 } 153 if (!(rights & AS_AREA_READ)) {154 printf("Received bad rights on time area: %X\n",155 rights);156 as_area_destroy(mapping);157 _exit(1);148 149 void *addr = as_get_mappable_page(PAGE_SIZE); 150 if (addr == NULL) { 151 errno = ENOMEM; 152 return -1; 158 153 } 159 ktime = mapping; 160 } 154 155 rc = physmem_map((void *) faddr, addr, 1, 156 AS_AREA_READ | AS_AREA_CACHEABLE); 157 if (rc != EOK) { 158 as_area_destroy(addr); 159 errno = rc; 160 return -1; 161 } 162 163 ktime = addr; 164 } 165 161 166 if (tz) { 162 167 tz->tz_minuteswest = 0; 163 168 tz->tz_dsttime = DST_NONE; 164 169 } 165 166 s2 = ktime->seconds2; 170 171 sysarg_t s2 = ktime->seconds2; 172 167 173 read_barrier(); 168 174 tv->tv_usec = ktime->useconds; 175 169 176 read_barrier(); 170 s1 = ktime->seconds1; 177 sysarg_t s1 = ktime->seconds1; 178 171 179 if (s1 != s2) { 180 tv->tv_sec = max(s1, s2); 172 181 tv->tv_usec = 0; 173 tv->tv_sec = s1 > s2 ? s1 : s2;174 182 } else 175 183 tv->tv_sec = s1; 176 184 177 185 return 0; 178 186 } … … 181 189 { 182 190 struct timeval tv; 183 184 191 if (gettimeofday(&tv, NULL)) 185 192 return (time_t) -1; 193 186 194 if (tloc) 187 195 *tloc = tv.tv_sec; 196 188 197 return tv.tv_sec; 189 198 } 190 199 191 /** Wait unconditionally for specified number of microseconds */ 192 int usleep(unsigned long usec) 193 { 194 atomic_t futex = FUTEX_INITIALIZER; 195 196 futex_initialize(&futex, 0); 197 futex_down_timeout(&futex, usec, 0); 200 /** Wait unconditionally for specified number of microseconds 201 * 202 */ 203 int usleep(useconds_t usec) 204 { 205 (void) __SYSCALL1(SYS_THREAD_USLEEP, usec); 198 206 return 0; 199 207 } 200 208 201 /** Wait unconditionally for specified number of seconds */ 202 unsigned int sleep(unsigned int seconds) 203 { 204 atomic_t futex = FUTEX_INITIALIZER; 205 206 futex_initialize(&futex, 0); 207 208 /* Sleep in 1000 second steps to support 209 full argument range */ 210 while (seconds > 0) { 211 unsigned int period = (seconds > 1000) ? 1000 : seconds; 212 213 futex_down_timeout(&futex, period * 1000000, 0); 214 seconds -= period; 215 } 209 /** Wait unconditionally for specified number of seconds 210 * 211 */ 212 unsigned int sleep(unsigned int sec) 213 { 214 /* 215 * Sleep in 1000 second steps to support 216 * full argument range 217 */ 218 219 while (sec > 0) { 220 unsigned int period = (sec > 1000) ? 1000 : sec; 221 222 usleep(period * 1000000); 223 sec -= period; 224 } 225 216 226 return 0; 217 227 } -
uspace/lib/c/generic/tls.c
rb50b5af2 r04803bf 40 40 #include <tls.h> 41 41 #include <malloc.h> 42 #include <str ing.h>42 #include <str.h> 43 43 #include <align.h> 44 44 -
uspace/lib/c/generic/udebug.c
rb50b5af2 r04803bf 31 31 */ 32 32 /** @file 33 */ 33 */ 34 34 35 35 #include <udebug.h> 36 36 #include <sys/types.h> 37 #include <ipc/ipc.h>38 37 #include <async.h> 39 38 … … 57 56 size_t *copied, size_t *needed) 58 57 { 59 ipcarg_t a_copied, a_needed;58 sysarg_t a_copied, a_needed; 60 59 int rc; 61 60 62 61 rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_THREAD_READ, 62 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed); 63 64 *copied = (size_t)a_copied; 65 *needed = (size_t)a_needed; 66 67 return rc; 68 } 69 70 int udebug_name_read(int phoneid, void *buffer, size_t n, 71 size_t *copied, size_t *needed) 72 { 73 sysarg_t a_copied, a_needed; 74 int rc; 75 76 rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_NAME_READ, 77 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed); 78 79 *copied = (size_t)a_copied; 80 *needed = (size_t)a_needed; 81 82 return rc; 83 } 84 85 int udebug_areas_read(int phoneid, void *buffer, size_t n, 86 size_t *copied, size_t *needed) 87 { 88 sysarg_t a_copied, a_needed; 89 int rc; 90 91 rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_AREAS_READ, 63 92 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed); 64 93 … … 81 110 } 82 111 112 int udebug_regs_read(int phoneid, thash_t tid, void *buffer) 113 { 114 return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_REGS_READ, 115 tid, (sysarg_t)buffer); 116 } 117 83 118 int udebug_go(int phoneid, thash_t tid, udebug_event_t *ev_type, 84 119 sysarg_t *val0, sysarg_t *val1) 85 120 { 86 ipcarg_t a_ev_type;121 sysarg_t a_ev_type; 87 122 int rc; 88 123 -
uspace/lib/c/generic/vfs/canonify.c
rb50b5af2 r04803bf 142 142 t->start[-1] = '\0'; 143 143 } 144 /** Eat the extra '/'. .144 /** Eat the extra '/'. 145 145 * 146 146 * @param t The current TK_SLASH token. … … 288 288 * 289 289 * A file system path is canonical, if the following holds: 290 * 1) the path is absolute (i.e. a/b/c is not canonical) 291 * 2) there is no trailing slash in the path (i.e. /a/b/c is not canonical) 292 * 3) there is no extra slash in the path (i.e. /a//b/c is not canonical) 293 * 4) there is no '.' component in the path (i.e. /a/./b/c is not canonical) 294 * 5) there is no '..' component in the path (i.e. /a/b/../c is not canonical) 290 * 291 * 1) the path is absolute 292 * (i.e. a/b/c is not canonical) 293 * 2) there is no trailing slash in the path if it has components 294 * (i.e. /a/b/c/ is not canonical) 295 * 3) there is no extra slash in the path 296 * (i.e. /a//b/c is not canonical) 297 * 4) there is no '.' component in the path 298 * (i.e. /a/./b/c is not canonical) 299 * 5) there is no '..' component in the path 300 * (i.e. /a/b/../c is not canonical) 295 301 * 296 302 * This function makes a potentially non-canonical file system path canonical. -
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.