Changeset cf2af94 in mainline for uspace/lib/c/generic/net/socket_client.c
- Timestamp:
- 2011-02-09T11:46:47Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cb15135a
- Parents:
- a49c4002 (diff), 0b37882 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/net/socket_client.c
ra49c4002 rcf2af94 43 43 #include <stdlib.h> 44 44 #include <errno.h> 45 45 #include <task.h> 46 46 #include <ipc/services.h> 47 47 #include <ipc/socket.h> 48 49 48 #include <net/modules.h> 50 49 #include <net/in.h> … … 214 213 callid = async_get_call(&call); 215 214 216 switch (IPC_GET_ METHOD(call)) {215 switch (IPC_GET_IMETHOD(call)) { 217 216 case NET_SOCKET_RECEIVED: 218 217 case NET_SOCKET_ACCEPTED: … … 220 219 fibril_rwlock_read_lock(&socket_globals.lock); 221 220 222 / / find the socket221 /* Find the socket */ 223 222 socket = sockets_find(socket_get_sockets(), 224 223 SOCKET_GET_SOCKET_ID(call)); … … 229 228 } 230 229 231 switch (IPC_GET_ METHOD(call)) {230 switch (IPC_GET_IMETHOD(call)) { 232 231 case NET_SOCKET_RECEIVED: 233 232 fibril_mutex_lock(&socket->receive_lock); 234 / / push the number of received packet fragments233 /* Push the number of received packet fragments */ 235 234 rc = dyn_fifo_push(&socket->received, 236 235 SOCKET_GET_DATA_FRAGMENTS(call), 237 236 SOCKET_MAX_RECEIVED_SIZE); 238 237 if (rc == EOK) { 239 / / signal the received packet238 /* Signal the received packet */ 240 239 fibril_condvar_signal(&socket->receive_signal); 241 240 } … … 244 243 245 244 case NET_SOCKET_ACCEPTED: 246 / / push the new socket identifier245 /* Push the new socket identifier */ 247 246 fibril_mutex_lock(&socket->accept_lock); 248 247 rc = dyn_fifo_push(&socket->accepted, 1, 249 248 SOCKET_MAX_ACCEPTED_SIZE); 250 249 if (rc == EOK) { 251 / / signal the accepted socket250 /* Signal the accepted socket */ 252 251 fibril_condvar_signal(&socket->accept_signal); 253 252 } … … 264 263 fibril_rwlock_write_lock(&socket->sending_lock); 265 264 266 / / set the data fragment size265 /* Set the data fragment size */ 267 266 socket->data_fragment_size = 268 267 SOCKET_GET_DATA_FRAGMENT_SIZE(call); … … 278 277 } 279 278 280 ipc_answer_0(callid, (ipcarg_t) rc);279 async_answer_0(callid, (sysarg_t) rc); 281 280 goto loop; 282 281 } … … 342 341 socket_id = 1; 343 342 ++count; 344 / / only this branch for last_id343 /* Only this branch for last_id */ 345 344 } else { 346 345 if (socket_id < INT_MAX) { … … 404 403 int socket_id; 405 404 services_t service; 406 ipcarg_t fragment_size;407 ipcarg_t header_size;405 sysarg_t fragment_size; 406 sysarg_t header_size; 408 407 int rc; 409 408 410 / / find the appropriate service409 /* Find the appropriate service */ 411 410 switch (domain) { 412 411 case PF_INET: … … 457 456 return phone; 458 457 459 / / create a new socket structure458 /* Create a new socket structure */ 460 459 socket = (socket_t *) malloc(sizeof(socket_t)); 461 460 if (!socket) … … 465 464 fibril_rwlock_write_lock(&socket_globals.lock); 466 465 467 / / request a new socket466 /* Request a new socket */ 468 467 socket_id = socket_generate_new_id(); 469 468 if (socket_id <= 0) { … … 484 483 socket->header_size = (size_t) header_size; 485 484 486 / / finish the new socket initialization485 /* Finish the new socket initialization */ 487 486 socket_initialize(socket, socket_id, phone, service); 488 / / store the new socket487 /* Store the new socket */ 489 488 rc = sockets_add(socket_get_sockets(), socket_id, socket); 490 489 … … 494 493 dyn_fifo_destroy(&socket->accepted); 495 494 free(socket); 496 async_msg_3(phone, NET_SOCKET_CLOSE, ( ipcarg_t) socket_id, 0,495 async_msg_3(phone, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0, 497 496 service); 498 497 return rc; … … 516 515 */ 517 516 static int 518 socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2,517 socket_send_data(int socket_id, sysarg_t message, sysarg_t arg2, 519 518 const void *data, size_t datalength) 520 519 { 521 520 socket_t *socket; 522 521 aid_t message_id; 523 ipcarg_t result;522 sysarg_t result; 524 523 525 524 if (!data) … … 531 530 fibril_rwlock_read_lock(&socket_globals.lock); 532 531 533 / / find the socket532 /* Find the socket */ 534 533 socket = sockets_find(socket_get_sockets(), socket_id); 535 534 if (!socket) { … … 538 537 } 539 538 540 / / request the message539 /* Request the message */ 541 540 message_id = async_send_3(socket->phone, message, 542 ( ipcarg_t) socket->socket_id, arg2, socket->service, NULL);543 / / send the address541 (sysarg_t) socket->socket_id, arg2, socket->service, NULL); 542 /* Send the address */ 544 543 async_data_write_start(socket->phone, data, datalength); 545 544 … … 566 565 return EINVAL; 567 566 568 / / send the address567 /* Send the address */ 569 568 return socket_send_data(socket_id, NET_SOCKET_BIND, 0, my_addr, 570 569 (size_t) addrlen); … … 591 590 fibril_rwlock_read_lock(&socket_globals.lock); 592 591 593 / / find the socket592 /* Find the socket */ 594 593 socket = sockets_find(socket_get_sockets(), socket_id); 595 594 if (!socket) { … … 598 597 } 599 598 600 / / request listen backlog change599 /* Request listen backlog change */ 601 600 result = (int) async_req_3_0(socket->phone, NET_SOCKET_LISTEN, 602 ( ipcarg_t) socket->socket_id, (ipcarg_t) backlog, socket->service);601 (sysarg_t) socket->socket_id, (sysarg_t) backlog, socket->service); 603 602 604 603 fibril_rwlock_read_unlock(&socket_globals.lock); … … 625 624 socket_t *new_socket; 626 625 aid_t message_id; 627 ipcarg_t ipc_result;626 sysarg_t ipc_result; 628 627 int result; 629 628 ipc_call_t answer; … … 634 633 fibril_rwlock_write_lock(&socket_globals.lock); 635 634 636 / / find the socket635 /* Find the socket */ 637 636 socket = sockets_find(socket_get_sockets(), socket_id); 638 637 if (!socket) { … … 643 642 fibril_mutex_lock(&socket->accept_lock); 644 643 645 / / wait for an accepted socket644 /* Wait for an accepted socket */ 646 645 ++ socket->blocked; 647 646 while (dyn_fifo_value(&socket->accepted) <= 0) { 648 647 fibril_rwlock_write_unlock(&socket_globals.lock); 649 648 fibril_condvar_wait(&socket->accept_signal, &socket->accept_lock); 650 / / drop the accept lock to avoid deadlock649 /* Drop the accept lock to avoid deadlock */ 651 650 fibril_mutex_unlock(&socket->accept_lock); 652 651 fibril_rwlock_write_lock(&socket_globals.lock); … … 655 654 -- socket->blocked; 656 655 657 / / create a new scoket656 /* Create a new socket */ 658 657 new_socket = (socket_t *) malloc(sizeof(socket_t)); 659 658 if (!new_socket) { … … 681 680 } 682 681 683 / / request accept682 /* Request accept */ 684 683 message_id = async_send_5(socket->phone, NET_SOCKET_ACCEPT, 685 ( ipcarg_t) socket->socket_id, 0, socket->service, 0,684 (sysarg_t) socket->socket_id, 0, socket->service, 0, 686 685 new_socket->socket_id, &answer); 687 686 688 / / read address689 ipc_data_read_start(socket->phone, cliaddr, *addrlen);687 /* Read address */ 688 async_data_read_start(socket->phone, cliaddr, *addrlen); 690 689 fibril_rwlock_write_unlock(&socket_globals.lock); 691 690 async_wait_for(message_id, &ipc_result); … … 695 694 result = EINVAL; 696 695 697 / / dequeue the accepted socket if successful696 /* Dequeue the accepted socket if successful */ 698 697 dyn_fifo_pop(&socket->accepted); 699 / / set address length698 /* Set address length */ 700 699 *addrlen = SOCKET_GET_ADDRESS_LENGTH(answer); 701 700 new_socket->data_fragment_size = 702 701 SOCKET_GET_DATA_FRAGMENT_SIZE(answer); 703 702 } else if (result == ENOTSOCK) { 704 / / empty the queue if no accepted sockets703 /* Empty the queue if no accepted sockets */ 705 704 while (dyn_fifo_pop(&socket->accepted) > 0) 706 705 ; … … 731 730 return EDESTADDRREQ; 732 731 733 / / send the address732 /* Send the address */ 734 733 return socket_send_data(socket_id, NET_SOCKET_CONNECT, 0, serv_addr, 735 734 addrlen); … … 744 743 int accepted_id; 745 744 746 / / destroy all accepted sockets745 /* Destroy all accepted sockets */ 747 746 while ((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0) 748 747 socket_destroy(sockets_find(socket_get_sockets(), accepted_id)); … … 780 779 } 781 780 782 / / request close781 /* Request close */ 783 782 rc = (int) async_req_3_0(socket->phone, NET_SOCKET_CLOSE, 784 ( ipcarg_t) socket->socket_id, 0, socket->service);783 (sysarg_t) socket->socket_id, 0, socket->service); 785 784 if (rc != EOK) { 786 785 fibril_rwlock_write_unlock(&socket_globals.lock); 787 786 return rc; 788 787 } 789 / / free the socket structure788 /* Free the socket structure */ 790 789 socket_destroy(socket); 791 790 … … 815 814 */ 816 815 static int 817 sendto_core( ipcarg_t message, int socket_id, const void *data,816 sendto_core(sysarg_t message, int socket_id, const void *data, 818 817 size_t datalength, int flags, const struct sockaddr *toaddr, 819 818 socklen_t addrlen) … … 821 820 socket_t *socket; 822 821 aid_t message_id; 823 ipcarg_t result;822 sysarg_t result; 824 823 size_t fragments; 825 824 ipc_call_t answer; … … 833 832 fibril_rwlock_read_lock(&socket_globals.lock); 834 833 835 / / find socket834 /* Find socket */ 836 835 socket = sockets_find(socket_get_sockets(), socket_id); 837 836 if (!socket) { … … 842 841 fibril_rwlock_read_lock(&socket->sending_lock); 843 842 844 / / compute data fragment count843 /* Compute data fragment count */ 845 844 if (socket->data_fragment_size > 0) { 846 845 fragments = (datalength + socket->header_size) / … … 853 852 } 854 853 855 / / request send854 /* Request send */ 856 855 message_id = async_send_5(socket->phone, message, 857 ( ipcarg_t) socket->socket_id,856 (sysarg_t) socket->socket_id, 858 857 (fragments == 1 ? datalength : socket->data_fragment_size), 859 socket->service, ( ipcarg_t) flags, fragments, &answer);860 861 / / send the address if given858 socket->service, (sysarg_t) flags, fragments, &answer); 859 860 /* Send the address if given */ 862 861 if (!toaddr || 863 862 (async_data_write_start(socket->phone, toaddr, addrlen) == EOK)) { 864 863 if (fragments == 1) { 865 / / send all if only one fragment864 /* Send all if only one fragment */ 866 865 async_data_write_start(socket->phone, data, datalength); 867 866 } else { 868 / / send the first fragment867 /* Send the first fragment */ 869 868 async_data_write_start(socket->phone, data, 870 869 socket->data_fragment_size - socket->header_size); … … 872 871 socket->data_fragment_size - socket->header_size; 873 872 874 / / send the middle fragments873 /* Send the middle fragments */ 875 874 while (--fragments > 1) { 876 875 async_data_write_start(socket->phone, data, … … 880 879 } 881 880 882 / / send the last fragment881 /* Send the last fragment */ 883 882 async_data_write_start(socket->phone, data, 884 883 (datalength + socket->header_size) % … … 892 891 (SOCKET_GET_DATA_FRAGMENT_SIZE(answer) != 893 892 socket->data_fragment_size)) { 894 / / set the data fragment size893 /* Set the data fragment size */ 895 894 socket->data_fragment_size = 896 895 SOCKET_GET_DATA_FRAGMENT_SIZE(answer); … … 917 916 int send(int socket_id, void *data, size_t datalength, int flags) 918 917 { 919 / / without the address918 /* Without the address */ 920 919 return sendto_core(NET_SOCKET_SEND, socket_id, data, datalength, flags, 921 920 NULL, 0); … … 950 949 return EDESTADDRREQ; 951 950 952 / / with the address951 /* With the address */ 953 952 return sendto_core(NET_SOCKET_SENDTO, socket_id, data, datalength, 954 953 flags, toaddr, addrlen); … … 966 965 * read. The actual address length is set. Used only if 967 966 * fromaddr is not NULL. 968 * @return EOK on success. 967 * @return Positive received message size in bytes on success. 968 * @return Zero if no more data (other side closed the connection). 969 969 * @return ENOTSOCK if the socket is not found. 970 970 * @return EBADMEM if the data parameter is NULL. … … 972 972 * @return Other error codes as defined for the spcific message. 973 973 */ 974 static int975 recvfrom_core( ipcarg_t message, int socket_id, void *data, size_t datalength,974 static ssize_t 975 recvfrom_core(sysarg_t message, int socket_id, void *data, size_t datalength, 976 976 int flags, struct sockaddr *fromaddr, socklen_t *addrlen) 977 977 { 978 978 socket_t *socket; 979 979 aid_t message_id; 980 ipcarg_t ipc_result;980 sysarg_t ipc_result; 981 981 int result; 982 982 size_t fragments; … … 984 984 size_t index; 985 985 ipc_call_t answer; 986 ssize_t retval; 986 987 987 988 if (!data) … … 996 997 fibril_rwlock_read_lock(&socket_globals.lock); 997 998 998 / / find the socket999 /* Find the socket */ 999 1000 socket = sockets_find(socket_get_sockets(), socket_id); 1000 1001 if (!socket) { … … 1004 1005 1005 1006 fibril_mutex_lock(&socket->receive_lock); 1006 / / wait for a received packet1007 /* Wait for a received packet */ 1007 1008 ++socket->blocked; 1008 while ((result = dyn_fifo_value(&socket->received)) < =0) {1009 while ((result = dyn_fifo_value(&socket->received)) < 0) { 1009 1010 fibril_rwlock_read_unlock(&socket_globals.lock); 1010 1011 fibril_condvar_wait(&socket->receive_signal, 1011 1012 &socket->receive_lock); 1012 1013 1013 / / drop the receive lock to avoid deadlock1014 /* Drop the receive lock to avoid deadlock */ 1014 1015 fibril_mutex_unlock(&socket->receive_lock); 1015 1016 fibril_rwlock_read_lock(&socket_globals.lock); … … 1019 1020 fragments = (size_t) result; 1020 1021 1021 // prepare lengths if more fragments 1022 if (fragments == 0) { 1023 /* No more data, other side has closed the connection. */ 1024 fibril_mutex_unlock(&socket->receive_lock); 1025 fibril_rwlock_read_unlock(&socket_globals.lock); 1026 return 0; 1027 } 1028 1029 /* Prepare lengths if more fragments */ 1022 1030 if (fragments > 1) { 1023 1031 lengths = (size_t *) malloc(sizeof(size_t) * fragments + … … 1029 1037 } 1030 1038 1031 / / request packet data1039 /* Request packet data */ 1032 1040 message_id = async_send_4(socket->phone, message, 1033 ( ipcarg_t) socket->socket_id, 0, socket->service,1034 ( ipcarg_t) flags, &answer);1035 1036 / / read the address if desired1041 (sysarg_t) socket->socket_id, 0, socket->service, 1042 (sysarg_t) flags, &answer); 1043 1044 /* Read the address if desired */ 1037 1045 if(!fromaddr || 1038 1046 (async_data_read_start(socket->phone, fromaddr, 1039 1047 *addrlen) == EOK)) { 1040 / / read the fragment lengths1048 /* Read the fragment lengths */ 1041 1049 if (async_data_read_start(socket->phone, lengths, 1042 1050 sizeof(int) * (fragments + 1)) == EOK) { 1043 1051 if (lengths[fragments] <= datalength) { 1044 1052 1045 / / read all fragments if long enough1053 /* Read all fragments if long enough */ 1046 1054 for (index = 0; index < fragments; 1047 1055 ++index) { … … 1057 1065 1058 1066 free(lengths); 1059 } else { 1060 / / request packet data1067 } else { /* fragments == 1 */ 1068 /* Request packet data */ 1061 1069 message_id = async_send_4(socket->phone, message, 1062 ( ipcarg_t) socket->socket_id, 0, socket->service,1063 ( ipcarg_t) flags, &answer);1064 1065 / / read the address if desired1070 (sysarg_t) socket->socket_id, 0, socket->service, 1071 (sysarg_t) flags, &answer); 1072 1073 /* Read the address if desired */ 1066 1074 if (!fromaddr || 1067 1075 (async_data_read_start(socket->phone, fromaddr, 1068 1076 *addrlen) == EOK)) { 1069 / / read all if only one fragment1077 /* Read all if only one fragment */ 1070 1078 async_data_read_start(socket->phone, data, datalength); 1071 1079 } … … 1075 1083 result = (int) ipc_result; 1076 1084 if (result == EOK) { 1077 / / dequeue the received packet1085 /* Dequeue the received packet */ 1078 1086 dyn_fifo_pop(&socket->received); 1079 / / return read data length1080 re sult= SOCKET_GET_READ_DATA_LENGTH(answer);1081 / / set address length1087 /* Return read data length */ 1088 retval = SOCKET_GET_READ_DATA_LENGTH(answer); 1089 /* Set address length */ 1082 1090 if (fromaddr && addrlen) 1083 1091 *addrlen = SOCKET_GET_ADDRESS_LENGTH(answer); 1092 } else { 1093 retval = (ssize_t) result; 1084 1094 } 1085 1095 1086 1096 fibril_mutex_unlock(&socket->receive_lock); 1087 1097 fibril_rwlock_read_unlock(&socket_globals.lock); 1088 return re sult;1098 return retval; 1089 1099 } 1090 1100 … … 1095 1105 * @param[in] datalength The data length. 1096 1106 * @param[in] flags Various receive flags. 1097 * @return EOK on success. 1107 * @return Positive received message size in bytes on success. 1108 * @return Zero if no more data (other side closed the connection). 1098 1109 * @return ENOTSOCK if the socket is not found. 1099 1110 * @return EBADMEM if the data parameter is NULL. … … 1102 1113 * message. 1103 1114 */ 1104 int recv(int socket_id, void *data, size_t datalength, int flags)1105 { 1106 / / without the address1115 ssize_t recv(int socket_id, void *data, size_t datalength, int flags) 1116 { 1117 /* Without the address */ 1107 1118 return recvfrom_core(NET_SOCKET_RECV, socket_id, data, datalength, 1108 1119 flags, NULL, NULL); … … 1118 1129 * @param[in,out] addrlen The address length. The maximum address length is 1119 1130 * read. The actual address length is set. 1120 * @return EOK on success. 1131 * @return Positive received message size in bytes on success. 1132 * @return Zero if no more data (other side closed the connection). 1121 1133 * @return ENOTSOCK if the socket is not found. 1122 1134 * @return EBADMEM if the data or fromaddr parameter is NULL. … … 1125 1137 * message. 1126 1138 */ 1127 int1139 ssize_t 1128 1140 recvfrom(int socket_id, void *data, size_t datalength, int flags, 1129 1141 struct sockaddr *fromaddr, socklen_t *addrlen) … … 1135 1147 return NO_DATA; 1136 1148 1137 / / with the address1149 /* With the address */ 1138 1150 return recvfrom_core(NET_SOCKET_RECVFROM, socket_id, data, datalength, 1139 1151 flags, fromaddr, addrlen); … … 1160 1172 socket_t *socket; 1161 1173 aid_t message_id; 1162 ipcarg_t result;1174 sysarg_t result; 1163 1175 1164 1176 if (!value || !optlen) … … 1170 1182 fibril_rwlock_read_lock(&socket_globals.lock); 1171 1183 1172 / / find the socket1184 /* Find the socket */ 1173 1185 socket = sockets_find(socket_get_sockets(), socket_id); 1174 1186 if (!socket) { … … 1177 1189 } 1178 1190 1179 / / request option value1191 /* Request option value */ 1180 1192 message_id = async_send_3(socket->phone, NET_SOCKET_GETSOCKOPT, 1181 ( ipcarg_t) socket->socket_id, (ipcarg_t) optname, socket->service,1193 (sysarg_t) socket->socket_id, (sysarg_t) optname, socket->service, 1182 1194 NULL); 1183 1195 1184 / / read the length1196 /* Read the length */ 1185 1197 if (async_data_read_start(socket->phone, optlen, 1186 1198 sizeof(*optlen)) == EOK) { 1187 / / read the value1199 /* Read the value */ 1188 1200 async_data_read_start(socket->phone, value, *optlen); 1189 1201 } … … 1212 1224 size_t optlen) 1213 1225 { 1214 / / send the value1226 /* Send the value */ 1215 1227 return socket_send_data(socket_id, NET_SOCKET_SETSOCKOPT, 1216 ( ipcarg_t) optname, value, optlen);1228 (sysarg_t) optname, value, optlen); 1217 1229 } 1218 1230
Note:
See TracChangeset
for help on using the changeset viewer.