Changeset 8ff0bd2 in mainline for uspace/lib/c/generic
- Timestamp:
- 2011-09-04T11:30:58Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 03bc76a
- Parents:
- d2c67e7 (diff), deac215e (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:
-
- 1 added
- 4 deleted
- 36 edited
- 1 moved
-
adt/hash_table.c (modified) (5 diffs)
-
adt/list.c (modified) (3 diffs)
-
adt/measured_strings.c (modified) (12 diffs)
-
adt/prodcons.c (modified) (1 diff)
-
async.c (modified) (48 diffs)
-
async_obsolete.c (modified) (5 diffs)
-
ddi.c (modified) (2 diffs)
-
devman.c (modified) (12 diffs)
-
devman_obsolete.c (deleted)
-
devmap.c (deleted)
-
devmap_obsolete.c (deleted)
-
elf/elf_load.c (moved) (moved from uspace/srv/loader/elf_load.c ) (9 diffs)
-
event.c (modified) (3 diffs)
-
fibril.c (modified) (4 diffs)
-
fibril_synch.c (modified) (3 diffs)
-
io/console.c (modified) (1 diff)
-
io/io.c (modified) (10 diffs)
-
io/printf_core.c (modified) (5 diffs)
-
ipc.c (modified) (6 diffs)
-
libc.c (modified) (1 diff)
-
loader.c (modified) (1 diff)
-
loc.c (added)
-
net/icmp_api.c (modified) (4 diffs)
-
net/icmp_common.c (modified) (1 diff)
-
net/modules.c (modified) (5 diffs)
-
net/socket_client.c (modified) (33 diffs)
-
ns.c (modified) (3 diffs)
-
ns_obsolete.c (modified) (1 diff)
-
private/async.h (modified) (1 diff)
-
private/io.h (modified) (1 diff)
-
private/thread.h (modified) (1 diff)
-
rtld/elf_load.c (deleted)
-
rtld/module.c (modified) (7 diffs)
-
rtld/rtld.c (modified) (1 diff)
-
rtld/symbol.c (modified) (6 diffs)
-
str.c (modified) (5 diffs)
-
sysinfo.c (modified) (1 diff)
-
task.c (modified) (3 diffs)
-
thread.c (modified) (1 diff)
-
time.c (modified) (1 diff)
-
udebug.c (modified) (1 diff)
-
vfs/vfs.c (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/adt/hash_table.c
rd2c67e7 r8ff0bd2 61 61 assert(max_keys > 0); 62 62 63 h->entry = malloc(m * sizeof(li nk_t));63 h->entry = malloc(m * sizeof(list_t)); 64 64 if (!h->entry) 65 65 return false; 66 66 67 memset((void *) h->entry, 0, m * sizeof(li nk_t));67 memset((void *) h->entry, 0, m * sizeof(list_t)); 68 68 69 69 hash_count_t i; … … 123 123 assert(chain < h->entries); 124 124 125 link_t *cur; 126 for (cur = h->entry[chain].next; cur != &h->entry[chain]; 127 cur = cur->next) { 125 list_foreach(h->entry[chain], cur) { 128 126 if (h->op->compare(key, h->max_keys, cur)) { 129 127 /* … … 153 151 assert(keys <= h->max_keys); 154 152 155 link_t *cur;156 157 153 if (keys == h->max_keys) { 154 link_t *cur; 155 158 156 /* 159 157 * All keys are known, hash_table_find() can be used to find the … … 176 174 hash_index_t chain; 177 175 for (chain = 0; chain < h->entries; chain++) { 178 for (cur = h->entry[chain].next; cur != &h->entry[chain]; 176 link_t *cur; 177 178 for (cur = h->entry[chain].head.next; cur != &h->entry[chain].head; 179 179 cur = cur->next) { 180 180 if (h->op->compare(key, keys, cur)) { … … 203 203 { 204 204 hash_index_t bucket; 205 link_t *cur;206 205 207 206 for (bucket = 0; bucket < h->entries; bucket++) { 208 for (cur = h->entry[bucket].next; cur != &h->entry[bucket]; 209 cur = cur->next) { 207 list_foreach(h->entry[bucket], cur) { 210 208 f(cur, arg); 211 209 } -
uspace/lib/c/generic/adt/list.c
rd2c67e7 r8ff0bd2 30 30 * @{ 31 31 */ 32 /** @file 32 33 /** 34 * @file 35 * @brief Functions completing doubly linked circular list implementaion. 36 * 37 * This file contains some of the functions implementing doubly linked circular lists. 38 * However, this ADT is mostly implemented in @ref list.h. 33 39 */ 34 40 35 41 #include <adt/list.h> 36 42 #include <bool.h> 37 43 38 44 /** Check for membership 39 45 * 40 * Check whether link is contained in the list head.41 * The membership is defined as pointer equivalence.46 * Check whether link is contained in a list. 47 * Membership is defined as pointer equivalence. 42 48 * 43 * @param link Item to look for.44 * @param headList to look in.49 * @param link Item to look for. 50 * @param list List to look in. 45 51 * 46 52 * @return true if link is contained in head, false otherwise. 47 53 * 48 54 */ 49 int list_member(const link_t *link, const li nk_t *head)55 int list_member(const link_t *link, const list_t *list) 50 56 { 51 int found = 0;52 link_t *hlp = head->next;57 bool found = false; 58 link_t *hlp = list->head.next; 53 59 54 while (hlp != head) {60 while (hlp != &list->head) { 55 61 if (hlp == link) { 56 found = 1;62 found = true; 57 63 break; 58 64 } … … 63 69 } 64 70 65 66 71 /** Concatenate two lists 67 72 * 68 * Concatenate lists head1 and head2, producing a single69 * list head1 containing items from both (in head1, head270 * order) and empty list head2.73 * Concatenate lists @a list1 and @a list2, producing a single 74 * list @a list1 containing items from both (in @a list1, @a list2 75 * order) and empty list @a list2. 71 76 * 72 * @param head1First list and concatenated output73 * @param head2Second list and empty output.77 * @param list1 First list and concatenated output 78 * @param list2 Second list and empty output. 74 79 * 75 80 */ 76 void list_concat(li nk_t *head1, link_t *head2)81 void list_concat(list_t *list1, list_t *list2) 77 82 { 78 if (list_empty( head2))83 if (list_empty(list2)) 79 84 return; 80 81 head2->next->prev = head1->prev;82 head2->prev->next = head1;83 head1->prev->next = head2->next;84 head1->prev = head2->prev;85 list_initialize( head2);85 86 list2->head.next->prev = list1->head.prev; 87 list2->head.prev->next = &list1->head; 88 list1->head.prev->next = list2->head.next; 89 list1->head.prev = list2->head.prev; 90 list_initialize(list2); 86 91 } 87 88 92 89 93 /** Count list items … … 91 95 * Return the number of items in the list. 92 96 * 93 * @param link List to count. 94 * 95 * @return Number of items in the list. 96 * 97 * @param list List to count. 98 * @return Number of items in the list. 97 99 */ 98 unsigned int list_count(const li nk_t *link)100 unsigned int list_count(const list_t *list) 99 101 { 100 102 unsigned int count = 0; 101 link_t *hlp = link->next;102 103 103 while (hlp !=link) {104 list_foreach(*list, link) { 104 105 count++; 105 hlp = hlp->next;106 106 } 107 107 -
uspace/lib/c/generic/adt/measured_strings.c
rd2c67e7 r8ff0bd2 42 42 #include <errno.h> 43 43 #include <async.h> 44 #include <async_obsolete.h>45 44 46 45 /** Creates a new measured string bundled with a copy of the given string … … 298 297 * size has to be negotiated in advance. 299 298 * 300 * @param[in] phone The other module phone.299 * @param[in] exch Exchange. 301 300 * @param[out] strings The returned measured strings array. 302 301 * @param[out] data The measured strings data. This memory block stores the … … 305 304 * @return EOK on success. 306 305 * @return EINVAL if the strings or data parameter is NULL. 307 * @return EINVAL if the phone or count parameter is not positive.306 * @return EINVAL if the exch or count parameter is invalid. 308 307 * @return EINVAL if the sent array differs in size. 309 308 * @return ENOMEM if there is not enough memory left. … … 311 310 * async_data_read_start() function. 312 311 */ 313 int 314 measured_strings_return(int phone, measured_string_t **strings, uint8_t **data, 315 size_t count) 312 int measured_strings_return(async_exch_t *exch, measured_string_t **strings, 313 uint8_t **data, size_t count) 316 314 { 317 315 size_t *lengths; … … 320 318 int rc; 321 319 322 if (( phone < 0) || (!strings) || (!data) || (count <= 0))320 if ((exch == NULL) || (!strings) || (!data) || (count <= 0)) 323 321 return EINVAL; 324 322 … … 327 325 return ENOMEM; 328 326 329 rc = async_ obsolete_data_read_start(phone, lengths,327 rc = async_data_read_start(exch, lengths, 330 328 sizeof(size_t) * (count + 1)); 331 329 if (rc != EOK) { … … 352 350 (*strings)[index].length = lengths[index]; 353 351 if (lengths[index] > 0) { 354 rc = async_ obsolete_data_read_start(phone, next, lengths[index]);352 rc = async_data_read_start(exch, next, lengths[index]); 355 353 if (rc != EOK) { 356 354 free(lengths); … … 376 374 * size has to be negotiated in advance. 377 375 * 378 * @param[in] phone The other module phone.376 * @param[in] exch Exchange. 379 377 * @param[in] strings The measured strings array to be transferred. 380 378 * @param[in] count The measured strings array size. 381 379 * @return EOK on success. 382 380 * @return EINVAL if the strings parameter is NULL. 383 * @return EINVAL if the phone or count parameter is not positive.381 * @return EINVAL if the exch or count parameter is invalid. 384 382 * @return Other error codes as defined for the 385 383 * async_data_write_start() function. 386 384 */ 387 int 388 measured_strings_send(int phone, const measured_string_t *strings, 385 int measured_strings_send(async_exch_t *exch, const measured_string_t *strings, 389 386 size_t count) 390 387 { … … 393 390 int rc; 394 391 395 if (( phone < 0) || (!strings) || (count <= 0))392 if ((exch == NULL) || (!strings) || (count <= 0)) 396 393 return EINVAL; 397 394 … … 400 397 return ENOMEM; 401 398 402 rc = async_ obsolete_data_write_start(phone, lengths,399 rc = async_data_write_start(exch, lengths, 403 400 sizeof(size_t) * (count + 1)); 404 401 if (rc != EOK) { … … 411 408 for (index = 0; index < count; index++) { 412 409 if (strings[index].length > 0) { 413 rc = async_ obsolete_data_write_start(phone, strings[index].value,410 rc = async_data_write_start(exch, strings[index].value, 414 411 strings[index].length); 415 412 if (rc != EOK) … … 423 420 /** @} 424 421 */ 425 -
uspace/lib/c/generic/adt/prodcons.c
rd2c67e7 r8ff0bd2 61 61 fibril_condvar_wait(&pc->cv, &pc->mtx); 62 62 63 link_t *head = pc->list.next;63 link_t *head = list_first(&pc->list); 64 64 list_remove(head); 65 65 -
uspace/lib/c/generic/async.c
rd2c67e7 r8ff0bd2 98 98 #include <ipc/ipc.h> 99 99 #include <async.h> 100 #include "private/async.h" 100 101 #undef LIBC_ASYNC_C_ 101 102 … … 107 108 #include <errno.h> 108 109 #include <sys/time.h> 109 #include < arch/barrier.h>110 #include <libarch/barrier.h> 110 111 #include <bool.h> 111 112 #include <malloc.h> 112 113 #include <mem.h> 113 114 #include <stdlib.h> 114 #include "private/async.h"115 #include <macros.h> 115 116 116 117 #define CLIENT_HASH_TABLE_BUCKETS 32 … … 138 139 link_t link; 139 140 140 sysarg_t in_task_hash;141 task_id_t in_task_id; 141 142 atomic_t refcnt; 142 143 void *data; … … 150 151 link_t link; 151 152 152 /** Incoming client task hash. */153 sysarg_t in_task_hash;153 /** Incoming client task ID. */ 154 task_id_t in_task_id; 154 155 155 156 /** Incoming phone hash. */ … … 160 161 161 162 /** Messages that should be delivered to this fibril. */ 162 li nk_t msg_queue;163 list_t msg_queue; 163 164 164 165 /** Identification of the opening call. */ … … 166 167 /** Call data of the opening call. */ 167 168 ipc_call_t call; 169 /** Local argument or NULL if none. */ 170 void *carg; 168 171 169 172 /** Identification of the closing call. */ … … 171 174 172 175 /** Fibril function that will be used to handle the connection. */ 173 void (*cfibril)(ipc_callid_t, ipc_call_t *);176 async_client_conn_t cfibril; 174 177 } connection_t; 175 178 … … 201 204 } 202 205 203 void *async_get_client_data(void)204 {205 assert(fibril_connection);206 return fibril_connection->client->data;207 }208 209 206 /** Default fibril function that gets called to handle new connection. 210 207 * … … 213 210 * @param callid Hash of the incoming call. 214 211 * @param call Data of the incoming call. 215 * 216 */ 217 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call) 212 * @param arg Local argument 213 * 214 */ 215 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call, 216 void *arg) 218 217 { 219 218 ipc_answer_0(callid, ENOENT); … … 226 225 * @param callid Hash of the incoming call. 227 226 * @param call Data of the incoming call. 227 * @param arg Local argument. 228 228 * 229 229 */ … … 233 233 234 234 static async_client_conn_t client_connection = default_client_connection; 235 static async_ client_conn_t interrupt_received = default_interrupt_received;235 static async_interrupt_handler_t interrupt_received = default_interrupt_received; 236 236 237 237 /** Setter for client_connection function pointer. … … 250 250 * notification fibril. 251 251 */ 252 void async_set_interrupt_received(async_ client_conn_t intr)252 void async_set_interrupt_received(async_interrupt_handler_t intr) 253 253 { 254 254 interrupt_received = intr; … … 284 284 { 285 285 assert(key); 286 assert(keys == 2); 286 287 assert(item); 287 288 288 289 client_t *client = hash_table_get_instance(item, client_t, link); 289 return (key[0] == client->in_task_hash); 290 return (key[0] == LOWER32(client->in_task_id) && 291 (key[1] == UPPER32(client->in_task_id))); 290 292 } 291 293 … … 356 358 wd->to_event.inlist = true; 357 359 358 link_t *tmp = timeout_list. next;359 while (tmp != &timeout_list ) {360 link_t *tmp = timeout_list.head.next; 361 while (tmp != &timeout_list.head) { 360 362 awaiter_t *cur 361 363 = list_get_instance(tmp, awaiter_t, to_event.link); … … 367 369 } 368 370 369 list_ append(&wd->to_event.link, tmp);371 list_insert_before(&wd->to_event.link, tmp); 370 372 } 371 373 … … 564 566 } 565 567 566 msg_t *msg = list_get_instance( conn->msg_queue.next, msg_t, link);568 msg_t *msg = list_get_instance(list_first(&conn->msg_queue), msg_t, link); 567 569 list_remove(&msg->link); 568 570 … … 573 575 futex_up(&async_futex); 574 576 return callid; 577 } 578 579 static client_t *async_client_get(task_id_t client_id, bool create) 580 { 581 unsigned long key[2] = { 582 LOWER32(client_id), 583 UPPER32(client_id), 584 }; 585 client_t *client = NULL; 586 587 futex_down(&async_futex); 588 link_t *lnk = hash_table_find(&client_hash_table, key); 589 if (lnk) { 590 client = hash_table_get_instance(lnk, client_t, link); 591 atomic_inc(&client->refcnt); 592 } else if (create) { 593 client = malloc(sizeof(client_t)); 594 if (client) { 595 client->in_task_id = client_id; 596 client->data = async_client_data_create(); 597 598 atomic_set(&client->refcnt, 1); 599 hash_table_insert(&client_hash_table, key, &client->link); 600 } 601 } 602 603 futex_up(&async_futex); 604 return client; 605 } 606 607 static void async_client_put(client_t *client) 608 { 609 bool destroy; 610 unsigned long key[2] = { 611 LOWER32(client->in_task_id), 612 UPPER32(client->in_task_id) 613 }; 614 615 futex_down(&async_futex); 616 617 if (atomic_predec(&client->refcnt) == 0) { 618 hash_table_remove(&client_hash_table, key, 2); 619 destroy = true; 620 } else 621 destroy = false; 622 623 futex_up(&async_futex); 624 625 if (destroy) { 626 if (client->data) 627 async_client_data_destroy(client->data); 628 629 free(client); 630 } 631 } 632 633 void *async_get_client_data(void) 634 { 635 assert(fibril_connection); 636 return fibril_connection->client->data; 637 } 638 639 void *async_get_client_data_by_id(task_id_t client_id) 640 { 641 client_t *client = async_client_get(client_id, false); 642 if (!client) 643 return NULL; 644 if (!client->data) { 645 async_client_put(client); 646 return NULL; 647 } 648 649 return client->data; 650 } 651 652 void async_put_client_data_by_id(task_id_t client_id) 653 { 654 client_t *client = async_client_get(client_id, false); 655 656 assert(client); 657 assert(client->data); 658 659 /* Drop the reference we got in async_get_client_data_by_hash(). */ 660 async_client_put(client); 661 662 /* Drop our own reference we got at the beginning of this function. */ 663 async_client_put(client); 575 664 } 576 665 … … 593 682 */ 594 683 fibril_connection = (connection_t *) arg; 595 596 futex_down(&async_futex);597 684 598 685 /* … … 601 688 * hash in a new tracking structure. 602 689 */ 603 604 unsigned long key = fibril_connection->in_task_hash; 605 link_t *lnk = hash_table_find(&client_hash_table, &key); 606 607 client_t *client; 608 609 if (lnk) { 610 client = hash_table_get_instance(lnk, client_t, link); 611 atomic_inc(&client->refcnt); 612 } else { 613 client = malloc(sizeof(client_t)); 614 if (!client) { 615 ipc_answer_0(fibril_connection->callid, ENOMEM); 616 futex_up(&async_futex); 617 return 0; 618 } 619 620 client->in_task_hash = fibril_connection->in_task_hash; 621 client->data = async_client_data_create(); 622 623 atomic_set(&client->refcnt, 1); 624 hash_table_insert(&client_hash_table, &key, &client->link); 625 } 626 627 futex_up(&async_futex); 628 690 691 client_t *client = async_client_get(fibril_connection->in_task_id, true); 692 if (!client) { 693 ipc_answer_0(fibril_connection->callid, ENOMEM); 694 return 0; 695 } 696 629 697 fibril_connection->client = client; 630 698 … … 633 701 */ 634 702 fibril_connection->cfibril(fibril_connection->callid, 635 &fibril_connection->call );703 &fibril_connection->call, fibril_connection->carg); 636 704 637 705 /* 638 706 * Remove the reference for this client task connection. 639 707 */ 640 bool destroy; 641 642 futex_down(&async_futex); 643 644 if (atomic_predec(&client->refcnt) == 0) { 645 hash_table_remove(&client_hash_table, &key, 1); 646 destroy = true; 647 } else 648 destroy = false; 649 650 futex_up(&async_futex); 651 652 if (destroy) { 653 if (client->data) 654 async_client_data_destroy(client->data); 655 656 free(client); 657 } 708 async_client_put(client); 658 709 659 710 /* … … 661 712 */ 662 713 futex_down(&async_futex); 663 key = fibril_connection->in_phone_hash;714 unsigned long key = fibril_connection->in_phone_hash; 664 715 hash_table_remove(&conn_hash_table, &key, 1); 665 716 futex_up(&async_futex); … … 670 721 while (!list_empty(&fibril_connection->msg_queue)) { 671 722 msg_t *msg = 672 list_get_instance( fibril_connection->msg_queue.next, msg_t,673 link);723 list_get_instance(list_first(&fibril_connection->msg_queue), 724 msg_t, link); 674 725 675 726 list_remove(&msg->link); … … 695 746 * particular fibrils. 696 747 * 697 * @param in_task_ hashIdentification of the incoming connection.748 * @param in_task_id Identification of the incoming connection. 698 749 * @param in_phone_hash Identification of the incoming connection. 699 750 * @param callid Hash of the opening IPC_M_CONNECT_ME_TO call. … … 704 755 * @param cfibril Fibril function that should be called upon opening the 705 756 * connection. 757 * @param carg Extra argument to pass to the connection fibril 706 758 * 707 759 * @return New fibril id or NULL on failure. 708 760 * 709 761 */ 710 fid_t async_new_connection( sysarg_t in_task_hash, sysarg_t in_phone_hash,762 fid_t async_new_connection(task_id_t in_task_id, sysarg_t in_phone_hash, 711 763 ipc_callid_t callid, ipc_call_t *call, 712 async_client_conn_t cfibril )764 async_client_conn_t cfibril, void *carg) 713 765 { 714 766 connection_t *conn = malloc(sizeof(*conn)); … … 720 772 } 721 773 722 conn->in_task_ hash = in_task_hash;774 conn->in_task_id = in_task_id; 723 775 conn->in_phone_hash = in_phone_hash; 724 776 list_initialize(&conn->msg_queue); 725 777 conn->callid = callid; 726 778 conn->close_callid = 0; 779 conn->carg = carg; 727 780 728 781 if (call) … … 778 831 case IPC_M_CONNECT_ME_TO: 779 832 /* Open new connection with fibril, etc. */ 780 async_new_connection(call->in_task_ hash, IPC_GET_ARG5(*call),781 callid, call, client_connection );833 async_new_connection(call->in_task_id, IPC_GET_ARG5(*call), 834 callid, call, client_connection, NULL); 782 835 return; 783 836 } … … 799 852 futex_down(&async_futex); 800 853 801 link_t *cur = timeout_list.next;802 while (cur != &timeout_list) {854 link_t *cur = list_first(&timeout_list); 855 while (cur != NULL) { 803 856 awaiter_t *waiter = 804 857 list_get_instance(cur, awaiter_t, to_event.link); … … 806 859 if (tv_gt(&waiter->to_event.expires, &tv)) 807 860 break; 808 809 cur = cur->next;810 861 811 862 list_remove(&waiter->to_event.link); … … 821 872 fibril_add_ready(waiter->fid); 822 873 } 874 875 cur = list_first(&timeout_list); 823 876 } 824 877 … … 847 900 suseconds_t timeout; 848 901 if (!list_empty(&timeout_list)) { 849 awaiter_t *waiter = list_get_instance( timeout_list.next,850 awaiter_t, to_event.link);902 awaiter_t *waiter = list_get_instance( 903 list_first(&timeout_list), awaiter_t, to_event.link); 851 904 852 905 struct timeval tv; … … 926 979 { 927 980 if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 928 1, &client_hash_table_ops))981 2, &client_hash_table_ops)) 929 982 abort(); 930 983 … … 942 995 session_ns->arg2 = 0; 943 996 session_ns->arg3 = 0; 997 998 fibril_mutex_initialize(&session_ns->remote_state_mtx); 999 session_ns->remote_state_data = NULL; 944 1000 945 1001 list_initialize(&session_ns->exch_list); … … 1414 1470 */ 1415 1471 int async_connect_to_me(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2, 1416 sysarg_t arg3, async_client_conn_t client_receiver )1472 sysarg_t arg3, async_client_conn_t client_receiver, void *carg) 1417 1473 { 1418 1474 if (exch == NULL) 1419 1475 return ENOENT; 1420 1476 1421 sysarg_t task_hash;1422 1477 sysarg_t phone_hash; 1423 int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 1424 NULL, NULL, NULL, &task_hash, &phone_hash); 1478 sysarg_t rc; 1479 1480 aid_t req; 1481 ipc_call_t answer; 1482 req = async_send_3(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 1483 &answer); 1484 async_wait_for(req, &rc); 1425 1485 if (rc != EOK) 1426 return rc; 1427 1486 return (int) rc; 1487 1488 phone_hash = IPC_GET_ARG5(answer); 1489 1428 1490 if (client_receiver != NULL) 1429 async_new_connection( task_hash, phone_hash, 0, NULL,1430 client_receiver );1491 async_new_connection(answer.in_task_id, phone_hash, 0, NULL, 1492 client_receiver, carg); 1431 1493 1432 1494 return EOK; … … 1502 1564 sess->arg3 = 0; 1503 1565 1566 fibril_mutex_initialize(&sess->remote_state_mtx); 1567 sess->remote_state_data = NULL; 1568 1504 1569 list_initialize(&sess->exch_list); 1505 1570 fibril_mutex_initialize(&sess->mutex); … … 1583 1648 sess->arg3 = arg3; 1584 1649 1650 fibril_mutex_initialize(&sess->remote_state_mtx); 1651 sess->remote_state_data = NULL; 1652 1585 1653 list_initialize(&sess->exch_list); 1586 1654 fibril_mutex_initialize(&sess->mutex); … … 1588 1656 1589 1657 return sess; 1658 } 1659 1660 /** Set arguments for new connections. 1661 * 1662 * FIXME This is an ugly hack to work around the problem that parallel 1663 * exchanges are implemented using parallel connections. When we create 1664 * a callback session, the framework does not know arguments for the new 1665 * connections. 1666 * 1667 * The proper solution seems to be to implement parallel exchanges using 1668 * tagging. 1669 */ 1670 void async_sess_args_set(async_sess_t *sess, sysarg_t arg1, sysarg_t arg2, 1671 sysarg_t arg3) 1672 { 1673 sess->arg1 = arg1; 1674 sess->arg2 = arg2; 1675 sess->arg3 = arg3; 1590 1676 } 1591 1677 … … 1633 1719 sess->arg3 = arg3; 1634 1720 1721 fibril_mutex_initialize(&sess->remote_state_mtx); 1722 sess->remote_state_data = NULL; 1723 1635 1724 list_initialize(&sess->exch_list); 1636 1725 fibril_mutex_initialize(&sess->mutex); … … 1664 1753 sess->arg3 = 0; 1665 1754 1755 fibril_mutex_initialize(&sess->remote_state_mtx); 1756 sess->remote_state_data = NULL; 1757 1666 1758 list_initialize(&sess->exch_list); 1667 1759 fibril_mutex_initialize(&sess->mutex); … … 1685 1777 int async_hangup(async_sess_t *sess) 1686 1778 { 1779 async_exch_t *exch; 1780 1687 1781 assert(sess); 1688 1782 1689 1783 if (atomic_get(&sess->refcnt) > 0) 1690 1784 return EBUSY; 1785 1786 fibril_mutex_lock(&async_sess_mutex); 1691 1787 1692 1788 int rc = async_hangup_internal(sess->phone); 1693 1789 if (rc == EOK) 1694 1790 free(sess); 1791 1792 while (!list_empty(&sess->exch_list)) { 1793 exch = (async_exch_t *) 1794 list_get_instance(list_first(&sess->exch_list), 1795 async_exch_t, sess_link); 1796 1797 list_remove(&exch->sess_link); 1798 list_remove(&exch->global_link); 1799 async_hangup_internal(exch->phone); 1800 free(exch); 1801 } 1802 1803 fibril_mutex_unlock(&async_sess_mutex); 1695 1804 1696 1805 return rc; … … 1724 1833 */ 1725 1834 exch = (async_exch_t *) 1726 list_get_instance(sess->exch_list.next, async_exch_t, sess_link); 1835 list_get_instance(list_first(&sess->exch_list), 1836 async_exch_t, sess_link); 1837 1727 1838 list_remove(&exch->sess_link); 1728 1839 list_remove(&exch->global_link); … … 1736 1847 exch = (async_exch_t *) malloc(sizeof(async_exch_t)); 1737 1848 if (exch != NULL) { 1738 li st_initialize(&exch->sess_link);1739 li st_initialize(&exch->global_link);1849 link_initialize(&exch->sess_link); 1850 link_initialize(&exch->global_link); 1740 1851 exch->sess = sess; 1741 1852 exch->phone = sess->phone; … … 1754 1865 exch = (async_exch_t *) malloc(sizeof(async_exch_t)); 1755 1866 if (exch != NULL) { 1756 li st_initialize(&exch->sess_link);1757 li st_initialize(&exch->global_link);1867 link_initialize(&exch->sess_link); 1868 link_initialize(&exch->global_link); 1758 1869 exch->sess = sess; 1759 1870 exch->phone = phone; … … 1767 1878 */ 1768 1879 exch = (async_exch_t *) 1769 list_get_instance(inactive_exch_list.next, async_exch_t, 1770 global_link); 1880 list_get_instance(list_first(&inactive_exch_list), 1881 async_exch_t, global_link); 1882 1771 1883 list_remove(&exch->sess_link); 1772 1884 list_remove(&exch->global_link); … … 1808 1920 async_sess_t *sess = exch->sess; 1809 1921 1922 atomic_dec(&sess->refcnt); 1923 1810 1924 if (sess->mgmt == EXCHANGE_SERIALIZE) 1811 1925 fibril_mutex_unlock(&sess->mutex); … … 2322 2436 sess->arg3 = 0; 2323 2437 2438 fibril_mutex_initialize(&sess->remote_state_mtx); 2439 sess->remote_state_data = NULL; 2440 2324 2441 list_initialize(&sess->exch_list); 2325 2442 fibril_mutex_initialize(&sess->mutex); … … 2368 2485 sess->arg3 = 0; 2369 2486 2487 fibril_mutex_initialize(&sess->remote_state_mtx); 2488 sess->remote_state_data = NULL; 2489 2370 2490 list_initialize(&sess->exch_list); 2371 2491 fibril_mutex_initialize(&sess->mutex); … … 2410 2530 sess->arg3 = 0; 2411 2531 2532 fibril_mutex_initialize(&sess->remote_state_mtx); 2533 sess->remote_state_data = NULL; 2534 2412 2535 list_initialize(&sess->exch_list); 2413 2536 fibril_mutex_initialize(&sess->mutex); … … 2417 2540 } 2418 2541 2542 int async_state_change_start(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2, 2543 sysarg_t arg3, async_exch_t *other_exch) 2544 { 2545 return async_req_5_0(exch, IPC_M_STATE_CHANGE_AUTHORIZE, 2546 arg1, arg2, arg3, 0, other_exch->phone); 2547 } 2548 2549 bool async_state_change_receive(ipc_callid_t *callid, sysarg_t *arg1, 2550 sysarg_t *arg2, sysarg_t *arg3) 2551 { 2552 assert(callid); 2553 2554 ipc_call_t call; 2555 *callid = async_get_call(&call); 2556 2557 if (IPC_GET_IMETHOD(call) != IPC_M_STATE_CHANGE_AUTHORIZE) 2558 return false; 2559 2560 if (arg1) 2561 *arg1 = IPC_GET_ARG1(call); 2562 if (arg2) 2563 *arg2 = IPC_GET_ARG2(call); 2564 if (arg3) 2565 *arg3 = IPC_GET_ARG3(call); 2566 2567 return true; 2568 } 2569 2570 int async_state_change_finalize(ipc_callid_t callid, async_exch_t *other_exch) 2571 { 2572 return ipc_answer_1(callid, EOK, other_exch->phone); 2573 } 2574 2575 /** Lock and get session remote state 2576 * 2577 * Lock and get the local replica of the remote state 2578 * in stateful sessions. The call should be paired 2579 * with async_remote_state_release*(). 2580 * 2581 * @param[in] sess Stateful session. 2582 * 2583 * @return Local replica of the remote state. 2584 * 2585 */ 2586 void *async_remote_state_acquire(async_sess_t *sess) 2587 { 2588 fibril_mutex_lock(&sess->remote_state_mtx); 2589 return sess->remote_state_data; 2590 } 2591 2592 /** Update the session remote state 2593 * 2594 * Update the local replica of the remote state 2595 * in stateful sessions. The remote state must 2596 * be already locked. 2597 * 2598 * @param[in] sess Stateful session. 2599 * @param[in] state New local replica of the remote state. 2600 * 2601 */ 2602 void async_remote_state_update(async_sess_t *sess, void *state) 2603 { 2604 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 2605 sess->remote_state_data = state; 2606 } 2607 2608 /** Release the session remote state 2609 * 2610 * Unlock the local replica of the remote state 2611 * in stateful sessions. 2612 * 2613 * @param[in] sess Stateful session. 2614 * 2615 */ 2616 void async_remote_state_release(async_sess_t *sess) 2617 { 2618 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 2619 2620 fibril_mutex_unlock(&sess->remote_state_mtx); 2621 } 2622 2623 /** Release the session remote state and end an exchange 2624 * 2625 * Unlock the local replica of the remote state 2626 * in stateful sessions. This is convenience function 2627 * which gets the session pointer from the exchange 2628 * and also ends the exchange. 2629 * 2630 * @param[in] exch Stateful session's exchange. 2631 * 2632 */ 2633 void async_remote_state_release_exchange(async_exch_t *exch) 2634 { 2635 if (exch == NULL) 2636 return; 2637 2638 async_sess_t *sess = exch->sess; 2639 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 2640 2641 async_exchange_end(exch); 2642 fibril_mutex_unlock(&sess->remote_state_mtx); 2643 } 2644 2419 2645 /** @} 2420 2646 */ -
uspace/lib/c/generic/async_obsolete.c
rd2c67e7 r8ff0bd2 38 38 #include <async.h> 39 39 #include <async_obsolete.h> 40 #include "private/async.h" 40 41 #undef LIBC_ASYNC_C_ 41 42 #undef LIBC_ASYNC_OBSOLETE_C_ … … 44 45 #include <malloc.h> 45 46 #include <errno.h> 46 #include "private/async.h"47 47 48 48 /** Send message and return id of the sent message. … … 166 166 } 167 167 168 void async_obsolete_serialize_start(void)169 {170 fibril_inc_sercount();171 }172 173 void async_obsolete_serialize_end(void)174 {175 fibril_dec_sercount();176 }177 178 168 /** Wrapper for IPC_M_DATA_WRITE calls using the async framework. 179 169 * … … 240 230 */ 241 231 int async_obsolete_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2, 242 sysarg_t arg3, async_client_conn_t client_receiver )232 sysarg_t arg3, async_client_conn_t client_receiver, void *carg) 243 233 { 244 234 sysarg_t task_hash; … … 251 241 if (client_receiver != NULL) 252 242 async_new_connection(task_hash, phone_hash, 0, NULL, 253 client_receiver );243 client_receiver, carg); 254 244 255 245 return EOK; -
uspace/lib/c/generic/ddi.c
rd2c67e7 r8ff0bd2 31 31 */ 32 32 /** @file 33 */ 33 */ 34 34 35 #include <sys/types.h> 36 #include <abi/ddi/arg.h> 35 37 #include <ddi.h> 36 38 #include <libarch/ddi.h> … … 40 42 #include <align.h> 41 43 #include <libarch/config.h> 42 #include <kernel/ddi/ddi_arg.h>43 44 44 45 /** Return unique device number. -
uspace/lib/c/generic/devman.c
rd2c67e7 r8ff0bd2 1 1 /* 2 2 * Copyright (c) 2007 Josef Cejka 3 * Copyright (c) 20 09Jiri Svoboda3 * Copyright (c) 2011 Jiri Svoboda 4 4 * Copyright (c) 2010 Lenka Trochtova 5 5 * All rights reserved. … … 35 35 */ 36 36 37 #include <adt/list.h> 37 38 #include <str.h> 38 39 #include <ipc/services.h> … … 88 89 if (devman_driver_block_sess == NULL) 89 90 devman_driver_block_sess = 90 service_connect_blocking(EXCHANGE_ SERIALIZE,91 service_connect_blocking(EXCHANGE_PARALLEL, 91 92 SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 92 93 } … … 137 138 if (devman_driver_sess == NULL) 138 139 devman_driver_sess = 139 service_connect(EXCHANGE_ SERIALIZE, SERVICE_DEVMAN,140 service_connect(EXCHANGE_PARALLEL, SERVICE_DEVMAN, 140 141 DEVMAN_DRIVER, 0); 141 142 … … 194 195 195 196 exch = devman_exchange_begin(DEVMAN_DRIVER); 196 async_connect_to_me(exch, 0, 0, 0, NULL);197 async_connect_to_me(exch, 0, 0, 0, conn, NULL); 197 198 devman_exchange_end(exch); 198 199 … … 231 232 } 232 233 233 link_t *link = match_ids->ids.next;234 234 match_id_t *match_id = NULL; 235 235 236 while (link != &match_ids->ids) {236 list_foreach(match_ids->ids, link) { 237 237 match_id = list_get_instance(link, match_id_t, link); 238 238 … … 255 255 return retval; 256 256 } 257 258 link = link->next;259 257 } 260 258 … … 273 271 } 274 272 275 int devman_add_device_to_c lass(devman_handle_t devman_handle,276 const char *c lass_name)273 int devman_add_device_to_category(devman_handle_t devman_handle, 274 const char *cat_name) 277 275 { 278 276 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 279 277 280 278 ipc_call_t answer; 281 aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_C LASS,279 aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CATEGORY, 282 280 devman_handle, &answer); 283 sysarg_t retval = async_data_write_start(exch, c lass_name,284 str_size(c lass_name));281 sysarg_t retval = async_data_write_start(exch, cat_name, 282 str_size(cat_name)); 285 283 286 284 devman_exchange_end(exch); … … 310 308 } 311 309 310 /** Remove function from device. 311 * 312 * Request devman to remove function owned by this driver task. 313 * @param funh Devman handle of the function 314 * 315 * @return EOK on success or negative error code. 316 */ 317 int devman_remove_function(devman_handle_t funh) 318 { 319 async_exch_t *exch; 320 sysarg_t retval; 321 322 exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 323 retval = async_req_1_0(exch, DEVMAN_REMOVE_FUNCTION, (sysarg_t) funh); 324 devman_exchange_end(exch); 325 326 return (int) retval; 327 } 328 329 int devman_drv_fun_online(devman_handle_t funh) 330 { 331 async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER); 332 if (exch == NULL) 333 return ENOMEM; 334 335 sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_ONLINE, funh); 336 337 devman_exchange_end(exch); 338 return (int) retval; 339 } 340 341 int devman_drv_fun_offline(devman_handle_t funh) 342 { 343 async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER); 344 if (exch == NULL) 345 return ENOMEM; 346 347 sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_OFFLINE, funh); 348 349 devman_exchange_end(exch); 350 return (int) retval; 351 } 352 312 353 async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt, 313 354 devman_handle_t handle, unsigned int flags) … … 325 366 } 326 367 327 int devman_ device_get_handle(const char *pathname, devman_handle_t *handle,368 int devman_fun_get_handle(const char *pathname, devman_handle_t *handle, 328 369 unsigned int flags) 329 370 { … … 335 376 exch = devman_exchange_begin(DEVMAN_CLIENT); 336 377 if (exch == NULL) 337 return errno;378 return ENOMEM; 338 379 } 339 380 … … 366 407 } 367 408 368 int devman_device_get_handle_by_class(const char *classname,369 const char *devname, devman_handle_t *handle, unsigned int flags)409 static int devman_get_str_internal(sysarg_t method, sysarg_t arg1, char *buf, 410 size_t buf_size) 370 411 { 371 412 async_exch_t *exch; 372 373 if (flags & IPC_FLAG_BLOCKING) 374 exch = devman_exchange_begin_blocking(DEVMAN_CLIENT); 375 else { 376 exch = devman_exchange_begin(DEVMAN_CLIENT); 377 if (exch == NULL) 378 return errno; 379 } 413 ipc_call_t dreply; 414 size_t act_size; 415 sysarg_t dretval; 416 417 exch = devman_exchange_begin_blocking(LOC_PORT_CONSUMER); 380 418 381 419 ipc_call_t answer; 382 aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,383 flags, &answer);384 sysarg_t retval = async_data_write_start(exch, classname,385 str_size(classname));386 387 if (retval != EOK) {388 devman_exchange_end(exch);420 aid_t req = async_send_1(exch, method, arg1, &answer); 421 aid_t dreq = async_data_read(exch, buf, buf_size - 1, &dreply); 422 async_wait_for(dreq, &dretval); 423 424 devman_exchange_end(exch); 425 426 if (dretval != EOK) { 389 427 async_wait_for(req, NULL); 390 return retval; 391 } 392 393 retval = async_data_write_start(exch, devname, 394 str_size(devname)); 395 396 devman_exchange_end(exch); 397 398 if (retval != EOK) { 399 async_wait_for(req, NULL); 400 return retval; 401 } 402 428 return dretval; 429 } 430 431 sysarg_t retval; 403 432 async_wait_for(req, &retval); 404 433 405 if (retval != EOK) { 406 if (handle != NULL) 407 *handle = (devman_handle_t) -1; 408 409 return retval; 410 } 411 412 if (handle != NULL) 413 *handle = (devman_handle_t) IPC_GET_ARG1(answer); 414 415 return retval; 416 } 417 418 int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size) 434 if (retval != EOK) 435 return retval; 436 437 act_size = IPC_GET_ARG2(dreply); 438 assert(act_size <= buf_size - 1); 439 buf[act_size] = '\0'; 440 441 return EOK; 442 } 443 444 int devman_fun_get_path(devman_handle_t handle, char *buf, size_t buf_size) 445 { 446 return devman_get_str_internal(DEVMAN_FUN_GET_PATH, handle, buf, 447 buf_size); 448 } 449 450 int devman_fun_get_name(devman_handle_t handle, char *buf, size_t buf_size) 451 { 452 return devman_get_str_internal(DEVMAN_FUN_GET_NAME, handle, buf, 453 buf_size); 454 } 455 456 int devman_fun_online(devman_handle_t funh) 419 457 { 420 458 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 421 459 if (exch == NULL) 422 return errno; 423 460 return ENOMEM; 461 462 sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_ONLINE, funh); 463 464 devman_exchange_end(exch); 465 return (int) retval; 466 } 467 468 int devman_fun_offline(devman_handle_t funh) 469 { 470 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 471 if (exch == NULL) 472 return ENOMEM; 473 474 sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_OFFLINE, funh); 475 476 devman_exchange_end(exch); 477 return (int) retval; 478 } 479 480 static int devman_get_handles_once(sysarg_t method, sysarg_t arg1, 481 devman_handle_t *handle_buf, size_t buf_size, size_t *act_size) 482 { 483 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_CLIENT); 484 424 485 ipc_call_t answer; 425 aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_DEVICE_PATH, 426 handle, &answer); 427 428 ipc_call_t data_request_call; 429 aid_t data_request = async_data_read(exch, path, path_size, 430 &data_request_call); 431 432 devman_exchange_end(exch); 433 434 if (data_request == 0) { 486 aid_t req = async_send_1(exch, method, arg1, &answer); 487 int rc = async_data_read_start(exch, handle_buf, buf_size); 488 489 devman_exchange_end(exch); 490 491 if (rc != EOK) { 435 492 async_wait_for(req, NULL); 436 return ENOMEM; 437 } 438 439 sysarg_t data_request_rc; 440 async_wait_for(data_request, &data_request_rc); 441 442 sysarg_t opening_request_rc; 443 async_wait_for(req, &opening_request_rc); 444 445 if (data_request_rc != EOK) { 446 /* Prefer the return code of the opening request. */ 447 if (opening_request_rc != EOK) 448 return (int) opening_request_rc; 449 else 450 return (int) data_request_rc; 451 } 452 453 if (opening_request_rc != EOK) 454 return (int) opening_request_rc; 455 456 /* To be on the safe-side. */ 457 path[path_size - 1] = 0; 458 size_t transferred_size = IPC_GET_ARG2(data_request_call); 459 if (transferred_size >= path_size) 460 return ELIMIT; 461 462 /* Terminate the string (trailing 0 not send over IPC). */ 463 path[transferred_size] = 0; 493 return rc; 494 } 495 496 sysarg_t retval; 497 async_wait_for(req, &retval); 498 499 if (retval != EOK) { 500 return retval; 501 } 502 503 *act_size = IPC_GET_ARG1(answer); 464 504 return EOK; 465 505 } 466 506 507 /** Get list of handles. 508 * 509 * Returns an allocated array of handles. 510 * 511 * @param method IPC method 512 * @param arg1 IPC argument 1 513 * @param data Place to store pointer to array of handles 514 * @param count Place to store number of handles 515 * @return EOK on success or negative error code 516 */ 517 static int devman_get_handles_internal(sysarg_t method, sysarg_t arg1, 518 devman_handle_t **data, size_t *count) 519 { 520 devman_handle_t *handles; 521 size_t act_size; 522 size_t alloc_size; 523 int rc; 524 525 *data = NULL; 526 act_size = 0; /* silence warning */ 527 528 rc = devman_get_handles_once(method, arg1, NULL, 0, 529 &act_size); 530 if (rc != EOK) 531 return rc; 532 533 alloc_size = act_size; 534 handles = malloc(alloc_size); 535 if (handles == NULL) 536 return ENOMEM; 537 538 while (true) { 539 rc = devman_get_handles_once(method, arg1, handles, alloc_size, 540 &act_size); 541 if (rc != EOK) 542 return rc; 543 544 if (act_size <= alloc_size) 545 break; 546 547 alloc_size *= 2; 548 free(handles); 549 550 handles = malloc(alloc_size); 551 if (handles == NULL) 552 return ENOMEM; 553 } 554 555 *count = act_size / sizeof(devman_handle_t); 556 *data = handles; 557 return EOK; 558 } 559 560 int devman_fun_get_child(devman_handle_t funh, devman_handle_t *devh) 561 { 562 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 563 if (exch == NULL) 564 return ENOMEM; 565 566 sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_GET_CHILD, 567 funh, devh); 568 569 devman_exchange_end(exch); 570 return (int) retval; 571 } 572 573 int devman_dev_get_functions(devman_handle_t devh, devman_handle_t **funcs, 574 size_t *count) 575 { 576 return devman_get_handles_internal(DEVMAN_DEV_GET_FUNCTIONS, 577 devh, funcs, count); 578 } 579 580 int devman_fun_sid_to_handle(service_id_t sid, devman_handle_t *handle) 581 { 582 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 583 if (exch == NULL) 584 return ENOMEM; 585 586 sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_SID_TO_HANDLE, 587 sid, handle); 588 589 devman_exchange_end(exch); 590 return (int) retval; 591 } 592 467 593 /** @} 468 594 */ -
uspace/lib/c/generic/elf/elf_load.c
rd2c67e7 r8ff0bd2 29 29 */ 30 30 31 /** @addtogroup generic 31 /** @addtogroup generic 32 32 * @{ 33 33 */ … … 49 49 #include <assert.h> 50 50 #include <as.h> 51 #include <elf/elf.h> 51 52 #include <unistd.h> 52 53 #include <fcntl.h> … … 55 56 #include <entry_point.h> 56 57 57 #include "elf.h" 58 #include "elf_load.h" 58 #include <elf/elf_load.h> 59 59 60 60 #define DPRINTF(...) … … 74 74 static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry); 75 75 76 /** Read until the buffer is read in its entirety. */77 static int my_read(int fd, void *buf, size_t len)78 {79 int cnt = 0;80 do {81 buf += cnt;82 len -= cnt;83 cnt = read(fd, buf, len);84 } while ((cnt > 0) && ((len - cnt) > 0));85 86 return cnt;87 }88 89 76 /** Load ELF binary from a file. 90 77 * … … 160 147 int i, rc; 161 148 162 rc = my_read(elf->fd, header, sizeof(elf_header_t));163 if (rc < 0) {149 rc = read_all(elf->fd, header, sizeof(elf_header_t)); 150 if (rc != sizeof(elf_header_t)) { 164 151 DPRINTF("Read error.\n"); 165 152 return EE_INVALID; … … 222 209 + i * sizeof(elf_segment_header_t), SEEK_SET); 223 210 224 rc = my_read(elf->fd, &segment_hdr,211 rc = read_all(elf->fd, &segment_hdr, 225 212 sizeof(elf_segment_header_t)); 226 if (rc < 0) {213 if (rc != sizeof(elf_segment_header_t)) { 227 214 DPRINTF("Read error.\n"); 228 215 return EE_INVALID; … … 244 231 + i * sizeof(elf_section_header_t), SEEK_SET); 245 232 246 rc = my_read(elf->fd, §ion_hdr,233 rc = read_all(elf->fd, §ion_hdr, 247 234 sizeof(elf_section_header_t)); 248 if (rc < 0) {235 if (rc != sizeof(elf_section_header_t)) { 249 236 DPRINTF("Read error.\n"); 250 237 return EE_INVALID; … … 334 321 uintptr_t seg_addr; 335 322 size_t mem_sz; 336 int rc;323 ssize_t rc; 337 324 338 325 bias = elf->bias; … … 412 399 if (now > left) now = left; 413 400 414 rc = my_read(elf->fd, dp, now);415 416 if (rc < 0) {401 rc = read_all(elf->fd, dp, now); 402 403 if (rc != (ssize_t) now) { 417 404 DPRINTF("Read error.\n"); 418 405 return EE_INVALID; -
uspace/lib/c/generic/event.c
rd2c67e7 r8ff0bd2 39 39 #include <libc.h> 40 40 #include <event.h> 41 #include <kernel/ipc/event_types.h>42 41 43 42 /** Subscribe event notifications. … … 50 49 */ 51 50 int event_subscribe(event_type_t evno, sysarg_t imethod) 51 { 52 return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno, 53 (sysarg_t) imethod); 54 } 55 56 int event_task_subscribe(event_task_type_t evno, sysarg_t imethod) 52 57 { 53 58 return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno, … … 67 72 } 68 73 74 int event_task_unmask(event_task_type_t evno) 75 { 76 return __SYSCALL1(SYS_EVENT_UNMASK, (sysarg_t) evno); 77 } 78 69 79 /** @} 70 80 */ -
uspace/lib/c/generic/fibril.c
rd2c67e7 r8ff0bd2 41 41 #include <unistd.h> 42 42 #include <stdio.h> 43 #include < arch/barrier.h>43 #include <libarch/barrier.h> 44 44 #include <libarch/faddr.h> 45 45 #include <futex.h> … … 222 222 fibril_t *dstf; 223 223 if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) { 224 dstf = list_get_instance(manager_list.next, fibril_t, link); 224 dstf = list_get_instance(list_first(&manager_list), fibril_t, 225 link); 225 226 if (serialization_count && stype == FIBRIL_TO_MANAGER) { 226 227 serialized_threads++; … … 233 234 } else { 234 235 if (!list_empty(&serialized_list)) { 235 dstf = list_get_instance( serialized_list.next, fibril_t,236 link);236 dstf = list_get_instance(list_first(&serialized_list), 237 fibril_t, link); 237 238 serialized_threads--; 238 239 } else { 239 dstf = list_get_instance( ready_list.next, fibril_t,240 link);240 dstf = list_get_instance(list_first(&ready_list), 241 fibril_t, link); 241 242 } 242 243 } … … 326 327 327 328 if (!list_empty(&manager_list)) 328 list_remove( manager_list.next);329 list_remove(list_first(&manager_list)); 329 330 330 331 futex_up(&fibril_futex); -
uspace/lib/c/generic/fibril_synch.c
rd2c67e7 r8ff0bd2 148 148 fibril_t *f; 149 149 150 assert(!list_empty(&fm->waiters));151 tmp = fm->waiters.next;150 tmp = list_first(&fm->waiters); 151 assert(tmp != NULL); 152 152 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 153 153 wdp->active = true; … … 279 279 280 280 while (!list_empty(&frw->waiters)) { 281 link_t *tmp = frw->waiters.next;281 link_t *tmp = list_first(&frw->waiters); 282 282 awaiter_t *wdp; 283 283 fibril_t *f; … … 422 422 futex_down(&async_futex); 423 423 while (!list_empty(&fcv->waiters)) { 424 tmp = fcv->waiters.next;424 tmp = list_first(&fcv->waiters); 425 425 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 426 426 list_remove(&wdp->wu_event.link); -
uspace/lib/c/generic/io/console.c
rd2c67e7 r8ff0bd2 76 76 bool console_kcon(void) 77 77 { 78 #if 079 78 return __SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE); 80 #endif81 82 return false;83 79 } 84 80 -
uspace/lib/c/generic/io/io.c
rd2c67e7 r8ff0bd2 45 45 #include <vfs/vfs.h> 46 46 #include <vfs/vfs_sess.h> 47 #include <ipc/ devmap.h>47 #include <ipc/loc.h> 48 48 #include <adt/list.h> 49 49 #include "../private/io.h" … … 101 101 static LIST_INITIALIZE(files); 102 102 103 void __stdio_init(int filc , fdi_node_t *filv[])103 void __stdio_init(int filc) 104 104 { 105 105 if (filc > 0) { 106 stdin = f open_node(filv[0], "r");106 stdin = fdopen(0, "r"); 107 107 } else { 108 108 stdin = &stdin_null; … … 111 111 112 112 if (filc > 1) { 113 stdout = f open_node(filv[1], "w");113 stdout = fdopen(1, "w"); 114 114 } else { 115 115 stdout = &stdout_klog; … … 118 118 119 119 if (filc > 2) { 120 stderr = f open_node(filv[2], "w");120 stderr = fdopen(2, "w"); 121 121 } else { 122 122 stderr = &stderr_klog; … … 127 127 void __stdio_done(void) 128 128 { 129 link_t *link = files.next; 130 131 while (link != &files) { 132 FILE *file = list_get_instance(link, FILE, link); 129 while (!list_empty(&files)) { 130 FILE *file = list_get_instance(list_first(&files), FILE, link); 133 131 fclose(file); 134 link = files.next;135 132 } 136 133 } … … 288 285 } 289 286 290 FILE *fopen_node(fdi_node_t *node, const char *mode)291 {292 int flags;293 if (!parse_mode(mode, &flags))294 return NULL;295 296 /* Open file. */297 FILE *stream = malloc(sizeof(FILE));298 if (stream == NULL) {299 errno = ENOMEM;300 return NULL;301 }302 303 stream->fd = open_node(node, flags);304 if (stream->fd < 0) {305 /* errno was set by open_node() */306 free(stream);307 return NULL;308 }309 310 stream->error = false;311 stream->eof = false;312 stream->klog = false;313 stream->sess = NULL;314 stream->need_sync = false;315 _setvbuf(stream);316 317 list_append(&stream->link, &files);318 319 return stream;320 }321 322 287 int fclose(FILE *stream) 323 288 { … … 597 562 } 598 563 599 buf+= now;564 data += now; 600 565 stream->buf_head += now; 601 566 buf_free -= now; 602 567 bytes_left -= now; 603 568 total_written += now; 569 stream->buf_state = _bs_write; 604 570 605 571 if (buf_free == 0) { … … 609 575 } 610 576 } 611 612 if (total_written > 0)613 stream->buf_state = _bs_write;614 577 615 578 if (need_flush) … … 717 680 off64_t ftell(FILE *stream) 718 681 { 682 _fflushbuf(stream); 719 683 return lseek(stream->fd, 0, SEEK_CUR); 720 684 } … … 784 748 } 785 749 786 int fnode(FILE *stream, fdi_node_t *node) 787 { 788 if (stream->fd >= 0) 789 return fd_node(stream->fd, node); 750 int fhandle(FILE *stream, int *handle) 751 { 752 if (stream->fd >= 0) { 753 *handle = stream->fd; 754 return EOK; 755 } 790 756 791 757 return ENOENT; -
uspace/lib/c/generic/io/printf_core.c
rd2c67e7 r8ff0bd2 74 74 #define PRINT_NUMBER_BUFFER_SIZE (64 + 5) 75 75 76 /** Get signed or unsigned integer argument */ 77 #define PRINTF_GET_INT_ARGUMENT(type, ap, flags) \ 78 ({ \ 79 unsigned type res; \ 80 \ 81 if ((flags) & __PRINTF_FLAG_SIGNED) { \ 82 signed type arg = va_arg((ap), signed type); \ 83 \ 84 if (arg < 0) { \ 85 res = -arg; \ 86 (flags) |= __PRINTF_FLAG_NEGATIVE; \ 87 } else \ 88 res = arg; \ 89 } else \ 90 res = va_arg((ap), unsigned type); \ 91 \ 92 res; \ 93 }) 94 76 95 /** Enumeration of possible arguments types. 77 96 */ … … 206 225 } 207 226 208 return (int) (counter + 1);227 return (int) (counter); 209 228 } 210 229 … … 244 263 } 245 264 246 return (int) (counter + 1);265 return (int) (counter); 247 266 } 248 267 … … 831 850 size_t size; 832 851 uint64_t number; 852 833 853 switch (qualifier) { 834 854 case PrintfQualifierByte: 835 855 size = sizeof(unsigned char); 836 number = (uint64_t) va_arg(ap, unsigned int);856 number = PRINTF_GET_INT_ARGUMENT(int, ap, flags); 837 857 break; 838 858 case PrintfQualifierShort: 839 859 size = sizeof(unsigned short); 840 number = (uint64_t) va_arg(ap, unsigned int);860 number = PRINTF_GET_INT_ARGUMENT(int, ap, flags); 841 861 break; 842 862 case PrintfQualifierInt: 843 863 size = sizeof(unsigned int); 844 number = (uint64_t) va_arg(ap, unsigned int);864 number = PRINTF_GET_INT_ARGUMENT(int, ap, flags); 845 865 break; 846 866 case PrintfQualifierLong: 847 867 size = sizeof(unsigned long); 848 number = (uint64_t) va_arg(ap, unsigned long);868 number = PRINTF_GET_INT_ARGUMENT(long, ap, flags); 849 869 break; 850 870 case PrintfQualifierLongLong: 851 871 size = sizeof(unsigned long long); 852 number = (uint64_t) va_arg(ap, unsigned long long);872 number = PRINTF_GET_INT_ARGUMENT(long long, ap, flags); 853 873 break; 854 874 case PrintfQualifierPointer: … … 865 885 counter = -counter; 866 886 goto out; 867 }868 869 if (flags & __PRINTF_FLAG_SIGNED) {870 if (number & (0x1 << (size * 8 - 1))) {871 flags |= __PRINTF_FLAG_NEGATIVE;872 873 if (size == sizeof(uint64_t)) {874 number = -((int64_t) number);875 } else {876 number = ~number;877 number &=878 ~(0xFFFFFFFFFFFFFFFFll <<879 (size * 8));880 number++;881 }882 }883 887 } 884 888 -
uspace/lib/c/generic/ipc.c
rd2c67e7 r8ff0bd2 47 47 #include <futex.h> 48 48 #include <fibril.h> 49 #include <macros.h> 49 50 50 51 /** … … 458 459 while (!list_empty(&queued_calls)) { 459 460 async_call_t *call = 460 list_get_instance( queued_calls.next, async_call_t, list);461 list_get_instance(list_first(&queued_calls), async_call_t, list); 461 462 ipc_callid_t callid = 462 463 ipc_call_async_internal(call->u.msg.phoneid, &call->u.msg.data); … … 511 512 512 513 link_t *item; 513 for (item = dispatched_calls. next; item != &dispatched_calls;514 for (item = dispatched_calls.head.next; item != &dispatched_calls.head; 514 515 item = item->next) { 515 516 async_call_t *call = … … 611 612 /** Request callback connection. 612 613 * 613 * The @a task hashand @a phonehash identifiers returned614 * The @a task_id and @a phonehash identifiers returned 614 615 * by the kernel can be used for connection tracking. 615 616 * … … 618 619 * @param arg2 User defined argument. 619 620 * @param arg3 User defined argument. 620 * @param task hash Opaque identifier of the client task.621 * @param task_id Identifier of the client task. 621 622 * @param phonehash Opaque identifier of the phone that will 622 623 * be used for incoming calls. … … 626 627 */ 627 628 int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, 628 sysarg_t *taskhash, sysarg_t *phonehash) 629 { 630 return ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2, 631 arg3, NULL, NULL, NULL, taskhash, phonehash); 629 task_id_t *task_id, sysarg_t *phonehash) 630 { 631 ipc_call_t data; 632 int rc = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, 633 IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, (sysarg_t) &data); 634 if (rc == EOK) { 635 *task_id = data.in_task_id; 636 *phonehash = IPC_GET_ARG5(data); 637 } 638 return rc; 632 639 } 633 640 -
uspace/lib/c/generic/libc.c
rd2c67e7 r8ff0bd2 91 91 argc = 0; 92 92 argv = NULL; 93 __stdio_init(0 , NULL);93 __stdio_init(0); 94 94 } else { 95 95 argc = __pcb->argc; 96 96 argv = __pcb->argv; 97 __stdio_init(__pcb->filc , __pcb->filv);97 __stdio_init(__pcb->filc); 98 98 (void) chdir(__pcb->cwd); 99 99 } -
uspace/lib/c/generic/loader.c
rd2c67e7 r8ff0bd2 256 256 * 257 257 */ 258 int loader_set_files(loader_t *ldr, fdi_node_t *const files[]) 259 { 260 /* 261 * Serialize the arguments into a single array. First 262 * compute size of the buffer needed. 263 */ 264 fdi_node_t *const *ap = files; 265 size_t count = 0; 266 while (*ap != NULL) { 267 count++; 268 ap++; 269 } 270 271 fdi_node_t *files_buf; 272 files_buf = (fdi_node_t *) malloc(count * sizeof(fdi_node_t)); 273 if (files_buf == NULL) 274 return ENOMEM; 275 276 /* Fill the buffer */ 277 size_t i; 278 for (i = 0; i < count; i++) 279 files_buf[i] = *files[i]; 280 258 int loader_set_files(loader_t *ldr, int * const files[]) 259 { 281 260 /* Send serialized files to the loader */ 282 261 async_exch_t *exch = async_exchange_begin(ldr->sess); 283 284 ipc_call_t answer; 285 aid_t req = async_send_0(exch, LOADER_SET_FILES, &answer); 286 sysarg_t rc = async_data_write_start(exch, (void *) files_buf, 287 count * sizeof(fdi_node_t)); 288 289 async_exchange_end(exch); 290 free(files_buf); 291 262 async_exch_t *vfs_exch = vfs_exchange_begin(); 263 264 int i; 265 for (i = 0; files[i]; i++); 266 267 ipc_call_t answer; 268 aid_t req = async_send_1(exch, LOADER_SET_FILES, i, &answer); 269 270 sysarg_t rc = EOK; 271 272 for (i = 0; files[i]; i++) { 273 rc = async_state_change_start(exch, VFS_PASS_HANDLE, *files[i], 274 0, vfs_exch); 275 if (rc != EOK) 276 break; 277 } 278 279 vfs_exchange_end(vfs_exch); 280 async_exchange_end(exch); 281 292 282 if (rc != EOK) { 293 283 async_wait_for(req, NULL); -
uspace/lib/c/generic/net/icmp_api.c
rd2c67e7 r8ff0bd2 42 42 #include <net/ip_codes.h> 43 43 #include <async.h> 44 #include <async_obsolete.h>45 44 #include <sys/types.h> 46 45 #include <sys/time.h> … … 55 54 * timeout occurs. 56 55 * 57 * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.56 * @param[in] sess The ICMP session. 58 57 * @param[in] size The message data length in bytes. 59 58 * @param[in] timeout The timeout in milliseconds. … … 74 73 */ 75 74 int 76 icmp_echo_msg( int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl,75 icmp_echo_msg(async_sess_t *sess, size_t size, mseconds_t timeout, ip_ttl_t ttl, 77 76 ip_tos_t tos, int dont_fragment, const struct sockaddr *addr, 78 77 socklen_t addrlen) … … 83 82 if (addrlen <= 0) 84 83 return EINVAL; 85 86 message_id = async_obsolete_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl, 84 85 async_exch_t *exch = async_exchange_begin(sess); 86 87 message_id = async_send_5(exch, NET_ICMP_ECHO, size, timeout, ttl, 87 88 tos, (sysarg_t) dont_fragment, NULL); 88 89 89 90 /* Send the address */ 90 async_obsolete_data_write_start(icmp_phone, addr, (size_t) addrlen); 91 async_data_write_start(exch, addr, (size_t) addrlen); 92 93 async_exchange_end(exch); 91 94 92 95 async_wait_for(message_id, &result); -
uspace/lib/c/generic/net/icmp_common.c
rd2c67e7 r8ff0bd2 45 45 /** Connect to the ICMP module. 46 46 * 47 * @param[in] timeout Connection timeout in microseconds, zero 48 * for no timeout. 49 * 50 * @return ICMP module phone on success. 51 * @return ETIMEOUT if the connection timeouted. 47 * @return ICMP module session. 52 48 * 53 49 */ 54 int icmp_connect_module(suseconds_t timeout)50 async_sess_t *icmp_connect_module(void) 55 51 { 56 return connect_to_service _timeout(SERVICE_ICMP, timeout);52 return connect_to_service(SERVICE_ICMP); 57 53 } 58 54 -
uspace/lib/c/generic/net/modules.c
rd2c67e7 r8ff0bd2 40 40 41 41 #include <async.h> 42 #include <async_obsolete.h>43 42 #include <malloc.h> 44 43 #include <errno.h> … … 47 46 #include <net/modules.h> 48 47 #include <ns.h> 49 #include <ns_obsolete.h>50 51 /** The time between connect requests in microseconds. */52 #define MODULE_WAIT_TIME (10 * 1000)53 48 54 49 /** Answer a call. … … 98 93 } 99 94 100 /** Create bidirectional connection with the needed module service and register s95 /** Create bidirectional connection with the needed module service and register 101 96 * the message receiver. 102 97 * 103 * @param[in] need The needed module service. 104 * @param[in] arg1 The first parameter. 105 * @param[in] arg2 The second parameter. 106 * @param[in] arg3 The third parameter. 107 * @param[in] client_receiver The message receiver. 108 * 109 * @return The phone of the needed service. 110 * @return Other error codes as defined for the ipc_connect_to_me() 111 * function. 112 */ 113 int bind_service(services_t need, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, 114 async_client_conn_t client_receiver) 115 { 116 return bind_service_timeout(need, arg1, arg2, arg3, client_receiver, 0); 117 } 118 119 /** Create bidirectional connection with the needed module service and registers 120 * the message receiver. 121 * 122 * @param[in] need The needed module service. 123 * @param[in] arg1 The first parameter. 124 * @param[in] arg2 The second parameter. 125 * @param[in] arg3 The third parameter. 126 * @param[in] client_receiver The message receiver. 127 * @param[in] timeout The connection timeout in microseconds. No timeout if 128 * set to zero (0). 129 * 130 * @return The phone of the needed service. 131 * @return ETIMEOUT if the connection timeouted. 132 * @return Other error codes as defined for the ipc_connect_to_me() 133 * function. 134 * 135 */ 136 int bind_service_timeout(services_t need, sysarg_t arg1, sysarg_t arg2, 137 sysarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout) 98 * @param[in] need Needed module service. 99 * @param[in] arg1 First parameter. 100 * @param[in] arg2 Second parameter. 101 * @param[in] arg3 Third parameter. 102 * @param[in] client_receiver Message receiver. 103 * 104 * @return Session to the needed service. 105 * @return Other error codes as defined for the async_connect_to_me() 106 * function. 107 * 108 */ 109 async_sess_t *bind_service(services_t need, sysarg_t arg1, sysarg_t arg2, 110 sysarg_t arg3, async_client_conn_t client_receiver) 138 111 { 139 112 /* Connect to the needed service */ 140 int phone = connect_to_service_timeout(need, timeout);141 if ( phone >= 0) {113 async_sess_t *sess = connect_to_service(need); 114 if (sess != NULL) { 142 115 /* Request the bidirectional connection */ 143 int rc = async_obsolete_connect_to_me(phone, arg1, arg2, arg3, client_receiver); 116 async_exch_t *exch = async_exchange_begin(sess); 117 int rc = async_connect_to_me(exch, arg1, arg2, arg3, 118 client_receiver, NULL); 119 async_exchange_end(exch); 120 144 121 if (rc != EOK) { 145 async_obsolete_hangup(phone); 146 return rc; 122 async_hangup(sess); 123 errno = rc; 124 return NULL; 147 125 } 148 126 } 149 127 150 return phone; 151 } 152 153 /** Connects to the needed module. 154 * 155 * @param[in] need The needed module service. 156 * @return The phone of the needed service. 157 */ 158 int connect_to_service(services_t need) 159 { 160 return connect_to_service_timeout(need, 0); 161 } 162 163 /** Connects to the needed module. 164 * 165 * @param[in] need The needed module service. 166 * @param[in] timeout The connection timeout in microseconds. No timeout if 167 * set to zero (0). 168 * @return The phone of the needed service. 169 * @return ETIMEOUT if the connection timeouted. 170 */ 171 int connect_to_service_timeout(services_t need, suseconds_t timeout) 172 { 173 int phone; 174 175 /* If no timeout is set */ 176 if (timeout <= 0) 177 return service_obsolete_connect_blocking(need, 0, 0); 178 179 while (true) { 180 phone = service_obsolete_connect(need, 0, 0); 181 if ((phone >= 0) || (phone != ENOENT)) 182 return phone; 183 184 /* Abort if no time is left */ 185 if (timeout <= 0) 186 return ETIMEOUT; 187 188 /* Wait the minimum of the module wait time and the timeout */ 189 usleep((timeout <= MODULE_WAIT_TIME) ? 190 timeout : MODULE_WAIT_TIME); 191 timeout -= MODULE_WAIT_TIME; 192 } 193 } 194 195 /** Replies the data to the other party. 196 * 197 * @param[in] data The data buffer to be sent. 128 return sess; 129 } 130 131 /** Connect to the needed module. 132 * 133 * @param[in] need Needed module service. 134 * 135 * @return Session to the needed service. 136 * @return NULL if the connection timeouted. 137 * 138 */ 139 async_sess_t *connect_to_service(services_t need) 140 { 141 return service_connect_blocking(EXCHANGE_SERIALIZE, need, 0, 0); 142 } 143 144 /** Reply the data to the other party. 145 * 146 * @param[in] data The data buffer to be sent. 198 147 * @param[in] data_length The buffer length. 199 * @return EOK on success. 200 * @return EINVAL if the client does not expect the data. 201 * @return EOVERFLOW if the client does not expect all the data. 202 * Only partial data are transfered. 203 * @return Other error codes as defined for the 204 * async_data_read_finalize() function. 148 * 149 * @return EOK on success. 150 * @return EINVAL if the client does not expect the data. 151 * @return EOVERFLOW if the client does not expect all the data. 152 * Only partial data are transfered. 153 * @return Other error codes as defined for the 154 * async_data_read_finalize() function. 155 * 205 156 */ 206 157 int data_reply(void *data, size_t data_length) … … 208 159 size_t length; 209 160 ipc_callid_t callid; 210 161 211 162 /* Fetch the request */ 212 163 if (!async_data_read_receive(&callid, &length)) 213 164 return EINVAL; 214 165 215 166 /* Check the requested data size */ 216 167 if (length < data_length) { … … 218 169 return EOVERFLOW; 219 170 } 220 171 221 172 /* Send the data */ 222 173 return async_data_read_finalize(callid, data, data_length); -
uspace/lib/c/generic/net/socket_client.c
rd2c67e7 r8ff0bd2 39 39 #include <assert.h> 40 40 #include <async.h> 41 #include <async_obsolete.h>42 41 #include <fibril_synch.h> 43 42 #include <stdint.h> … … 65 64 #define SOCKET_MAX_ACCEPTED_SIZE 0 66 65 67 /** Default timeout for connections in microseconds. */68 #define SOCKET_CONNECT_TIMEOUT (1 * 1000 * 1000)69 70 66 /** 71 67 * Maximum number of random attempts to find a new socket identifier before … … 87 83 /** Socket identifier. */ 88 84 int socket_id; 89 /** Parent module phone. */90 int phone;85 /** Parent module session. */ 86 async_sess_t *sess; 91 87 /** Parent module service. */ 92 88 services_t service; … … 147 143 /** Socket client library global data. */ 148 144 static struct socket_client_globals { 149 /** TCP module phone. */ 150 int tcp_phone; 151 /** UDP module phone. */ 152 int udp_phone; 153 154 // /** The last socket identifier. 155 // */ 156 // int last_id; 145 /** TCP module session. */ 146 async_sess_t *tcp_sess; 147 /** UDP module session. */ 148 async_sess_t *udp_sess; 157 149 158 150 /** Active sockets. */ … … 167 159 fibril_rwlock_t lock; 168 160 } socket_globals = { 169 .tcp_phone = -1, 170 .udp_phone = -1, 171 // .last_id = 0, 161 .tcp_sess = NULL, 162 .udp_sess = NULL, 172 163 .sockets = NULL, 173 164 .lock = FIBRIL_RWLOCK_INITIALIZER(socket_globals.lock) … … 203 194 * @param[in] iid The initial message identifier. 204 195 * @param[in] icall The initial message call structure. 205 */ 206 static void socket_connection(ipc_callid_t iid, ipc_call_t * icall) 196 * @param[in] arg Local argument. 197 */ 198 static void socket_connection(ipc_callid_t iid, ipc_call_t * icall, void *arg) 207 199 { 208 200 ipc_callid_t callid; … … 282 274 } 283 275 284 /** Returns the TCP module phone. 285 * 286 * Connects to the TCP module if necessary. 287 * 288 * @return The TCP module phone. 289 * @return Other error codes as defined for the 290 * bind_service_timeout() function. 291 */ 292 static int socket_get_tcp_phone(void) 293 { 294 if (socket_globals.tcp_phone < 0) { 295 socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP, 296 0, 0, SERVICE_TCP, socket_connection, 297 SOCKET_CONNECT_TIMEOUT); 298 } 299 300 return socket_globals.tcp_phone; 301 } 302 303 /** Returns the UDP module phone. 304 * 305 * Connects to the UDP module if necessary. 306 * 307 * @return The UDP module phone. 308 * @return Other error codes as defined for the 309 * bind_service_timeout() function. 310 */ 311 static int socket_get_udp_phone(void) 312 { 313 if (socket_globals.udp_phone < 0) { 314 socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP, 315 0, 0, SERVICE_UDP, socket_connection, 316 SOCKET_CONNECT_TIMEOUT); 317 } 318 319 return socket_globals.udp_phone; 276 /** Return the TCP module session. 277 * 278 * Connect to the TCP module if necessary. 279 * 280 * @return The TCP module session. 281 * 282 */ 283 static async_sess_t *socket_get_tcp_sess(void) 284 { 285 if (socket_globals.tcp_sess == NULL) { 286 socket_globals.tcp_sess = bind_service(SERVICE_TCP, 287 0, 0, SERVICE_TCP, socket_connection); 288 } 289 290 return socket_globals.tcp_sess; 291 } 292 293 /** Return the UDP module session. 294 * 295 * Connect to the UDP module if necessary. 296 * 297 * @return The UDP module session. 298 * 299 */ 300 static async_sess_t *socket_get_udp_sess(void) 301 { 302 if (socket_globals.udp_sess == NULL) { 303 socket_globals.udp_sess = bind_service(SERVICE_UDP, 304 0, 0, SERVICE_UDP, socket_connection); 305 } 306 307 return socket_globals.udp_sess; 320 308 } 321 309 … … 333 321 sockets = socket_get_sockets(); 334 322 count = 0; 335 // socket_id = socket_globals.last_id;336 323 337 324 do { … … 346 333 if (socket_id < INT_MAX) { 347 334 ++socket_id; 348 /* } else if(socket_globals.last_id) { 349 * socket_globals.last_id = 0; 350 * socket_id = 1; 351 */ } else { 335 } else { 352 336 return ELIMIT; 353 337 } 354 338 } 355 339 } while (sockets_find(sockets, socket_id)); 356 357 // last_id = socket_id 340 358 341 return socket_id; 359 342 } … … 362 345 * 363 346 * @param[in,out] socket The socket to be initialized. 364 * @param[in] socket_id The new socket identifier. 365 * @param[in] phone The parent module phone. 366 * @param[in] service The parent module service. 367 */ 368 static void 369 socket_initialize(socket_t *socket, int socket_id, int phone, 370 services_t service) 347 * @param[in] socket_id The new socket identifier. 348 * @param[in] sess The parent module session. 349 * @param[in] service The parent module service. 350 */ 351 static void socket_initialize(socket_t *socket, int socket_id, 352 async_sess_t *sess, services_t service) 371 353 { 372 354 socket->socket_id = socket_id; 373 socket-> phone = phone;355 socket->sess = sess; 374 356 socket->service = service; 375 357 dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE); … … 396 378 * @return Other error codes as defined for the NET_SOCKET message. 397 379 * @return Other error codes as defined for the 398 * bind_service _timeout() function.380 * bind_service() function. 399 381 */ 400 382 int socket(int domain, int type, int protocol) 401 383 { 402 384 socket_t *socket; 403 int phone;385 async_sess_t *sess; 404 386 int socket_id; 405 387 services_t service; … … 418 400 switch (protocol) { 419 401 case IPPROTO_TCP: 420 phone = socket_get_tcp_phone();402 sess = socket_get_tcp_sess(); 421 403 service = SERVICE_TCP; 422 404 break; … … 433 415 switch (protocol) { 434 416 case IPPROTO_UDP: 435 phone = socket_get_udp_phone();417 sess = socket_get_udp_sess(); 436 418 service = SERVICE_UDP; 437 419 break; … … 454 436 } 455 437 456 if ( phone < 0)457 return phone;438 if (sess == NULL) 439 return ENOENT; 458 440 459 441 /* Create a new socket structure */ … … 472 454 return socket_id; 473 455 } 474 475 rc = (int) async_obsolete_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL, 456 457 async_exch_t *exch = async_exchange_begin(sess); 458 rc = (int) async_req_3_3(exch, NET_SOCKET, socket_id, 0, service, NULL, 476 459 &fragment_size, &header_size); 460 async_exchange_end(exch); 461 477 462 if (rc != EOK) { 478 463 fibril_rwlock_write_unlock(&socket_globals.lock); … … 485 470 486 471 /* Finish the new socket initialization */ 487 socket_initialize(socket, socket_id, phone, service);472 socket_initialize(socket, socket_id, sess, service); 488 473 /* Store the new socket */ 489 474 rc = sockets_add(socket_get_sockets(), socket_id, socket); … … 494 479 dyn_fifo_destroy(&socket->accepted); 495 480 free(socket); 496 async_obsolete_msg_3(phone, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0, 481 482 exch = async_exchange_begin(sess); 483 async_msg_3(exch, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0, 497 484 service); 485 async_exchange_end(exch); 486 498 487 return rc; 499 488 } … … 539 528 540 529 /* Request the message */ 541 message_id = async_obsolete_send_3(socket->phone, message, 530 async_exch_t *exch = async_exchange_begin(socket->sess); 531 message_id = async_send_3(exch, message, 542 532 (sysarg_t) socket->socket_id, arg2, socket->service, NULL); 543 533 /* Send the address */ 544 async_obsolete_data_write_start(socket->phone, data, datalength); 534 async_data_write_start(exch, data, datalength); 535 async_exchange_end(exch); 545 536 546 537 fibril_rwlock_read_unlock(&socket_globals.lock); … … 599 590 600 591 /* Request listen backlog change */ 601 result = (int) async_obsolete_req_3_0(socket->phone, NET_SOCKET_LISTEN, 592 async_exch_t *exch = async_exchange_begin(socket->sess); 593 result = (int) async_req_3_0(exch, NET_SOCKET_LISTEN, 602 594 (sysarg_t) socket->socket_id, (sysarg_t) backlog, socket->service); 595 async_exchange_end(exch); 603 596 604 597 fibril_rwlock_read_unlock(&socket_globals.lock); … … 670 663 return socket_id; 671 664 } 672 socket_initialize(new_socket, socket_id, socket-> phone,665 socket_initialize(new_socket, socket_id, socket->sess, 673 666 socket->service); 674 667 result = sockets_add(socket_get_sockets(), new_socket->socket_id, … … 682 675 683 676 /* Request accept */ 684 message_id = async_obsolete_send_5(socket->phone, NET_SOCKET_ACCEPT, 677 async_exch_t *exch = async_exchange_begin(socket->sess); 678 message_id = async_send_5(exch, NET_SOCKET_ACCEPT, 685 679 (sysarg_t) socket->socket_id, 0, socket->service, 0, 686 680 new_socket->socket_id, &answer); 687 681 688 682 /* Read address */ 689 async_obsolete_data_read_start(socket->phone, cliaddr, *addrlen); 683 async_data_read_start(exch, cliaddr, *addrlen); 684 async_exchange_end(exch); 685 690 686 fibril_rwlock_write_unlock(&socket_globals.lock); 691 687 async_wait_for(message_id, &ipc_result); … … 781 777 782 778 /* Request close */ 783 rc = (int) async_obsolete_req_3_0(socket->phone, NET_SOCKET_CLOSE, 779 async_exch_t *exch = async_exchange_begin(socket->sess); 780 rc = (int) async_req_3_0(exch, NET_SOCKET_CLOSE, 784 781 (sysarg_t) socket->socket_id, 0, socket->service); 782 async_exchange_end(exch); 783 785 784 if (rc != EOK) { 786 785 fibril_rwlock_write_unlock(&socket_globals.lock); … … 854 853 855 854 /* Request send */ 856 message_id = async_obsolete_send_5(socket->phone, message, 855 async_exch_t *exch = async_exchange_begin(socket->sess); 856 857 message_id = async_send_5(exch, message, 857 858 (sysarg_t) socket->socket_id, 858 859 (fragments == 1 ? datalength : socket->data_fragment_size), … … 861 862 /* Send the address if given */ 862 863 if (!toaddr || 863 (async_ obsolete_data_write_start(socket->phone, toaddr, addrlen) == EOK)) {864 (async_data_write_start(exch, toaddr, addrlen) == EOK)) { 864 865 if (fragments == 1) { 865 866 /* Send all if only one fragment */ 866 async_ obsolete_data_write_start(socket->phone, data, datalength);867 async_data_write_start(exch, data, datalength); 867 868 } else { 868 869 /* Send the first fragment */ 869 async_ obsolete_data_write_start(socket->phone, data,870 async_data_write_start(exch, data, 870 871 socket->data_fragment_size - socket->header_size); 871 872 data = ((const uint8_t *) data) + … … 874 875 /* Send the middle fragments */ 875 876 while (--fragments > 1) { 876 async_ obsolete_data_write_start(socket->phone, data,877 async_data_write_start(exch, data, 877 878 socket->data_fragment_size); 878 879 data = ((const uint8_t *) data) + … … 881 882 882 883 /* Send the last fragment */ 883 async_ obsolete_data_write_start(socket->phone, data,884 async_data_write_start(exch, data, 884 885 (datalength + socket->header_size) % 885 886 socket->data_fragment_size); 886 887 } 887 888 } 889 890 async_exchange_end(exch); 888 891 889 892 async_wait_for(message_id, &result); … … 1027 1030 return 0; 1028 1031 } 1032 1033 async_exch_t *exch = async_exchange_begin(socket->sess); 1029 1034 1030 1035 /* Prepare lengths if more fragments */ … … 1039 1044 1040 1045 /* Request packet data */ 1041 message_id = async_ obsolete_send_4(socket->phone, message,1046 message_id = async_send_4(exch, message, 1042 1047 (sysarg_t) socket->socket_id, 0, socket->service, 1043 1048 (sysarg_t) flags, &answer); … … 1045 1050 /* Read the address if desired */ 1046 1051 if(!fromaddr || 1047 (async_ obsolete_data_read_start(socket->phone, fromaddr,1052 (async_data_read_start(exch, fromaddr, 1048 1053 *addrlen) == EOK)) { 1049 1054 /* Read the fragment lengths */ 1050 if (async_ obsolete_data_read_start(socket->phone, lengths,1055 if (async_data_read_start(exch, lengths, 1051 1056 sizeof(int) * (fragments + 1)) == EOK) { 1052 1057 if (lengths[fragments] <= datalength) { … … 1055 1060 for (index = 0; index < fragments; 1056 1061 ++index) { 1057 async_obsolete_data_read_start( 1058 socket->phone, data, 1062 async_data_read_start(exch, data, 1059 1063 lengths[index]); 1060 1064 data = ((uint8_t *) data) + … … 1068 1072 } else { /* fragments == 1 */ 1069 1073 /* Request packet data */ 1070 message_id = async_ obsolete_send_4(socket->phone, message,1074 message_id = async_send_4(exch, message, 1071 1075 (sysarg_t) socket->socket_id, 0, socket->service, 1072 1076 (sysarg_t) flags, &answer); … … 1074 1078 /* Read the address if desired */ 1075 1079 if (!fromaddr || 1076 (async_obsolete_data_read_start(socket->phone, fromaddr, 1077 *addrlen) == EOK)) { 1080 (async_data_read_start(exch, fromaddr, *addrlen) == EOK)) { 1078 1081 /* Read all if only one fragment */ 1079 async_ obsolete_data_read_start(socket->phone, data, datalength);1082 async_data_read_start(exch, data, datalength); 1080 1083 } 1081 1084 } 1085 1086 async_exchange_end(exch); 1082 1087 1083 1088 async_wait_for(message_id, &ipc_result); … … 1191 1196 1192 1197 /* Request option value */ 1193 message_id = async_obsolete_send_3(socket->phone, NET_SOCKET_GETSOCKOPT, 1198 async_exch_t *exch = async_exchange_begin(socket->sess); 1199 1200 message_id = async_send_3(exch, NET_SOCKET_GETSOCKOPT, 1194 1201 (sysarg_t) socket->socket_id, (sysarg_t) optname, socket->service, 1195 1202 NULL); 1196 1203 1197 1204 /* Read the length */ 1198 if (async_ obsolete_data_read_start(socket->phone, optlen,1205 if (async_data_read_start(exch, optlen, 1199 1206 sizeof(*optlen)) == EOK) { 1200 1207 /* Read the value */ 1201 async_obsolete_data_read_start(socket->phone, value, *optlen); 1202 } 1208 async_data_read_start(exch, value, *optlen); 1209 } 1210 1211 async_exchange_end(exch); 1203 1212 1204 1213 fibril_rwlock_read_unlock(&socket_globals.lock); -
uspace/lib/c/generic/ns.c
rd2c67e7 r8ff0bd2 42 42 { 43 43 async_exch_t *exch = async_exchange_begin(session_ns); 44 int rc = async_connect_to_me(exch, service, 0, 0, NULL );44 int rc = async_connect_to_me(exch, service, 0, 0, NULL, NULL); 45 45 async_exchange_end(exch); 46 46 … … 56 56 async_exchange_end(exch); 57 57 58 /* 59 * FIXME Ugly hack to work around limitation of implementing 60 * parallel exchanges using multiple connections. Shift out 61 * first argument for non-initial connections. 62 */ 63 async_sess_args_set(sess, arg2, arg3, 0); 64 58 65 return sess; 59 66 } … … 66 73 async_connect_me_to_blocking(mgmt, exch, service, arg2, arg3); 67 74 async_exchange_end(exch); 75 76 /* 77 * FIXME Ugly hack to work around limitation of implementing 78 * parallel exchanges using multiple connections. Shift out 79 * first argument for non-initial connections. 80 */ 81 async_sess_args_set(sess, arg2, arg3, 0); 68 82 69 83 return sess; -
uspace/lib/c/generic/ns_obsolete.c
rd2c67e7 r8ff0bd2 36 36 #include <async_obsolete.h> 37 37 #include <ns_obsolete.h> 38 #include < kernel/ipc/ipc_methods.h>38 #include <abi/ipc/methods.h> 39 39 40 40 int service_obsolete_connect(sysarg_t service, sysarg_t arg2, sysarg_t arg3) -
uspace/lib/c/generic/private/async.h
rd2c67e7 r8ff0bd2 36 36 #define LIBC_PRIVATE_ASYNC_H_ 37 37 38 #include <async.h> 38 39 #include <adt/list.h> 39 40 #include <fibril.h> 41 #include <fibril_synch.h> 40 42 #include <sys/time.h> 41 43 #include <bool.h> 44 45 /** Session data */ 46 struct _async_sess { 47 /** List of inactive exchanges */ 48 list_t exch_list; 49 50 /** Exchange management style */ 51 exch_mgmt_t mgmt; 52 53 /** Session identification */ 54 int phone; 55 56 /** First clone connection argument */ 57 sysarg_t arg1; 58 59 /** Second clone connection argument */ 60 sysarg_t arg2; 61 62 /** Third clone connection argument */ 63 sysarg_t arg3; 64 65 /** Exchange mutex */ 66 fibril_mutex_t mutex; 67 68 /** Number of opened exchanges */ 69 atomic_t refcnt; 70 71 /** Mutex for stateful connections */ 72 fibril_mutex_t remote_state_mtx; 73 74 /** Data for stateful connections */ 75 void *remote_state_data; 76 }; 77 78 /** Exchange data */ 79 struct _async_exch { 80 /** Link into list of inactive exchanges */ 81 link_t sess_link; 82 83 /** Link into global list of inactive exchanges */ 84 link_t global_link; 85 86 /** Session pointer */ 87 async_sess_t *sess; 88 89 /** Exchange identification */ 90 int phone; 91 }; 42 92 43 93 /** Structures of this type are used to track the timeout events. */ -
uspace/lib/c/generic/private/io.h
rd2c67e7 r8ff0bd2 36 36 #define LIBC_PRIVATE_IO_H_ 37 37 38 #include <vfs/vfs.h> 39 40 extern void __stdio_init(int filc, fdi_node_t *filv[]); 38 extern void __stdio_init(int); 41 39 extern void __stdio_done(void); 42 40 -
uspace/lib/c/generic/private/thread.h
rd2c67e7 r8ff0bd2 36 36 #define LIBC_PRIVATE_THREAD_H_ 37 37 38 #include < kernel/proc/uarg.h>38 #include <abi/proc/uarg.h> 39 39 40 40 extern void __thread_entry(void); -
uspace/lib/c/generic/rtld/module.c
rd2c67e7 r8ff0bd2 35 35 */ 36 36 37 #include <adt/list.h> 38 #include <elf/elf_load.h> 39 #include <fcntl.h> 40 #include <loader/pcb.h> 37 41 #include <stdio.h> 38 42 #include <stdlib.h> 39 43 #include <unistd.h> 40 #include <fcntl.h>41 #include <adt/list.h>42 #include <loader/pcb.h>43 44 44 45 #include <rtld/rtld.h> … … 47 48 #include <rtld/rtld_arch.h> 48 49 #include <rtld/module.h> 49 #include <elf_load.h>50 50 51 51 /** (Eagerly) process all relocation tables in a module. … … 93 93 module_t *module_find(const char *name) 94 94 { 95 link_t *head = &runtime_env->modules_head;96 97 link_t *cur;98 95 module_t *m; 99 96 const char *p, *soname; … … 110 107 111 108 /* Traverse list of all modules. Not extremely fast, but simple */ 112 DPRINTF("head = %p\n", head); 113 for (cur = head->next; cur != head; cur = cur->next) { 109 list_foreach(runtime_env->modules, cur) { 114 110 DPRINTF("cur = %p\n", cur); 115 111 m = list_get_instance(cur, module_t, modules_link); … … 177 173 178 174 /* Insert into the list of loaded modules */ 179 list_append(&m->modules_link, &runtime_env->modules _head);175 list_append(&m->modules_link, &runtime_env->modules); 180 176 181 177 return m; … … 249 245 void modules_process_relocs(module_t *start) 250 246 { 251 link_t *head = &runtime_env->modules_head; 252 253 link_t *cur; 254 module_t *m; 255 256 for (cur = head->next; cur != head; cur = cur->next) { 247 module_t *m; 248 249 list_foreach(runtime_env->modules, cur) { 257 250 m = list_get_instance(cur, module_t, modules_link); 258 251 … … 268 261 void modules_untag(void) 269 262 { 270 link_t *head = &runtime_env->modules_head; 271 272 link_t *cur; 273 module_t *m; 274 275 for (cur = head->next; cur != head; cur = cur->next) { 263 module_t *m; 264 265 list_foreach(runtime_env->modules, cur) { 276 266 m = list_get_instance(cur, module_t, modules_link); 277 267 m->bfs_tag = false; -
uspace/lib/c/generic/rtld/rtld.c
rd2c67e7 r8ff0bd2 44 44 { 45 45 runtime_env = &rt_env_static; 46 list_initialize(&runtime_env->modules _head);46 list_initialize(&runtime_env->modules); 47 47 runtime_env->next_bias = 0x2000000; 48 48 runtime_env->program = NULL; -
uspace/lib/c/generic/rtld/symbol.c
rd2c67e7 r8ff0bd2 38 38 #include <stdlib.h> 39 39 40 #include <elf/elf.h> 40 41 #include <rtld/rtld.h> 41 42 #include <rtld/rtld_debug.h> 42 43 #include <rtld/symbol.h> 43 #include <elf.h>44 44 45 45 /* … … 118 118 module_t *m, *dm; 119 119 elf_symbol_t *sym, *s; 120 li nk_t queue_head;120 list_t queue; 121 121 size_t i; 122 122 … … 132 132 133 133 /* Insert root (the program) into the queue and tag it */ 134 list_initialize(&queue _head);134 list_initialize(&queue); 135 135 start->bfs_tag = true; 136 list_append(&start->queue_link, &queue _head);136 list_append(&start->queue_link, &queue); 137 137 138 138 /* If the symbol is found, it will be stored in 'sym' */ … … 140 140 141 141 /* While queue is not empty */ 142 while (!list_empty(&queue _head)) {142 while (!list_empty(&queue)) { 143 143 /* Pop first element from the queue */ 144 m = list_get_instance( queue_head.next, module_t, queue_link);144 m = list_get_instance(list_first(&queue), module_t, queue_link); 145 145 list_remove(&m->queue_link); 146 146 … … 162 162 if (dm->bfs_tag == false) { 163 163 dm->bfs_tag = true; 164 list_append(&dm->queue_link, &queue _head);164 list_append(&dm->queue_link, &queue); 165 165 } 166 166 } … … 168 168 169 169 /* Empty the queue so that we leave it in a clean state */ 170 while (!list_empty(&queue _head))171 list_remove( queue_head.next);170 while (!list_empty(&queue)) 171 list_remove(list_first(&queue)); 172 172 173 173 if (!sym) { -
uspace/lib/c/generic/str.c
rd2c67e7 r8ff0bd2 2 2 * Copyright (c) 2005 Martin Decky 3 3 * Copyright (c) 2008 Jiri Svoboda 4 * Copyright (c) 2011 Martin Sucha 5 * Copyright (c) 2011 Oleg Romanenko 4 6 * All rights reserved. 5 7 * … … 540 542 541 543 dstr_size = str_size(dest); 544 if (dstr_size >= size) 545 return; 546 542 547 str_cpy(dest + dstr_size, size - dstr_size, src); 548 } 549 550 /** Convert space-padded ASCII to string. 551 * 552 * Common legacy text encoding in hardware is 7-bit ASCII fitted into 553 * a fixed-width byte buffer (bit 7 always zero), right-padded with spaces 554 * (ASCII 0x20). Convert space-padded ascii to string representation. 555 * 556 * If the text does not fit into the destination buffer, the function converts 557 * as many characters as possible and returns EOVERFLOW. 558 * 559 * If the text contains non-ASCII bytes (with bit 7 set), the whole string is 560 * converted anyway and invalid characters are replaced with question marks 561 * (U_SPECIAL) and the function returns EIO. 562 * 563 * Regardless of return value upon return @a dest will always be well-formed. 564 * 565 * @param dest Destination buffer 566 * @param size Size of destination buffer 567 * @param src Space-padded ASCII. 568 * @param n Size of the source buffer in bytes. 569 * 570 * @return EOK on success, EOVERFLOW if the text does not fit 571 * destination buffer, EIO if the text contains 572 * non-ASCII bytes. 573 */ 574 int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n) 575 { 576 size_t sidx; 577 size_t didx; 578 size_t dlast; 579 uint8_t byte; 580 int rc; 581 int result; 582 583 /* There must be space for a null terminator in the buffer. */ 584 assert(size > 0); 585 result = EOK; 586 587 didx = 0; 588 dlast = 0; 589 for (sidx = 0; sidx < n; ++sidx) { 590 byte = src[sidx]; 591 if (!ascii_check(byte)) { 592 byte = U_SPECIAL; 593 result = EIO; 594 } 595 596 rc = chr_encode(byte, dest, &didx, size - 1); 597 if (rc != EOK) { 598 assert(rc == EOVERFLOW); 599 dest[didx] = '\0'; 600 return rc; 601 } 602 603 /* Remember dest index after last non-empty character */ 604 if (byte != 0x20) 605 dlast = didx; 606 } 607 608 /* Terminate string after last non-empty character */ 609 dest[dlast] = '\0'; 610 return result; 543 611 } 544 612 … … 572 640 dest[dest_off] = '\0'; 573 641 } 642 643 /** Convert UTF16 string to string. 644 * 645 * Convert utf16 string @a src to string. The output is written to the buffer 646 * specified by @a dest and @a size. @a size must be non-zero and the string 647 * written will always be well-formed. Surrogate pairs also supported. 648 * 649 * @param dest Destination buffer. 650 * @param size Size of the destination buffer. 651 * @param src Source utf16 string. 652 * 653 * @return EOK, if success, negative otherwise. 654 */ 655 int utf16_to_str(char *dest, size_t size, const uint16_t *src) 656 { 657 size_t idx = 0, dest_off = 0; 658 wchar_t ch; 659 int rc = EOK; 660 661 /* There must be space for a null terminator in the buffer. */ 662 assert(size > 0); 663 664 while (src[idx]) { 665 if ((src[idx] & 0xfc00) == 0xd800) { 666 if (src[idx + 1] && (src[idx + 1] & 0xfc00) == 0xdc00) { 667 ch = 0x10000; 668 ch += (src[idx] & 0x03FF) << 10; 669 ch += (src[idx + 1] & 0x03FF); 670 idx += 2; 671 } 672 else 673 break; 674 } else { 675 ch = src[idx]; 676 idx++; 677 } 678 rc = chr_encode(ch, dest, &dest_off, size - 1); 679 if (rc != EOK) 680 break; 681 } 682 dest[dest_off] = '\0'; 683 return rc; 684 } 685 686 int str_to_utf16(uint16_t *dest, size_t size, const char *src) 687 { 688 int rc = EOK; 689 size_t offset = 0; 690 size_t idx = 0; 691 wchar_t c; 692 693 assert(size > 0); 694 695 while ((c = str_decode(src, &offset, STR_NO_LIMIT)) != 0) { 696 if (c > 0x10000) { 697 if (idx + 2 >= size - 1) { 698 rc = EOVERFLOW; 699 break; 700 } 701 c = (c - 0x10000); 702 dest[idx] = 0xD800 | (c >> 10); 703 dest[idx + 1] = 0xDC00 | (c & 0x3FF); 704 idx++; 705 } else { 706 dest[idx] = c; 707 } 708 709 idx++; 710 if (idx >= size - 1) { 711 rc = EOVERFLOW; 712 break; 713 } 714 } 715 716 dest[idx] = '\0'; 717 return rc; 718 } 719 574 720 575 721 /** Convert wide string to new string. … … 652 798 653 799 dest[dlen - 1] = '\0'; 800 } 801 802 /** Convert string to wide string. 803 * 804 * Convert string @a src to wide string. A new wide NULL-terminated 805 * string will be allocated on the heap. 806 * 807 * @param src Source string. 808 */ 809 wchar_t *str_to_awstr(const char *str) 810 { 811 size_t len = str_length(str); 812 813 wchar_t *wstr = calloc(len+1, sizeof(wchar_t)); 814 if (wstr == NULL) 815 return NULL; 816 817 str_to_wstr(wstr, len + 1, str); 818 return wstr; 654 819 } 655 820 … … 950 1115 return dest; 951 1116 } 952 953 1117 954 1118 /** Convert initial part of string to unsigned long according to given base. -
uspace/lib/c/generic/sysinfo.c
rd2c67e7 r8ff0bd2 47 47 * 48 48 */ 49 sysinfo_item_ tag_t sysinfo_get_tag(const char *path)49 sysinfo_item_val_type_t sysinfo_get_val_type(const char *path) 50 50 { 51 return (sysinfo_item_ tag_t) __SYSCALL2(SYS_SYSINFO_GET_TAG,51 return (sysinfo_item_val_type_t) __SYSCALL2(SYS_SYSINFO_GET_VAL_TYPE, 52 52 (sysarg_t) path, (sysarg_t) str_size(path)); 53 53 } -
uspace/lib/c/generic/task.c
rd2c67e7 r8ff0bd2 46 46 #include <libc.h> 47 47 #include "private/ns.h" 48 #include <vfs/vfs.h> 48 49 49 50 task_id_t task_get_id(void) … … 100 101 */ 101 102 int task_spawnv(task_id_t *id, const char *path, const char *const args[]) 103 { 104 /* Send default files */ 105 int *files[4]; 106 int fd_stdin; 107 int fd_stdout; 108 int fd_stderr; 109 110 if ((stdin != NULL) && (fhandle(stdin, &fd_stdin) == EOK)) 111 files[0] = &fd_stdin; 112 else 113 files[0] = NULL; 114 115 if ((stdout != NULL) && (fhandle(stdout, &fd_stdout) == EOK)) 116 files[1] = &fd_stdout; 117 else 118 files[1] = NULL; 119 120 if ((stderr != NULL) && (fhandle(stderr, &fd_stderr) == EOK)) 121 files[2] = &fd_stderr; 122 else 123 files[2] = NULL; 124 125 files[3] = NULL; 126 127 return task_spawnvf(id, path, args, files); 128 } 129 130 /** Create a new task by running an executable from the filesystem. 131 * 132 * This is really just a convenience wrapper over the more complicated 133 * loader API. Arguments are passed as a null-terminated array of strings. 134 * Files are passed as null-terminated array of pointers to fdi_node_t. 135 * 136 * @param id If not NULL, the ID of the task is stored here on success. 137 * @param path Pathname of the binary to execute. 138 * @param argv Command-line arguments. 139 * @param files Standard files to use. 140 * 141 * @return Zero on success or negative error code. 142 * 143 */ 144 int task_spawnvf(task_id_t *id, const char *path, const char *const args[], 145 int *const files[]) 102 146 { 103 147 /* Connect to a program loader. */ … … 127 171 goto error; 128 172 129 /* Send default files */ 130 fdi_node_t *files[4]; 131 fdi_node_t stdin_node; 132 fdi_node_t stdout_node; 133 fdi_node_t stderr_node; 134 135 if ((stdin != NULL) && (fnode(stdin, &stdin_node) == EOK)) 136 files[0] = &stdin_node; 137 else 138 files[0] = NULL; 139 140 if ((stdout != NULL) && (fnode(stdout, &stdout_node) == EOK)) 141 files[1] = &stdout_node; 142 else 143 files[1] = NULL; 144 145 if ((stderr != NULL) && (fnode(stderr, &stderr_node) == EOK)) 146 files[2] = &stderr_node; 147 else 148 files[2] = NULL; 149 150 files[3] = NULL; 151 173 /* Send files */ 152 174 rc = loader_set_files(ldr, files); 153 175 if (rc != EOK) -
uspace/lib/c/generic/thread.c
rd2c67e7 r8ff0bd2 37 37 #include <stdlib.h> 38 38 #include <libarch/faddr.h> 39 #include < kernel/proc/uarg.h>39 #include <abi/proc/uarg.h> 40 40 #include <fibril.h> 41 41 #include <str.h> -
uspace/lib/c/generic/time.c
rd2c67e7 r8ff0bd2 36 36 #include <time.h> 37 37 #include <bool.h> 38 #include < arch/barrier.h>38 #include <libarch/barrier.h> 39 39 #include <macros.h> 40 40 #include <errno.h> -
uspace/lib/c/generic/udebug.c
rd2c67e7 r8ff0bd2 35 35 #include <udebug.h> 36 36 #include <sys/types.h> 37 #include < kernel/ipc/ipc_methods.h>37 #include <abi/ipc/methods.h> 38 38 #include <async.h> 39 39 -
uspace/lib/c/generic/vfs/vfs.c
rd2c67e7 r8ff0bd2 51 51 #include <assert.h> 52 52 #include <str.h> 53 #include < devmap.h>53 #include <loc.h> 54 54 #include <ipc/vfs.h> 55 #include <ipc/ devmap.h>55 #include <ipc/loc.h> 56 56 57 57 static FIBRIL_MUTEX_INITIALIZE(vfs_mutex); … … 69 69 * 70 70 */ 71 staticasync_exch_t *vfs_exchange_begin(void)71 async_exch_t *vfs_exchange_begin(void) 72 72 { 73 73 fibril_mutex_lock(&vfs_mutex); … … 87 87 * 88 88 */ 89 staticvoid vfs_exchange_end(async_exch_t *exch)89 void vfs_exchange_end(async_exch_t *exch) 90 90 { 91 91 async_exchange_end(exch); … … 142 142 } 143 143 144 int mount(const char *fs_name, const char *mp, const char *fq dn,144 int mount(const char *fs_name, const char *mp, const char *fqsn, 145 145 const char *opts, unsigned int flags) 146 146 { 147 147 int null_id = -1; 148 char null[ DEVMAP_NAME_MAXLEN];149 150 if (str_cmp(fq dn, "") == 0) {148 char null[LOC_NAME_MAXLEN]; 149 150 if (str_cmp(fqsn, "") == 0) { 151 151 /* No device specified, create a fresh 152 152 null/%d device instead */ 153 null_id = devmap_null_create();153 null_id = loc_null_create(); 154 154 155 155 if (null_id == -1) 156 156 return ENOMEM; 157 157 158 snprintf(null, DEVMAP_NAME_MAXLEN, "null/%d", null_id);159 fq dn = null;160 } 161 162 devmap_handle_t devmap_handle;163 int res = devmap_device_get_handle(fqdn, &devmap_handle, flags);158 snprintf(null, LOC_NAME_MAXLEN, "null/%d", null_id); 159 fqsn = null; 160 } 161 162 service_id_t service_id; 163 int res = loc_service_get_id(fqsn, &service_id, flags); 164 164 if (res != EOK) { 165 165 if (null_id != -1) 166 devmap_null_destroy(null_id);166 loc_null_destroy(null_id); 167 167 168 168 return res; … … 173 173 if (!mpa) { 174 174 if (null_id != -1) 175 devmap_null_destroy(null_id);175 loc_null_destroy(null_id); 176 176 177 177 return ENOMEM; … … 181 181 182 182 sysarg_t rc_orig; 183 aid_t req = async_send_2(exch, VFS_IN_MOUNT, devmap_handle, flags, NULL);183 aid_t req = async_send_2(exch, VFS_IN_MOUNT, service_id, flags, NULL); 184 184 sysarg_t rc = async_data_write_start(exch, (void *) mpa, mpa_size); 185 185 if (rc != EOK) { … … 189 189 190 190 if (null_id != -1) 191 devmap_null_destroy(null_id);191 loc_null_destroy(null_id); 192 192 193 193 if (rc_orig == EOK) … … 204 204 205 205 if (null_id != -1) 206 devmap_null_destroy(null_id);206 loc_null_destroy(null_id); 207 207 208 208 if (rc_orig == EOK) … … 219 219 220 220 if (null_id != -1) 221 devmap_null_destroy(null_id);221 loc_null_destroy(null_id); 222 222 223 223 if (rc_orig == EOK) … … 235 235 236 236 if (null_id != -1) 237 devmap_null_destroy(null_id);237 loc_null_destroy(null_id); 238 238 239 239 if (rc_orig == EOK) … … 248 248 249 249 if ((rc != EOK) && (null_id != -1)) 250 devmap_null_destroy(null_id);250 loc_null_destroy(null_id); 251 251 252 252 return (int) rc; … … 329 329 } 330 330 331 int open_node(fdi_node_t *node, int oflag)332 {333 async_exch_t *exch = vfs_exchange_begin();334 335 ipc_call_t answer;336 aid_t req = async_send_4(exch, VFS_IN_OPEN_NODE, node->fs_handle,337 node->devmap_handle, node->index, oflag, &answer);338 339 vfs_exchange_end(exch);340 341 sysarg_t rc;342 async_wait_for(req, &rc);343 344 if (rc != EOK)345 return (int) rc;346 347 return (int) IPC_GET_ARG1(answer);348 }349 350 331 int close(int fildes) 351 332 { … … 415 396 else 416 397 return -1; 398 } 399 400 /** Read entire buffer. 401 * 402 * In face of short reads this function continues reading until either 403 * the entire buffer is read or no more data is available (at end of file). 404 * 405 * @param fildes File descriptor 406 * @param buf Buffer, @a nbytes bytes long 407 * @param nbytes Number of bytes to read 408 * 409 * @return On success, positive number of bytes read. 410 * On failure, negative error code from read(). 411 */ 412 ssize_t read_all(int fildes, void *buf, size_t nbyte) 413 { 414 ssize_t cnt = 0; 415 size_t nread = 0; 416 uint8_t *bp = (uint8_t *) buf; 417 418 do { 419 bp += cnt; 420 nread += cnt; 421 cnt = read(fildes, bp, nbyte - nread); 422 } while (cnt > 0 && (nbyte - nread - cnt) > 0); 423 424 if (cnt < 0) 425 return cnt; 426 427 return nread + cnt; 428 } 429 430 /** Write entire buffer. 431 * 432 * This function fails if it cannot write exactly @a len bytes to the file. 433 * 434 * @param fildes File descriptor 435 * @param buf Data, @a nbytes bytes long 436 * @param nbytes Number of bytes to write 437 * 438 * @return EOK on error, return value from write() if writing 439 * failed. 440 */ 441 ssize_t write_all(int fildes, const void *buf, size_t nbyte) 442 { 443 ssize_t cnt = 0; 444 ssize_t nwritten = 0; 445 const uint8_t *bp = (uint8_t *) buf; 446 447 do { 448 bp += cnt; 449 nwritten += cnt; 450 cnt = write(fildes, bp, nbyte - nwritten); 451 } while (cnt > 0 && ((ssize_t )nbyte - nwritten - cnt) > 0); 452 453 if (cnt < 0) 454 return cnt; 455 456 if ((ssize_t)nbyte - nwritten - cnt > 0) 457 return EIO; 458 459 return nbyte; 417 460 } 418 461 … … 749 792 } 750 793 751 if (!stat. device) {794 if (!stat.service) { 752 795 errno = ENOENT; 753 796 return NULL; 754 797 } 755 798 756 return devmap_device_connect(mgmt, stat.device, 0); 757 } 758 759 int fd_node(int fildes, fdi_node_t *node) 760 { 761 struct stat stat; 762 int rc = fstat(fildes, &stat); 763 764 if (rc == EOK) { 765 node->fs_handle = stat.fs_handle; 766 node->devmap_handle = stat.devmap_handle; 767 node->index = stat.index; 768 } 769 770 return rc; 799 return loc_service_connect(mgmt, stat.service, 0); 771 800 } 772 801 … … 786 815 } 787 816 817 int fd_wait(void) 818 { 819 async_exch_t *exch = vfs_exchange_begin(); 820 821 sysarg_t ret; 822 sysarg_t rc = async_req_0_1(exch, VFS_IN_WAIT_HANDLE, &ret); 823 824 vfs_exchange_end(exch); 825 826 if (rc == EOK) 827 return (int) ret; 828 829 return (int) rc; 830 } 831 788 832 /** @} 789 833 */
Note:
See TracChangeset
for help on using the changeset viewer.
