Changeset fb4d788 in mainline for uspace/lib/c
- Timestamp:
- 2015-07-28T11:28:14Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6accc5cf
- Parents:
- df2bce32 (diff), 47726b5e (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
- Files:
-
- 5 added
- 15 deleted
- 20 edited
- 3 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/Makefile
rdf2bce32 rfb4d788 97 97 generic/futex.c \ 98 98 generic/inet/addr.c \ 99 generic/inet/endpoint.c \ 100 generic/inet/tcp.c \ 101 generic/inet/udp.c \ 99 102 generic/inet.c \ 100 103 generic/inetcfg.c \ … … 137 140 generic/adt/list.c \ 138 141 generic/adt/hash_table.c \ 139 generic/adt/dynamic_fifo.c \140 generic/adt/char_map.c \141 142 generic/adt/prodcons.c \ 142 143 generic/time.c \ … … 145 146 generic/vfs/vfs.c \ 146 147 generic/vfs/canonify.c \ 147 generic/net/inet.c \148 generic/net/socket_client.c \149 generic/net/socket_parse.c \150 148 generic/setjmp.c \ 151 149 generic/stack.c \ -
uspace/lib/c/generic/fibril.c
rdf2bce32 rfb4d788 57 57 /** 58 58 * This futex serializes access to ready_list, 59 * serialized_list and manager_list.59 * manager_list and fibril_list. 60 60 */ 61 61 static futex_t fibril_futex = FUTEX_INITIALIZER; 62 62 63 63 static LIST_INITIALIZE(ready_list); 64 static LIST_INITIALIZE(serialized_list);65 64 static LIST_INITIALIZE(manager_list); 66 65 static LIST_INITIALIZE(fibril_list); 67 68 /** Number of threads that are executing a manager fibril. */69 static int threads_in_manager;70 71 /**72 * Number of threads that are executing a manager fibril73 * and are serialized. Protected by async_futex.74 */75 static int serialized_threads;76 77 /** Fibril-local count of serialization. If > 0, we must not preempt */78 static fibril_local int serialization_count;79 66 80 67 /** Function that spans the whole life-cycle of a fibril. … … 96 83 fibril->retval = fibril->func(fibril->arg); 97 84 85 futex_down(&async_futex); 98 86 fibril_switch(FIBRIL_FROM_DEAD); 99 87 /* Not reached */ … … 126 114 127 115 fibril->waits_for = NULL; 116 117 futex_lock(&fibril_futex); 128 118 list_append(&fibril->all_link, &fibril_list); 119 futex_unlock(&fibril_futex); 129 120 130 121 return fibril; 131 122 } 132 123 133 void fibril_teardown(fibril_t *fibril) 134 { 124 void fibril_teardown(fibril_t *fibril, bool locked) 125 { 126 if (!locked) 127 futex_lock(&fibril_futex); 135 128 list_remove(&fibril->all_link); 129 if (!locked) 130 futex_unlock(&fibril_futex); 136 131 tls_free(fibril->tcb); 137 132 free(fibril); … … 140 135 /** Switch from the current fibril. 141 136 * 142 * If calling with FIBRIL_TO_MANAGER parameter, the async_futex should be143 * held.137 * If stype is FIBRIL_TO_MANAGER or FIBRIL_FROM_DEAD, the async_futex must 138 * be held. 144 139 * 145 140 * @param stype Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER, … … 153 148 int fibril_switch(fibril_switch_type_t stype) 154 149 { 155 int retval = 0; 156 157 futex_lock(&fibril_futex); 158 159 if (stype == FIBRIL_PREEMPT && list_empty(&ready_list)) 160 goto ret_0; 161 162 if (stype == FIBRIL_FROM_MANAGER) { 163 if ((list_empty(&ready_list)) && (list_empty(&serialized_list))) 164 goto ret_0; 165 166 /* 167 * Do not preempt if there is not enough threads to run the 168 * ready fibrils which are not serialized. 169 */ 170 if ((list_empty(&serialized_list)) && 171 (threads_in_manager <= serialized_threads)) { 172 goto ret_0; 150 futex_lock(&fibril_futex); 151 152 switch (stype) { 153 case FIBRIL_PREEMPT: 154 case FIBRIL_FROM_MANAGER: 155 if (list_empty(&ready_list)) { 156 futex_unlock(&fibril_futex); 157 return 0; 173 158 } 174 } 175 176 /* If we are going to manager and none exists, create it */ 177 if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) { 159 break; 160 case FIBRIL_TO_MANAGER: 161 case FIBRIL_FROM_DEAD: 162 /* Make sure the async_futex is held. */ 163 assert((atomic_signed_t) async_futex.val.count <= 0); 164 165 /* If we are going to manager and none exists, create it */ 178 166 while (list_empty(&manager_list)) { 179 167 futex_unlock(&fibril_futex); … … 181 169 futex_lock(&fibril_futex); 182 170 } 171 break; 183 172 } 184 173 … … 188 177 /* Save current state */ 189 178 if (!context_save(&srcf->ctx)) { 190 if (serialization_count)191 srcf->flags &= ~FIBRIL_SERIALIZED;192 193 179 if (srcf->clean_after_me) { 194 180 /* … … 208 194 as_area_destroy(stack); 209 195 } 210 fibril_teardown(srcf->clean_after_me );196 fibril_teardown(srcf->clean_after_me, true); 211 197 srcf->clean_after_me = NULL; 212 198 } … … 215 201 } 216 202 217 /* Save myself to the correct run list */ 218 if (stype == FIBRIL_PREEMPT) 203 /* Put the current fibril into the correct run list */ 204 switch (stype) { 205 case FIBRIL_PREEMPT: 219 206 list_append(&srcf->link, &ready_list); 220 else if (stype == FIBRIL_FROM_MANAGER) { 207 break; 208 case FIBRIL_FROM_MANAGER: 221 209 list_append(&srcf->link, &manager_list); 222 threads_in_manager--; 223 } else { 210 break; 211 default: 212 assert(stype == FIBRIL_TO_MANAGER); 213 224 214 /* 225 * If stype == FIBRIL_TO_MANAGER, don't put ourselves to 226 * any list, we should already be somewhere, or we will 227 * be lost. 215 * Don't put the current fibril into any list, it should 216 * already be somewhere, or it will be lost. 228 217 */ 218 break; 229 219 } 230 220 } 231 221 222 fibril_t *dstf; 223 232 224 /* Choose a new fibril to run */ 233 fibril_t *dstf; 234 if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) { 225 switch (stype) { 226 case FIBRIL_TO_MANAGER: 227 case FIBRIL_FROM_DEAD: 235 228 dstf = list_get_instance(list_first(&manager_list), fibril_t, 236 229 link); 237 if (serialization_count && stype == FIBRIL_TO_MANAGER) {238 serialized_threads++;239 srcf->flags |= FIBRIL_SERIALIZED;240 }241 threads_in_manager++;242 230 243 231 if (stype == FIBRIL_FROM_DEAD) 244 232 dstf->clean_after_me = srcf; 245 } else { 246 if (!list_empty(&serialized_list)) { 247 dstf = list_get_instance(list_first(&serialized_list), 248 fibril_t, link); 249 serialized_threads--; 250 } else { 251 dstf = list_get_instance(list_first(&ready_list), 252 fibril_t, link); 253 } 254 } 233 break; 234 default: 235 dstf = list_get_instance(list_first(&ready_list), fibril_t, 236 link); 237 break; 238 } 239 255 240 list_remove(&dstf->link); 256 241 … … 265 250 context_restore(&dstf->ctx); 266 251 /* not reached */ 267 268 ret_0:269 futex_unlock(&fibril_futex);270 return retval;271 252 } 272 253 … … 294 275 AS_AREA_LATE_RESERVE); 295 276 if (fibril->stack == (void *) -1) { 296 fibril_teardown(fibril );277 fibril_teardown(fibril, false); 297 278 return 0; 298 279 } … … 321 302 322 303 as_area_destroy(fibril->stack); 323 fibril_teardown(fibril );304 fibril_teardown(fibril, false); 324 305 } 325 306 … … 335 316 336 317 futex_lock(&fibril_futex); 337 338 if ((fibril->flags & FIBRIL_SERIALIZED)) 339 list_append(&fibril->link, &serialized_list); 340 else 341 list_append(&fibril->link, &ready_list); 342 318 list_append(&fibril->link, &ready_list); 343 319 futex_unlock(&fibril_futex); 344 320 } … … 363 339 { 364 340 futex_lock(&fibril_futex); 365 366 341 if (!list_empty(&manager_list)) 367 342 list_remove(list_first(&manager_list)); 368 369 343 futex_unlock(&fibril_futex); 370 344 } … … 380 354 } 381 355 382 /** Disable preemption383 *384 * If the fibril wants to send several message in a row and does not want to be385 * preempted, it should start async_serialize_start() in the beginning of386 * communication and async_serialize_end() in the end. If it is a true387 * multithreaded application, it should protect the communication channel by a388 * futex as well.389 *390 */391 void fibril_inc_sercount(void)392 {393 serialization_count++;394 }395 396 /** Restore the preemption counter to the previous state. */397 void fibril_dec_sercount(void)398 {399 serialization_count--;400 }401 402 int fibril_get_sercount(void)403 {404 return serialization_count;405 }406 407 356 /** @} 408 357 */ -
uspace/lib/c/generic/fibril_synch.c
rdf2bce32 rfb4d788 105 105 fibril_t *f = (fibril_t *) fibril_get_id(); 106 106 107 if (fibril_get_sercount() != 0)108 abort();109 110 107 futex_down(&async_futex); 111 108 if (fm->counter-- <= 0) { … … 197 194 fibril_t *f = (fibril_t *) fibril_get_id(); 198 195 199 if (fibril_get_sercount() != 0)200 abort();201 202 196 futex_down(&async_futex); 203 197 if (frw->writers) { … … 224 218 fibril_t *f = (fibril_t *) fibril_get_id(); 225 219 226 if (fibril_get_sercount() != 0)227 abort();228 229 220 futex_down(&async_futex); 230 221 if (frw->writers || frw->readers) { … … 461 452 if (rc == ETIMEOUT && timer->state == fts_active) { 462 453 timer->state = fts_fired; 463 timer->handler_ running = true;454 timer->handler_fid = fibril_get_id(); 464 455 fibril_mutex_unlock(timer->lockp); 465 456 timer->fun(timer->arg); 466 457 fibril_mutex_lock(timer->lockp); 467 timer->handler_ running = false;458 timer->handler_fid = 0; 468 459 } 469 460 break; … … 477 468 /* Acknowledge timer fibril has finished cleanup. */ 478 469 timer->state = fts_clean; 470 fibril_condvar_broadcast(&timer->cv); 479 471 fibril_mutex_unlock(timer->lockp); 480 free(timer);481 472 482 473 return 0; … … 525 516 timer->state = fts_cleanup; 526 517 fibril_condvar_broadcast(&timer->cv); 518 519 /* Wait for timer fibril to terminate */ 520 while (timer->state != fts_clean) 521 fibril_condvar_wait(&timer->cv, timer->lockp); 527 522 fibril_mutex_unlock(timer->lockp); 523 524 free(timer); 528 525 } 529 526 … … 608 605 assert(fibril_mutex_is_locked(timer->lockp)); 609 606 610 while (timer->handler_running) 607 while (timer->handler_fid != 0) { 608 if (timer->handler_fid == fibril_get_id()) { 609 printf("Deadlock detected.\n"); 610 stacktrace_print(); 611 printf("Fibril %zx is trying to clear timer %p from " 612 "inside its handler %p.\n", 613 fibril_get_id(), timer, timer->fun); 614 abort(); 615 } 616 611 617 fibril_condvar_wait(&timer->cv, timer->lockp); 618 } 612 619 613 620 old_state = timer->state; -
uspace/lib/c/generic/getopt.c
rdf2bce32 rfb4d788 95 95 * Compute the greatest common divisor of a and b. 96 96 */ 97 static int 98 gcd(a, b) 99 int a; 100 int b; 97 static int gcd(int a, int b) 101 98 { 102 99 int c; 103 100 104 101 c = a % b; 105 102 while (c != 0) { … … 108 105 c = a % b; 109 106 } 110 107 111 108 return b; 112 109 } … … 117 114 * in each block). 118 115 */ 119 static void 120 permute_args(panonopt_start, panonopt_end, opt_end, nargv) 121 int panonopt_start; 122 int panonopt_end; 123 int opt_end; 124 char **nargv; 116 static void permute_args(int panonopt_start, int panonopt_end, int opt_end, 117 char **nargv) 125 118 { 126 119 int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; … … 157 150 * Returns -2 if -- is found (can be long option or end of options marker). 158 151 */ 159 static int 160 getopt_internal(nargc, nargv, options) 161 int nargc; 162 char **nargv; 163 const char *options; 152 static int getopt_internal(int nargc, char **nargv, const char *options) 164 153 { 165 154 const char *oli; /* option letter list index */ … … 299 288 * Parse argc/argv argument vector. 300 289 */ 301 int 302 getopt(nargc, nargv, options) 303 int nargc; 304 char * const *nargv; 305 const char *options; 290 int getopt(int nargc, char * const *nargv, const char *options) 306 291 { 307 292 int retval; … … 332 317 * Parse argc/argv argument vector. 333 318 */ 334 int 335 getopt_long(nargc, nargv, options, long_options, idx) 336 int nargc; 337 char * const *nargv; 338 const char *options; 339 const struct option *long_options; 340 int *idx; 319 int getopt_long(int nargc, char * const *nargv, const char *options, 320 const struct option *long_options, int *idx) 341 321 { 342 322 int retval; -
uspace/lib/c/generic/inet.c
rdf2bce32 rfb4d788 177 177 178 178 dgram.tos = IPC_GET_ARG1(*icall); 179 dgram.iplink = IPC_GET_ARG2(*icall); 179 180 180 181 ipc_callid_t callid; -
uspace/lib/c/generic/inet/addr.c
rdf2bce32 rfb4d788 1 1 /* 2 2 * Copyright (c) 2013 Jiri Svoboda 3 * Copyright (c) 2013 Martin Decky 3 4 * All rights reserved. 4 5 * … … 36 37 #include <errno.h> 37 38 #include <unistd.h> 38 #include <net/socket_codes.h>39 39 #include <inet/addr.h> 40 #include <net/inet.h>41 40 #include <stdio.h> 42 41 #include <malloc.h> … … 44 43 45 44 #define INET_PREFIXSTRSIZE 5 45 46 #define INET6_ADDRSTRLEN (8 * 4 + 7 + 1) 46 47 47 48 #if !(defined(__BE__) ^ defined(__LE__)) … … 180 181 } 181 182 182 /** Determine address version.183 *184 * @param text Address in common notation.185 * @param af Place to store address version.186 *187 * @return EOK on success, EINVAL if input is not in valid format.188 *189 */190 static int inet_addr_version(const char *text, ip_ver_t *ver)191 {192 char *dot = str_chr(text, '.');193 if (dot != NULL) {194 *ver = ip_v4;195 return EOK;196 }197 198 char *collon = str_chr(text, ':');199 if (collon != NULL) {200 *ver = ip_v6;201 return EOK;202 }203 204 return EINVAL;205 }206 207 static int ipver_af(ip_ver_t ver)208 {209 switch (ver) {210 case ip_any:211 return AF_NONE;212 case ip_v4:213 return AF_INET;214 case ip_v6:215 return AF_INET6;216 default:217 assert(false);218 return EINVAL;219 }220 }221 222 ip_ver_t ipver_from_af(int af)223 {224 switch (af) {225 case AF_NONE:226 return ip_any;227 case AF_INET:228 return ip_v4;229 case AF_INET6:230 return ip_v6;231 default:232 assert(false);233 return EINVAL;234 }235 }236 237 183 void inet_naddr_addr(const inet_naddr_t *naddr, inet_addr_t *addr) 238 184 { … … 288 234 if (naddr->version != addr->version) 289 235 return 0; 290 236 291 237 switch (naddr->version) { 292 238 case ip_v4: … … 315 261 if (naddr->prefix > 128) 316 262 return 0; 317 263 318 264 size_t pos = 0; 319 265 for (size_t i = 0; i < 16; i++) { … … 321 267 if (naddr->prefix < pos) 322 268 break; 323 269 324 270 if (naddr->prefix - pos > 8) { 325 271 /* Comparison without masking */ … … 333 279 return 0; 334 280 } 335 281 336 282 pos += 8; 337 283 } 338 284 339 285 return 1; 340 286 default: … … 343 289 } 344 290 291 static int inet_addr_parse_v4(const char *str, inet_addr_t *raddr, 292 int *prefix) 293 { 294 uint32_t a = 0; 295 uint8_t b; 296 char *cur = (char *)str; 297 size_t i = 0; 298 299 while (i < 4) { 300 int rc = str_uint8_t(cur, (const char **)&cur, 10, false, &b); 301 if (rc != EOK) 302 return rc; 303 304 a = (a << 8) + b; 305 306 i++; 307 308 if (*cur == '\0' || *cur == '/') 309 break; 310 311 if (*cur != '.') 312 return EINVAL; 313 314 if (i < 4) 315 cur++; 316 } 317 318 if (prefix != NULL) { 319 if (*cur != '/') 320 return EINVAL; 321 cur++; 322 323 *prefix = strtoul(cur, &cur, 10); 324 if (*prefix > 32) 325 return EINVAL; 326 } 327 328 if (i != 4 || (*cur != '\0')) 329 return EINVAL; 330 331 raddr->version = ip_v4; 332 raddr->addr = a; 333 334 return EOK; 335 } 336 337 static int inet_addr_parse_v6(const char *str, inet_addr_t *raddr, int *prefix) 338 { 339 uint8_t data[16]; 340 341 memset(data, 0, 16); 342 343 const char *cur = str; 344 size_t i = 0; 345 size_t wildcard_pos = (size_t) -1; 346 size_t wildcard_size = 0; 347 348 /* Handle initial wildcard */ 349 if ((str[0] == ':') && (str[1] == ':')) { 350 cur = str + 2; 351 wildcard_pos = 0; 352 wildcard_size = 16; 353 354 /* Handle the unspecified address */ 355 if (*cur == '\0') 356 goto success; 357 } 358 359 while (i < 16) { 360 uint16_t bioctet; 361 int rc = str_uint16_t(cur, &cur, 16, false, &bioctet); 362 if (rc != EOK) 363 return rc; 364 365 data[i] = (bioctet >> 8) & 0xff; 366 data[i + 1] = bioctet & 0xff; 367 368 if (wildcard_pos != (size_t) -1) { 369 if (wildcard_size < 2) 370 return EINVAL; 371 372 wildcard_size -= 2; 373 } 374 375 i += 2; 376 377 if (*cur != ':') 378 break; 379 380 if (i < 16) { 381 cur++; 382 383 /* Handle wildcard */ 384 if (*cur == ':') { 385 if (wildcard_pos != (size_t) -1) 386 return EINVAL; 387 388 wildcard_pos = i; 389 wildcard_size = 16 - i; 390 cur++; 391 392 if (*cur == '\0' || *cur == '/') 393 break; 394 } 395 } 396 } 397 398 if (prefix != NULL) { 399 if (*cur != '/') 400 return EINVAL; 401 cur++; 402 403 *prefix = strtoul(cur, (char **)&cur, 10); 404 if (*prefix > 128) 405 return EINVAL; 406 } 407 408 if (*cur != '\0') 409 return EINVAL; 410 411 /* Create wildcard positions */ 412 if ((wildcard_pos != (size_t) -1) && (wildcard_size > 0)) { 413 size_t wildcard_shift = 16 - wildcard_size; 414 415 for (i = wildcard_pos + wildcard_shift; i > wildcard_pos; i--) { 416 size_t j = i - 1; 417 data[j + wildcard_size] = data[j]; 418 data[j] = 0; 419 } 420 } 421 422 success: 423 raddr->version = ip_v6; 424 memcpy(raddr->addr6, data, 16); 425 return EOK; 426 } 427 345 428 /** Parse node address. 346 429 * … … 353 436 int inet_addr_parse(const char *text, inet_addr_t *addr) 354 437 { 355 int rc = inet_addr_version(text, &addr->version); 356 if (rc != EOK) 357 return rc; 358 359 uint8_t buf[16]; 360 rc = inet_pton(ipver_af(addr->version), text, buf); 361 if (rc != EOK) 362 return rc; 363 364 switch (addr->version) { 365 case ip_v4: 366 addr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | 367 buf[3]; 368 break; 369 case ip_v6: 370 memcpy(addr->addr6, buf, 16); 371 break; 372 default: 373 return EINVAL; 374 } 375 376 return EOK; 438 int rc; 439 440 rc = inet_addr_parse_v4(text, addr, NULL); 441 if (rc == EOK) 442 return EOK; 443 444 rc = inet_addr_parse_v6(text, addr, NULL); 445 if (rc == EOK) 446 return EOK; 447 448 return EINVAL; 377 449 } 378 450 … … 387 459 int inet_naddr_parse(const char *text, inet_naddr_t *naddr) 388 460 { 389 char *slash = str_chr(text, '/'); 390 if (slash == NULL) 391 return EINVAL; 392 393 *slash = 0; 394 395 int rc = inet_addr_version(text, &naddr->version); 396 if (rc != EOK) 397 return rc; 398 399 uint8_t buf[16]; 400 rc = inet_pton(ipver_af(naddr->version), text, buf); 401 *slash = '/'; 402 403 if (rc != EOK) 404 return rc; 405 406 slash++; 407 uint8_t prefix; 408 409 switch (naddr->version) { 410 case ip_v4: 411 prefix = strtoul(slash, &slash, 10); 412 if (prefix > 32) 461 int rc; 462 inet_addr_t addr; 463 int prefix; 464 465 rc = inet_addr_parse_v4(text, &addr, &prefix); 466 if (rc == EOK) { 467 inet_addr_naddr(&addr, prefix, naddr); 468 return EOK; 469 } 470 471 rc = inet_addr_parse_v6(text, &addr, &prefix); 472 if (rc == EOK) { 473 inet_addr_naddr(&addr, prefix, naddr); 474 return EOK; 475 } 476 477 return EINVAL; 478 } 479 480 static int inet_addr_format_v4(addr32_t addr, char **bufp) 481 { 482 int rc; 483 484 rc = asprintf(bufp, "%u.%u.%u.%u", (addr >> 24) & 0xff, 485 (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); 486 if (rc < 0) 487 return ENOMEM; 488 489 return EOK; 490 } 491 492 static int inet_addr_format_v6(const addr128_t addr, char **bufp) 493 { 494 *bufp = (char *) malloc(INET6_ADDRSTRLEN); 495 if (*bufp == NULL) 496 return ENOMEM; 497 498 /* Find the longest zero subsequence */ 499 500 uint16_t zeroes[8]; 501 uint16_t bioctets[8]; 502 503 for (size_t i = 8; i > 0; i--) { 504 size_t j = i - 1; 505 506 bioctets[j] = (addr[j << 1] << 8) | addr[(j << 1) + 1]; 507 508 if (bioctets[j] == 0) { 509 zeroes[j] = 1; 510 if (j < 7) 511 zeroes[j] += zeroes[j + 1]; 512 } else 513 zeroes[j] = 0; 514 } 515 516 size_t wildcard_pos = (size_t) -1; 517 size_t wildcard_size = 0; 518 519 for (size_t i = 0; i < 8; i++) { 520 if (zeroes[i] > wildcard_size) { 521 wildcard_pos = i; 522 wildcard_size = zeroes[i]; 523 } 524 } 525 526 char *cur = *bufp; 527 size_t rest = INET6_ADDRSTRLEN; 528 bool tail_zero = false; 529 int ret; 530 531 for (size_t i = 0; i < 8; i++) { 532 if ((i == wildcard_pos) && (wildcard_size > 1)) { 533 ret = snprintf(cur, rest, ":"); 534 i += wildcard_size - 1; 535 tail_zero = true; 536 } else if (i == 0) { 537 ret = snprintf(cur, rest, "%" PRIx16, bioctets[i]); 538 tail_zero = false; 539 } else { 540 ret = snprintf(cur, rest, ":%" PRIx16, bioctets[i]); 541 tail_zero = false; 542 } 543 544 if (ret < 0) 413 545 return EINVAL; 414 415 naddr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | 416 buf[3]; 417 naddr->prefix = prefix; 418 419 break; 420 case ip_v6: 421 prefix = strtoul(slash, &slash, 10); 422 if (prefix > 128) 423 return EINVAL; 424 425 memcpy(naddr->addr6, buf, 16); 426 naddr->prefix = prefix; 427 428 break; 429 default: 430 return ENOTSUP; 431 } 432 546 547 cur += ret; 548 rest -= ret; 549 } 550 551 if (tail_zero) 552 (void) snprintf(cur, rest, ":"); 553 433 554 return EOK; 434 555 } … … 446 567 int inet_addr_format(const inet_addr_t *addr, char **bufp) 447 568 { 448 int rc = 0; 449 569 int rc; 570 571 rc = ENOTSUP; 572 450 573 switch (addr->version) { 451 574 case ip_any: 452 575 rc = asprintf(bufp, "none"); 576 if (rc < 0) 577 return ENOMEM; 578 rc = EOK; 453 579 break; 454 580 case ip_v4: 455 rc = asprintf(bufp, "%u.%u.%u.%u", (addr->addr >> 24) & 0xff, 456 (addr->addr >> 16) & 0xff, (addr->addr >> 8) & 0xff, 457 addr->addr & 0xff); 581 rc = inet_addr_format_v4(addr->addr, bufp); 458 582 break; 459 583 case ip_v6: 460 *bufp = (char *) malloc(INET6_ADDRSTRLEN); 461 if (*bufp == NULL) 462 return ENOMEM; 463 464 return inet_ntop(AF_INET6, addr->addr6, *bufp, INET6_ADDRSTRLEN); 465 default: 466 return ENOTSUP; 467 } 468 469 if (rc < 0) 470 return ENOMEM; 471 472 return EOK; 584 rc = inet_addr_format_v6(addr->addr6, bufp); 585 break; 586 } 587 588 return rc; 473 589 } 474 590 … … 485 601 int inet_naddr_format(const inet_naddr_t *naddr, char **bufp) 486 602 { 487 int rc = 0; 488 char prefix[INET_PREFIXSTRSIZE]; 489 603 int rc; 604 char *astr; 605 606 rc = ENOTSUP; 607 490 608 switch (naddr->version) { 491 609 case ip_any: 492 610 rc = asprintf(bufp, "none"); 611 if (rc < 0) 612 return ENOMEM; 613 rc = EOK; 493 614 break; 494 615 case ip_v4: 495 rc = asprintf(bufp, "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 496 "/%" PRIu8, (naddr->addr >> 24) & 0xff, 497 (naddr->addr >> 16) & 0xff, (naddr->addr >> 8) & 0xff, 498 naddr->addr & 0xff, naddr->prefix); 499 break; 500 case ip_v6: 501 *bufp = (char *) malloc(INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE); 502 if (*bufp == NULL) 616 rc = inet_addr_format_v4(naddr->addr, &astr); 617 if (rc != EOK) 503 618 return ENOMEM; 504 505 rc = inet_ntop(AF_INET6, naddr->addr6, *bufp, 506 INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE); 507 if (rc != EOK) { 508 free(*bufp); 509 return rc; 510 } 511 512 rc = snprintf(prefix, INET_PREFIXSTRSIZE, "/%" PRIu8, 513 naddr->prefix); 619 620 rc = asprintf(bufp, "%s/%" PRIu8, astr, naddr->prefix); 514 621 if (rc < 0) { 515 free( *bufp);622 free(astr); 516 623 return ENOMEM; 517 624 } 518 519 str_append(*bufp, INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE, prefix); 520 521 break; 522 default: 523 return ENOTSUP; 524 } 525 526 if (rc < 0) 527 return ENOMEM; 528 529 return EOK; 625 626 rc = EOK; 627 break; 628 case ip_v6: 629 rc = inet_addr_format_v6(naddr->addr6, &astr); 630 if (rc != EOK) 631 return ENOMEM; 632 633 rc = asprintf(bufp, "%s/%" PRIu8, astr, naddr->prefix); 634 if (rc < 0) { 635 free(astr); 636 return ENOMEM; 637 } 638 639 rc = EOK; 640 break; 641 } 642 643 return rc; 530 644 } 531 645 … … 586 700 } 587 701 588 void inet_sockaddr_in_addr(const sockaddr_in_t *sockaddr_in, inet_addr_t *addr)589 {590 addr->version = ip_v4;591 addr->addr = uint32_t_be2host(sockaddr_in->sin_addr.s_addr);592 }593 594 702 void inet_addr_set6(addr128_t v6, inet_addr_t *addr) 595 703 { … … 605 713 } 606 714 607 void inet_sockaddr_in6_addr(const sockaddr_in6_t *sockaddr_in6,608 inet_addr_t *addr)609 {610 addr->version = ip_v6;611 addr128_t_be2host(sockaddr_in6->sin6_addr.s6_addr, addr->addr6);612 }613 614 uint16_t inet_addr_sockaddr_in(const inet_addr_t *addr,615 sockaddr_in_t *sockaddr_in, sockaddr_in6_t *sockaddr_in6)616 {617 switch (addr->version) {618 case ip_v4:619 if (sockaddr_in != NULL) {620 sockaddr_in->sin_family = AF_INET;621 sockaddr_in->sin_addr.s_addr = host2uint32_t_be(addr->addr);622 }623 break;624 case ip_v6:625 if (sockaddr_in6 != NULL) {626 sockaddr_in6->sin6_family = AF_INET6;627 host2addr128_t_be(addr->addr6, sockaddr_in6->sin6_addr.s6_addr);628 }629 break;630 default:631 assert(false);632 break;633 }634 635 return ipver_af(addr->version);636 }637 638 int inet_addr_sockaddr(const inet_addr_t *addr, uint16_t port,639 sockaddr_t **nsockaddr, socklen_t *naddrlen)640 {641 sockaddr_in_t *sa4;642 sockaddr_in6_t *sa6;643 644 switch (addr->version) {645 case ip_v4:646 sa4 = calloc(1, sizeof(sockaddr_in_t));647 if (sa4 == NULL)648 return ENOMEM;649 650 sa4->sin_family = AF_INET;651 sa4->sin_port = host2uint16_t_be(port);652 sa4->sin_addr.s_addr = host2uint32_t_be(addr->addr);653 if (nsockaddr != NULL)654 *nsockaddr = (sockaddr_t *)sa4;655 if (naddrlen != NULL)656 *naddrlen = sizeof(*sa4);657 break;658 case ip_v6:659 sa6 = calloc(1, sizeof(sockaddr_in6_t));660 if (sa6 == NULL)661 return ENOMEM;662 663 sa6->sin6_family = AF_INET6;664 sa6->sin6_port = host2uint16_t_be(port);665 host2addr128_t_be(addr->addr6, sa6->sin6_addr.s6_addr);666 if (nsockaddr != NULL)667 *nsockaddr = (sockaddr_t *)sa6;668 if (naddrlen != NULL)669 *naddrlen = sizeof(*sa6);670 break;671 default:672 assert(false);673 break;674 }675 676 return EOK;677 }678 679 715 /** @} 680 716 */ -
uspace/lib/c/generic/inet/endpoint.c
rdf2bce32 rfb4d788 1 1 /* 2 * Copyright (c) 20 09 Lukas Mejdrech2 * Copyright (c) 2015 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup socket29 /** @addtogroup libc 30 30 * @{ 31 31 */ 32 33 /** @file 34 * Command-line argument parsing functions related to networking. 32 /** @file Internet endpoint 35 33 */ 36 34 37 extern int socket_parse_address_family(const char *, int *); 38 extern int socket_parse_protocol_family(const char *, int *); 39 extern int socket_parse_socket_type(const char *, int *); 35 #include <inet/endpoint.h> 36 #include <mem.h> 37 38 void inet_ep_init(inet_ep_t *ep) 39 { 40 memset(ep, 0, sizeof(*ep)); 41 } 42 43 void inet_ep2_init(inet_ep2_t *ep2) 44 { 45 memset(ep2, 0, sizeof(*ep2)); 46 } 40 47 41 48 /** @} -
uspace/lib/c/generic/iplink.c
rdf2bce32 rfb4d788 47 47 static void iplink_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg); 48 48 49 int iplink_open(async_sess_t *sess, iplink_ev_ops_t *ev_ops, 49 int iplink_open(async_sess_t *sess, iplink_ev_ops_t *ev_ops, void *arg, 50 50 iplink_t **riplink) 51 51 { … … 56 56 iplink->sess = sess; 57 57 iplink->ev_ops = ev_ops; 58 iplink->arg = arg; 58 59 59 60 async_exch_t *exch = async_exchange_begin(sess); … … 234 235 235 236 return (int) retval; 237 } 238 239 void *iplink_get_userptr(iplink_t *iplink) 240 { 241 return iplink->arg; 236 242 } 237 243 -
uspace/lib/c/generic/irq.c
rdf2bce32 rfb4d788 35 35 #include <ipc/irq.h> 36 36 #include <libc.h> 37 #include <stdlib.h> 38 #include <macros.h> 39 40 static irq_cmd_t default_cmds[] = { 41 { 42 .cmd = CMD_ACCEPT 43 } 44 }; 45 46 static const irq_code_t default_ucode = { 47 0, 48 NULL, 49 ARRAY_SIZE(default_cmds), 50 default_cmds 51 }; 37 52 38 53 /** Subscribe to IRQ notification. … … 49 64 const irq_code_t *ucode) 50 65 { 66 if (ucode == NULL) 67 ucode = &default_ucode; 68 51 69 return __SYSCALL4(SYS_IPC_IRQ_SUBSCRIBE, inr, devno, method, 52 70 (sysarg_t) ucode); -
uspace/lib/c/generic/libc.c
rdf2bce32 rfb4d788 122 122 __stdio_done(); 123 123 task_retval(status); 124 fibril_teardown(__tcb_get()->fibril_data );124 fibril_teardown(__tcb_get()->fibril_data, false); 125 125 } 126 126 -
uspace/lib/c/generic/thread.c
rdf2bce32 rfb4d788 88 88 #endif 89 89 90 fibril_teardown(fibril );90 fibril_teardown(fibril, false); 91 91 92 92 thread_exit(0); -
uspace/lib/c/include/async.h
rdf2bce32 rfb4d788 108 108 109 109 #define async_manager() \ 110 fibril_switch(FIBRIL_TO_MANAGER) 110 do { \ 111 futex_down(&async_futex); \ 112 fibril_switch(FIBRIL_FROM_DEAD); \ 113 } while (0) 111 114 112 115 #define async_get_call(data) \ -
uspace/lib/c/include/errno.h
rdf2bce32 rfb4d788 68 68 #define ENAK (-303) 69 69 70 /** An API function is called while another blocking function is in progress. */71 #define EINPROGRESS (-10036)72 73 /** The socket identifier is not valid. */74 #define ENOTSOCK (-10038)75 76 /** The destination address required. */77 #define EDESTADDRREQ (-10039)78 79 /** Protocol is not supported. */80 #define EPROTONOSUPPORT (-10043)81 82 /** Socket type is not supported. */83 #define ESOCKTNOSUPPORT (-10044)84 85 /** Protocol family is not supported. */86 #define EPFNOSUPPORT (-10046)87 88 /** Address family is not supported. */89 #define EAFNOSUPPORT (-10047)90 91 /** Address is already in use. */92 #define EADDRINUSE (-10048)93 94 /** The socket is not connected or bound. */95 #define ENOTCONN (-10057)96 97 #define ECONNREFUSED (-10058)98 99 #define ECONNABORTED (-10059)100 101 70 /** The requested operation was not performed. Try again later. */ 102 71 #define EAGAIN (-11002) 103 104 /** No data. */105 #define NO_DATA (-11004)106 72 107 73 #endif -
uspace/lib/c/include/fibril.h
rdf2bce32 rfb4d788 47 47 } while (0) 48 48 49 #define FIBRIL_SERIALIZED 1 50 #define FIBRIL_WRITER 2 49 #define FIBRIL_WRITER 1 51 50 52 51 struct fibril; … … 94 93 extern void fibril_destroy(fid_t fid); 95 94 extern fibril_t *fibril_setup(void); 96 extern void fibril_teardown(fibril_t *f );95 extern void fibril_teardown(fibril_t *f, bool locked); 97 96 extern int fibril_switch(fibril_switch_type_t stype); 98 97 extern void fibril_add_ready(fid_t fid); -
uspace/lib/c/include/fibril_synch.h
rdf2bce32 rfb4d788 135 135 fid_t fibril; 136 136 fibril_timer_state_t state; 137 bool handler_running; 137 /** FID of fibril executing handler or 0 if handler is not running */ 138 fid_t handler_fid; 138 139 139 140 suseconds_t delay; -
uspace/lib/c/include/inet/addr.h
rdf2bce32 rfb4d788 37 37 38 38 #include <stdint.h> 39 #include <net/in.h>40 #include <net/in6.h>41 #include <net/socket.h>42 39 43 40 typedef uint32_t addr32_t; … … 126 123 extern void inet_addr_set(addr32_t, inet_addr_t *); 127 124 extern void inet_naddr_set(addr32_t, uint8_t, inet_naddr_t *); 128 extern void inet_sockaddr_in_addr(const sockaddr_in_t *, inet_addr_t *);129 125 130 126 extern void inet_addr_set6(addr128_t, inet_addr_t *); 131 127 extern void inet_naddr_set6(addr128_t, uint8_t, inet_naddr_t *); 132 extern void inet_sockaddr_in6_addr(const sockaddr_in6_t *, inet_addr_t *);133 134 extern uint16_t inet_addr_sockaddr_in(const inet_addr_t *, sockaddr_in_t *,135 sockaddr_in6_t *);136 137 extern ip_ver_t ipver_from_af(int af);138 extern int inet_addr_sockaddr(const inet_addr_t *, uint16_t, sockaddr_t **,139 socklen_t *);140 128 141 129 #endif -
uspace/lib/c/include/inet/endpoint.h
rdf2bce32 rfb4d788 1 1 /* 2 * Copyright (c) 20 09 Lukas Mejdrech2 * Copyright (c) 2015 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 28 28 29 29 /** @addtogroup libc 30 * @{ 30 * @{ 31 */ 32 /** @file 31 33 */ 32 34 33 /** @file 34 * Character string to integer map. 35 #ifndef LIBC_INET_ASSOC_H_ 36 #define LIBC_INET_ASSOC_H_ 37 38 #include <stdint.h> 39 #include <inet/addr.h> 40 #include <loc.h> 41 42 /** Internet port number ranges 43 * 44 * Port number ranges per RFC 6335 section 6 (Port Number Ranges. 45 * Technically port zero is a system port. But since it is reserved, 46 * we will use it as a special value denoting no port is specified 47 * and we will exclude it from the system port range to disallow 48 * ever assigning it. 35 49 */ 36 37 #ifndef LIBC_CHAR_MAP_H_ 38 #define LIBC_CHAR_MAP_H_ 39 40 #include <libarch/types.h> 41 42 /** Invalid assigned value used also if an entry does not exist. */ 43 #define CHAR_MAP_NULL (-1) 44 45 /** Type definition of the character string to integer map. 46 * @see char_map 47 */ 48 typedef struct char_map char_map_t; 49 50 /** Character string to integer map item. 51 * 52 * This structure recursivelly contains itself as a character by character tree. 53 * The actually mapped character string consists of all the parent characters 54 * and the actual one. 55 */ 56 struct char_map { 57 /** Actually mapped character. */ 58 uint8_t c; 59 /** Stored integral value. */ 60 int value; 61 /** Next character array size. */ 62 int size; 63 /** First free position in the next character array. */ 64 int next; 65 /** Next character array. */ 66 char_map_t **items; 67 /** Consistency check magic value. */ 68 int magic; 50 enum inet_port_ranges { 51 /** Special value meaning no specific port */ 52 inet_port_any = 0, 53 /** Lowest system port (a.k.a. well known port) */ 54 inet_port_sys_lo = 1, 55 /** Highest system port (a.k.a. well known port) */ 56 inet_port_sys_hi = 1023, 57 /** Lowest user port (a.k.a. registered port) */ 58 inet_port_user_lo = 1024, 59 /** Highest user port (a.k.a. registered port) */ 60 inet_port_user_hi = 49151, 61 /** Lowest dynamic port (a.k.a. private or ephemeral port) */ 62 inet_port_dyn_lo = 49152, 63 /** Highest dynamic port (a.k.a. private or ephemeral port) */ 64 inet_port_dyn_hi = 65535 69 65 }; 70 66 71 extern int char_map_initialize(char_map_t *); 72 extern void char_map_destroy(char_map_t *); 73 extern int char_map_exclude(char_map_t *, const uint8_t *, size_t); 74 extern int char_map_add(char_map_t *, const uint8_t *, size_t, const int); 75 extern int char_map_find(const char_map_t *, const uint8_t *, size_t); 76 extern int char_map_update(char_map_t *, const uint8_t *, size_t, const int); 67 /** Internet endpoint (address-port pair), a.k.a. socket */ 68 typedef struct { 69 inet_addr_t addr; 70 uint16_t port; 71 } inet_ep_t; 72 73 /** Internet endpoint pair */ 74 typedef struct { 75 service_id_t local_link; 76 inet_ep_t local; 77 inet_ep_t remote; 78 } inet_ep2_t; 79 80 extern void inet_ep_init(inet_ep_t *); 81 extern void inet_ep2_init(inet_ep2_t *); 77 82 78 83 #endif -
uspace/lib/c/include/inet/iplink.h
rdf2bce32 rfb4d788 44 44 async_sess_t *sess; 45 45 struct iplink_ev_ops *ev_ops; 46 void *arg; 46 47 } iplink_t; 47 48 … … 81 82 } iplink_ev_ops_t; 82 83 83 extern int iplink_open(async_sess_t *, iplink_ev_ops_t *, iplink_t **);84 extern int iplink_open(async_sess_t *, iplink_ev_ops_t *, void *, iplink_t **); 84 85 extern void iplink_close(iplink_t *); 85 86 extern int iplink_send(iplink_t *, iplink_sdu_t *); … … 90 91 extern int iplink_get_mac48(iplink_t *, addr48_t *); 91 92 extern int iplink_set_mac48(iplink_t *, addr48_t); 93 extern void *iplink_get_userptr(iplink_t *); 92 94 93 95 #endif -
uspace/lib/c/include/ipc/services.h
rdf2bce32 rfb4d788 49 49 SERVICE_IRC = FOURCC('i', 'r', 'c', ' '), 50 50 SERVICE_CLIPBOARD = FOURCC('c', 'l', 'i', 'p'), 51 SERVICE_UDP = FOURCC('u', 'd', 'p', ' '),52 SERVICE_TCP = FOURCC('t', 'c', 'p', ' ')53 51 } services_t; 54 52 … … 61 59 #define SERVICE_NAME_INETPING6 "net/inetping6" 62 60 #define SERVICE_NAME_NETCONF "net/netconf" 61 #define SERVICE_NAME_UDP "net/udp" 62 #define SERVICE_NAME_TCP "net/tcp" 63 63 64 64 #endif -
uspace/lib/c/include/ipc/udp.h
rdf2bce32 rfb4d788 1 1 /* 2 * Copyright (c) 20 09 Lukas Mejdrech2 * Copyright (c) 2015 Jiri Svobda 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup libc 30 * @{ 29 /** @addtogroup libcipc 30 * @{ 31 */ 32 /** @file 31 33 */ 32 34 33 /** @file 34 * Internet protocol numbers according to the on-line IANA - Assigned Protocol 35 * numbers: 36 * 37 * http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml 38 */ 35 #ifndef LIBC_IPC_UDP_H_ 36 #define LIBC_IPC_UDP_H_ 39 37 40 #ifndef LIBC_IP_PROTOCOLS_H_ 41 #define LIBC_IP_PROTOCOLS_H_ 38 #include <ipc/common.h> 42 39 43 /** @name IP protocols definitions */ 44 /*@{*/ 40 typedef enum { 41 UDP_CALLBACK_CREATE = IPC_FIRST_USER_METHOD, 42 UDP_ASSOC_CREATE, 43 UDP_ASSOC_DESTROY, 44 UDP_ASSOC_SEND_MSG, 45 UDP_RMSG_INFO, 46 UDP_RMSG_READ, 47 UDP_RMSG_DISCARD 48 } udp_request_t; 45 49 46 #define IPPROTO_ICMP 1 47 #define IPPROTO_TCP 6 48 #define IPPROTO_UDP 17 49 #define IPPROTO_ICMPV6 58 50 51 /*@}*/ 50 typedef enum { 51 UDP_EV_DATA = IPC_FIRST_USER_METHOD 52 } udp_event_t; 52 53 53 54 #endif -
uspace/lib/c/include/malloc.h
rdf2bce32 rfb4d788 44 44 extern void *memalign(const size_t align, const size_t size) 45 45 __attribute__((malloc)); 46 extern void *realloc(const void *addr, const size_t size); 46 extern void *realloc(const void *addr, const size_t size) 47 __attribute__((warn_unused_result)); 47 48 extern void free(const void *addr); 48 49 extern void *heap_check(void); -
uspace/lib/c/include/mem.h
rdf2bce32 rfb4d788 40 40 41 41 extern void *memset(void *, int, size_t) 42 __attribute__((nonnull(1))) 42 43 ATTRIBUTE_OPTIMIZE("-fno-tree-loop-distribute-patterns"); 43 44 extern void *memcpy(void *, const void *, size_t) 45 __attribute__((nonnull(1, 2))) 44 46 ATTRIBUTE_OPTIMIZE("-fno-tree-loop-distribute-patterns"); 45 extern void *memmove(void *, const void *, size_t); 46 extern int memcmp(const void *, const void *, size_t); 47 extern void *memmove(void *, const void *, size_t) 48 __attribute__((nonnull(1, 2))); 49 extern int memcmp(const void *, const void *, size_t) 50 __attribute__((nonnull(1, 2))); 47 51 48 52 #endif -
uspace/lib/c/include/task.h
rdf2bce32 rfb4d788 60 60 extern int task_spawn(task_id_t *, task_wait_t *, const char *path, int, 61 61 va_list ap); 62 extern int task_spawnl(task_id_t *, task_wait_t *, const char *path, ...); 62 extern int task_spawnl(task_id_t *, task_wait_t *, const char *path, ...) 63 __attribute__((sentinel)); 63 64 64 65 extern int task_setup_wait(task_id_t, task_wait_t *);
Note:
See TracChangeset
for help on using the changeset viewer.