|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * bsdsocket.library emulation machine-independent part ! 5: * ! 6: * Copyright 1997, 1998 Mathias Ortmann ! 7: * ! 8: * Library initialization code (c) Tauno Taipaleenmaki ! 9: */ ! 10: ! 11: #include "sysconfig.h" ! 12: #include "sysdeps.h" ! 13: ! 14: #include <assert.h> ! 15: #include <stddef.h> ! 16: ! 17: #include "config.h" ! 18: #include "options.h" ! 19: #include "memory.h" ! 20: #include "custom.h" ! 21: #include "readcpu.h" ! 22: #include "newcpu.h" ! 23: #include "autoconf.h" ! 24: #include "bsdsocket.h" ! 25: #include "osdep/exectasks.h" ! 26: ! 27: #ifdef BSDSOCKET_SUPPORTED ! 28: ! 29: static uae_u32 SockLibBase; ! 30: ! 31: #define SOCKPOOLSIZE 128 ! 32: #define UNIQUE_ID (-1) ! 33: ! 34: /* ObtainSocket()/ReleaseSocket() public socket pool */ ! 35: long sockpoolids[SOCKPOOLSIZE]; ! 36: int sockpoolsocks[SOCKPOOLSIZE]; ! 37: uae_u32 sockpoolflags[SOCKPOOLSIZE]; ! 38: ! 39: long curruniqid = 65536; ! 40: ! 41: /* Memory-related helper functions */ ! 42: static void memcpyha (uae_u32 dst, char *src, int size) ! 43: { ! 44: while (size--) ! 45: put_byte (dst++, *src++); ! 46: } ! 47: ! 48: char *strncpyah (char *dst, uae_u32 src, int size) ! 49: { ! 50: char *res = dst; ! 51: while (size-- && (*dst++ = get_byte (src++))); ! 52: return res; ! 53: } ! 54: ! 55: char *strcpyah (char *dst, uae_u32 src) ! 56: { ! 57: char *res = dst; ! 58: while ((*dst++ = get_byte (src++)) != 0); ! 59: return res; ! 60: } ! 61: ! 62: uae_u32 strcpyha (uae_u32 dst, char *src) ! 63: { ! 64: uae_u32 res = dst; ! 65: ! 66: do { ! 67: put_byte (dst++, *src); ! 68: } while (*src++); ! 69: ! 70: return res; ! 71: } ! 72: ! 73: uae_u32 strncpyha (uae_u32 dst, char *src, int size) ! 74: { ! 75: uae_u32 res = dst; ! 76: while (size--) { ! 77: put_byte (dst++, *src); ! 78: if (!*src++) ! 79: return res; ! 80: } ! 81: return res; ! 82: } ! 83: ! 84: uae_u32 addstr (uae_u32 * dst, char *src) ! 85: { ! 86: uae_u32 res = *dst; ! 87: int len; ! 88: ! 89: len = strlen (src) + 1; ! 90: ! 91: strcpyha (*dst, src); ! 92: (*dst) += len; ! 93: ! 94: return res; ! 95: } ! 96: ! 97: uae_u32 addmem (uae_u32 * dst, char *src, int len) ! 98: { ! 99: uae_u32 res = *dst; ! 100: ! 101: if (!src) ! 102: return 0; ! 103: ! 104: memcpyha (*dst, src, len); ! 105: (*dst) += len; ! 106: ! 107: return res; ! 108: } ! 109: ! 110: /* Get current task */ ! 111: static uae_u32 gettask (void) ! 112: { ! 113: uae_u32 currtask, a1 = m68k_areg (regs, 1); ! 114: ! 115: m68k_areg (regs, 1) = 0; ! 116: currtask = CallLib (get_long (4), -0x126); /* FindTask */ ! 117: ! 118: m68k_areg (regs, 1) = a1; ! 119: ! 120: TRACE (("[%s] ", get_real_address (get_long (currtask + 10)))); ! 121: return currtask; ! 122: } ! 123: ! 124: /* errno/herrno setting */ ! 125: void seterrno (SB, int sb_errno) ! 126: { ! 127: sb->sb_errno = sb_errno; ! 128: ! 129: if (sb->errnoptr) { ! 130: switch (sb->errnosize) { ! 131: case 1: ! 132: put_byte (sb->errnoptr, sb_errno); ! 133: break; ! 134: case 2: ! 135: put_word (sb->errnoptr, sb_errno); ! 136: break; ! 137: case 4: ! 138: put_long (sb->errnoptr, sb_errno); ! 139: } ! 140: } ! 141: } ! 142: ! 143: void setherrno (SB, int sb_herrno) ! 144: { ! 145: sb->sb_herrno = sb_herrno; ! 146: ! 147: if (sb->herrnoptr) { ! 148: switch (sb->herrnosize) { ! 149: case 1: ! 150: put_byte (sb->herrnoptr, sb_herrno); ! 151: break; ! 152: case 2: ! 153: put_word (sb->herrnoptr, sb_herrno); ! 154: break; ! 155: case 4: ! 156: put_long (sb->herrnoptr, sb_herrno); ! 157: } ! 158: } ! 159: } ! 160: ! 161: /* Socket descriptor/opaque socket handle management */ ! 162: int getsd (SB, int s) ! 163: { ! 164: int i; ! 165: int *dt = sb->dtable; ! 166: ! 167: /* return socket descriptor if already exists */ ! 168: for (i = sb->dtablesize; i--;) ! 169: if (dt[i] == s) ! 170: return i + 1; ! 171: ! 172: /* create new table entry */ ! 173: for (i = 0; i < sb->dtablesize; i++) ! 174: if (dt[i] == -1) { ! 175: dt[i] = s; ! 176: sb->ftable[i] = SF_BLOCKING; ! 177: return i + 1; ! 178: } ! 179: /* descriptor table full. */ ! 180: seterrno (sb, 24); /* EMFILE */ ! 181: ! 182: return -1; ! 183: } ! 184: ! 185: int getsock (SB, int sd) ! 186: { ! 187: if ((unsigned int) (sd - 1) >= (unsigned int) sb->dtablesize) { ! 188: TRACE (("Invalid Socket Descriptor (%d)\n", sd)); ! 189: seterrno (sb, 38); /* ENOTSOCK */ ! 190: ! 191: return -1; ! 192: } ! 193: return sb->dtable[sd - 1]; ! 194: } ! 195: ! 196: void releasesock (SB, int sd) ! 197: { ! 198: if ((unsigned int) (sd - 1) < (unsigned int) sb->dtablesize) ! 199: sb->dtable[sd - 1] = -1; ! 200: } ! 201: ! 202: /* Signal queue */ ! 203: /* @@@ TODO: ensure proper interlocking */ ! 204: struct socketbase *sbsigqueue; ! 205: ! 206: void addtosigqueue (SB, int events) ! 207: { ! 208: locksigqueue (); ! 209: ! 210: if (events) ! 211: sb->sigstosend |= sb->eventsigs; ! 212: else ! 213: sb->sigstosend |= ((uae_u32) 1) << sb->signal; ! 214: ! 215: if (!sb->dosignal) { ! 216: sb->nextsig = sbsigqueue; ! 217: sbsigqueue = sb; ! 218: } ! 219: sb->dosignal = 1; ! 220: ! 221: unlocksigqueue (); ! 222: ! 223: INTREQ (0xA000); ! 224: } ! 225: ! 226: static uae_u32 bsdsock_int_handler (void) ! 227: { ! 228: SB; ! 229: ! 230: if (sbsigqueue != NULL) { ! 231: locksigqueue (); ! 232: ! 233: for (sb = sbsigqueue; sb; sb = sb->nextsig) { ! 234: if (sb->dosignal == 1) { ! 235: struct regstruct sbved_regs = regs; ! 236: m68k_areg (regs, 1) = sb->ownertask; ! 237: m68k_dreg (regs, 0) = sb->sigstosend; ! 238: CallLib (get_long (4), -0x144); /* Signal() */ ! 239: ! 240: regs = sbved_regs; ! 241: ! 242: sb->sigstosend = 0; ! 243: } ! 244: sb->dosignal = 0; ! 245: } ! 246: ! 247: sbsigqueue = NULL; ! 248: unlocksigqueue (); ! 249: } ! 250: return 0; ! 251: } ! 252: ! 253: void waitsig (SB) ! 254: { ! 255: m68k_dreg (regs, 0) = (((uae_u32) 1) << sb->signal) | sb->eintrsigs; ! 256: if (CallLib (get_long (4), -0x13e) & sb->eintrsigs) { ! 257: sockabort (sb); ! 258: seterrno (sb, 4); /* EINTR */ ! 259: ! 260: sb->eintr = 1; ! 261: } else ! 262: sb->eintr = 0; ! 263: } ! 264: ! 265: void cancelsig (SB) ! 266: { ! 267: locksigqueue (); ! 268: if (sb->dosignal) ! 269: sb->dosignal = 2; ! 270: unlocksigqueue (); ! 271: ! 272: m68k_dreg (regs, 0) = 0; ! 273: m68k_dreg (regs, 1) = ((uae_u32) 1) << sb->signal; ! 274: CallLib (get_long (4), -0x132); /* SetSignal() */ ! 275: ! 276: } ! 277: ! 278: /* Allocate and initialize per-task state structure */ ! 279: static struct socketbase *alloc_socketbase (void) ! 280: { ! 281: SB; ! 282: int i; ! 283: ! 284: if ((sb = calloc (sizeof (struct socketbase), 1)) != NULL) { ! 285: sb->ownertask = gettask (); ! 286: ! 287: m68k_dreg (regs, 0) = -1; ! 288: sb->signal = CallLib (get_long (4), -0x14A); ! 289: ! 290: if (sb->signal == -1) { ! 291: write_log ("bsdsocket: ERROR: Couldn't allocate signal for task 0x%lx.\n", sb->ownertask); ! 292: free (sb); ! 293: return NULL; ! 294: } ! 295: m68k_dreg (regs, 0) = SCRATCHBUFSIZE; ! 296: m68k_dreg (regs, 1) = 0; ! 297: ! 298: sb->dtablesize = DEFAULT_DTABLE_SIZE; ! 299: /* @@@ check malloc() result */ ! 300: sb->dtable = malloc (sb->dtablesize * sizeof (*sb->dtable)); ! 301: sb->ftable = malloc (sb->dtablesize * sizeof (*sb->ftable)); ! 302: ! 303: for (i = sb->dtablesize; i--;) ! 304: sb->dtable[i] = -1; ! 305: ! 306: sb->eintrsigs = 0x1000; /* SIGBREAKF_CTRL_C */ ! 307: ! 308: if (!host_sbinit (sb)) { ! 309: /* @@@ free everything */ ! 310: } ! 311: if (socketbases) ! 312: sb->next = socketbases; ! 313: socketbases = sb; ! 314: ! 315: return sb; ! 316: } ! 317: return NULL; ! 318: } ! 319: ! 320: struct socketbase *get_socketbase (void) ! 321: { ! 322: /* @@@ make portable for sizeof(void *) != sizeof(uae_u32) */ ! 323: return (struct socketbase *) get_long (m68k_areg (regs, 6) + offsetof (struct UAEBSDBase, sb)); ! 324: } ! 325: ! 326: static void free_socketbase (void) ! 327: { ! 328: struct socketbase *sb, *nsb; ! 329: int i; ! 330: ! 331: if ((sb = get_socketbase ()) != NULL) { ! 332: m68k_dreg (regs, 0) = sb->signal; ! 333: CallLib (get_long (4), -0x150); /* FreeSignal */ ! 334: ! 335: if (sb->hostent) { ! 336: m68k_areg (regs, 1) = sb->hostent; ! 337: m68k_dreg (regs, 0) = sb->hostentsize; ! 338: CallLib (get_long (4), -0xD2); /* FreeMem */ ! 339: ! 340: } ! 341: if (sb->protoent) { ! 342: m68k_areg (regs, 1) = sb->protoent; ! 343: m68k_dreg (regs, 0) = sb->protoentsize; ! 344: CallLib (get_long (4), -0xD2); /* FreeMem */ ! 345: ! 346: } ! 347: if (sb->servent) { ! 348: m68k_areg (regs, 1) = sb->servent; ! 349: m68k_dreg (regs, 0) = sb->serventsize; ! 350: CallLib (get_long (4), -0xD2); /* FreeMem */ ! 351: ! 352: } ! 353: host_sbcleanup (sb); ! 354: ! 355: free (sb->dtable); ! 356: free (sb->ftable); ! 357: ! 358: locksigqueue (); ! 359: ! 360: if (sb == socketbases) ! 361: socketbases = sb->next; ! 362: else { ! 363: for (nsb = socketbases; nsb; nsb = nsb->next) { ! 364: if (sb == nsb->next) { ! 365: nsb->next = sb->next; ! 366: break; ! 367: } ! 368: } ! 369: } ! 370: ! 371: if (sb == sbsigqueue) ! 372: sbsigqueue = sb->next; ! 373: else { ! 374: for (nsb = sbsigqueue; nsb; nsb = nsb->next) { ! 375: if (sb == nsb->next) { ! 376: nsb->next = sb->next; ! 377: break; ! 378: } ! 379: } ! 380: } ! 381: ! 382: unlocksigqueue (); ! 383: ! 384: free (sb); ! 385: } ! 386: } ! 387: ! 388: static uae_u32 bsdsocklib_Expunge (void) ! 389: { ! 390: TRACE (("Expunge() -> [ignored]\n")); ! 391: return 0; ! 392: } ! 393: ! 394: static uae_u32 functable, datatable, inittable; ! 395: ! 396: #define SOCKETBASE get_socketbase() ! 397: ! 398: static uae_u32 bsdsocklib_Open (void) ! 399: { ! 400: uae_u32 result = 0; ! 401: int opencount; ! 402: SB; ! 403: ! 404: locksigqueue (); ! 405: ! 406: TRACE (("OpenLibrary() -> ")); ! 407: ! 408: if ((sb = alloc_socketbase ()) != NULL) { ! 409: put_word (SockLibBase + 32, opencount = get_word (SockLibBase + 32) + 1); ! 410: ! 411: m68k_areg (regs, 0) = functable; ! 412: m68k_areg (regs, 1) = datatable; ! 413: m68k_areg (regs, 2) = 0; ! 414: m68k_dreg (regs, 0) = sizeof (struct UAEBSDBase); ! 415: m68k_dreg (regs, 1) = 0; ! 416: result = CallLib (get_long (4), -0x54); ! 417: ! 418: /* @@@ make portable for sizeof(void *) != sizeof(uae_u32) */ ! 419: put_long (result + offsetof (struct UAEBSDBase, sb), (uae_u32) sb); ! 420: ! 421: TRACE (("%0lx [%d]\n", result, opencount)); ! 422: } else ! 423: TRACE (("failed (out of memory)\n")); ! 424: ! 425: unlocksigqueue (); ! 426: ! 427: return result; ! 428: } ! 429: ! 430: static uae_u32 bsdsocklib_Close (void) ! 431: { ! 432: int opencount; ! 433: ! 434: uae_u32 base = m68k_areg (regs, 6); ! 435: uae_u32 negsize = get_word (base + 16); ! 436: ! 437: free_socketbase (); ! 438: ! 439: put_word (SockLibBase + 32, opencount = get_word (SockLibBase + 32) - 1); ! 440: ! 441: m68k_areg (regs, 1) = base - negsize; ! 442: m68k_dreg (regs, 0) = negsize + get_word (base + 18); ! 443: CallLib (get_long (4), -0xD2); /* FreeMem */ ! 444: ! 445: TRACE (("CloseLibrary() -> [%d]\n", opencount)); ! 446: ! 447: return 0; ! 448: } ! 449: ! 450: /* socket(domain, type, protocol)(d0/d1/d2) */ ! 451: static uae_u32 bsdsocklib_socket (void) ! 452: { ! 453: return host_socket (SOCKETBASE, m68k_dreg (regs, 0), m68k_dreg (regs, 1), ! 454: m68k_dreg (regs, 2)); ! 455: } ! 456: ! 457: /* bind(s, name, namelen)(d0/a0/d1) */ ! 458: static uae_u32 bsdsocklib_bind (void) ! 459: { ! 460: return host_bind (SOCKETBASE, m68k_dreg (regs, 0), m68k_areg (regs, 0), ! 461: m68k_dreg (regs, 1)); ! 462: } ! 463: ! 464: /* listen(s, backlog)(d0/d1) */ ! 465: static uae_u32 bsdsocklib_listen (void) ! 466: { ! 467: return host_listen (SOCKETBASE, m68k_dreg (regs, 0), m68k_dreg (regs, 1)); ! 468: } ! 469: ! 470: /* accept(s, addr, addrlen)(d0/a0/a1) */ ! 471: static uae_u32 bsdsocklib_accept (void) ! 472: { ! 473: SB = get_socketbase (); ! 474: host_accept (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1)); ! 475: return sb->resultval; ! 476: } ! 477: ! 478: /* connect(s, name, namelen)(d0/a0/d1) */ ! 479: static uae_u32 bsdsocklib_connect (void) ! 480: { ! 481: SB = get_socketbase (); ! 482: host_connect (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1)); ! 483: return sb->sb_errno ? -1 : 0; ! 484: } ! 485: ! 486: /* sendto(s, msg, len, flags, to, tolen)(d0/a0/d1/d2/a1/d3) */ ! 487: static uae_u32 bsdsocklib_sendto (void) ! 488: { ! 489: SB = get_socketbase (); ! 490: host_sendto (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1), ! 491: m68k_dreg (regs, 2), m68k_areg (regs, 1), m68k_dreg (regs, 3)); ! 492: return sb->resultval; ! 493: } ! 494: ! 495: /* send(s, msg, len, flags)(d0/a0/d1/d2) */ ! 496: static uae_u32 bsdsocklib_send (void) ! 497: { ! 498: SB = get_socketbase (); ! 499: host_sendto (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1), ! 500: m68k_dreg (regs, 2), 0, 0); ! 501: return sb->resultval; ! 502: } ! 503: ! 504: /* recvfrom(s, buf, len, flags, from, fromlen)(d0/a0/d1/d2/a1/a2) */ ! 505: static uae_u32 bsdsocklib_recvfrom (void) ! 506: { ! 507: SB = get_socketbase (); ! 508: host_recvfrom (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1), ! 509: m68k_dreg (regs, 2), m68k_areg (regs, 1), m68k_areg (regs, 2)); ! 510: return sb->resultval; ! 511: } ! 512: ! 513: /* recv(s, buf, len, flags)(d0/a0/d1/d2) */ ! 514: static uae_u32 bsdsocklib_recv (void) ! 515: { ! 516: SB = get_socketbase (); ! 517: host_recvfrom (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_dreg (regs, 1), ! 518: m68k_dreg (regs, 2), 0, 0); ! 519: return sb->resultval; ! 520: } ! 521: ! 522: /* shutdown(s, how)(d0/d1) */ ! 523: static uae_u32 bsdsocklib_shutdown (void) ! 524: { ! 525: return host_shutdown (SOCKETBASE, m68k_dreg (regs, 0), m68k_dreg (regs, 1)); ! 526: } ! 527: ! 528: /* setsockopt(s, level, optname, optval, optlen)(d0/d1/d2/a0/d3) */ ! 529: static uae_u32 bsdsocklib_setsockopt (void) ! 530: { ! 531: SB = get_socketbase (); ! 532: host_setsockopt (sb, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2), ! 533: m68k_areg (regs, 0), m68k_dreg (regs, 3)); ! 534: return sb->resultval; ! 535: } ! 536: ! 537: /* getsockopt(s, level, optname, optval, optlen)(d0/d1/d2/a0/a1) */ ! 538: static uae_u32 bsdsocklib_getsockopt (void) ! 539: { ! 540: return host_getsockopt (SOCKETBASE, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2), ! 541: m68k_areg (regs, 0), m68k_areg (regs, 1)); ! 542: } ! 543: ! 544: /* getsockname(s, hostname, namelen)(d0/a0/a1) */ ! 545: static uae_u32 bsdsocklib_getsockname (void) ! 546: { ! 547: return host_getsockname (SOCKETBASE, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1)); ! 548: } ! 549: ! 550: /* getpeername(s, hostname, namelen)(d0/a0/a1) */ ! 551: static uae_u32 bsdsocklib_getpeername (void) ! 552: { ! 553: return host_getpeername (SOCKETBASE, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1)); ! 554: } ! 555: ! 556: /* *------ generic system calls related to sockets */ ! 557: /* IoctlSocket(d, request, argp)(d0/d1/a0) */ ! 558: static uae_u32 bsdsocklib_IoctlSocket (void) ! 559: { ! 560: return host_IoctlSocket (SOCKETBASE, m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_areg (regs, 0)); ! 561: } ! 562: ! 563: /* *------ AmiTCP/IP specific stuff */ ! 564: /* CloseSocket(d)(d0) */ ! 565: static uae_u32 bsdsocklib_CloseSocket (void) ! 566: { ! 567: return host_CloseSocket (SOCKETBASE, m68k_dreg (regs, 0)); ! 568: } ! 569: ! 570: /* WaitSelect(nfds, readfds, writefds, execptfds, timeout, maskp)(d0/a0/a1/a2/a3/d1) */ ! 571: static uae_u32 bsdsocklib_WaitSelect (void) ! 572: { ! 573: SB = get_socketbase (); ! 574: host_WaitSelect (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), m68k_areg (regs, 1), ! 575: m68k_areg (regs, 2), m68k_areg (regs, 3), m68k_dreg (regs, 1)); ! 576: return sb->resultval; ! 577: } ! 578: ! 579: /* SetSocketSignals(SIGINTR, SIGIO, SIGURG)(d0/d1/d2) */ ! 580: static uae_u32 bsdsocklib_SetSocketSignals (void) ! 581: { ! 582: SB = get_socketbase (); ! 583: ! 584: TRACE (("SetSocketSignals(0x%08lx,0x%08lx,0x%08lx) -> ", m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2))); ! 585: sb->eintrsigs = m68k_dreg (regs, 0); ! 586: sb->eventsigs = m68k_dreg (regs, 1); ! 587: ! 588: return 0; ! 589: } ! 590: ! 591: /* SetDTableSize(size)(d0) */ ! 592: static uae_u32 bsdsocklib_SetDTableSize (void) ! 593: { ! 594: write_log ("bsdsocket: UNSUPPORTED: SetDTableSize()\n"); ! 595: return 0; ! 596: } ! 597: ! 598: static int sockpoolindex (long id) ! 599: { ! 600: int i; ! 601: ! 602: for (i = 0; i < SOCKPOOLSIZE; i++) ! 603: if (sockpoolids[i] == id) ! 604: return i; ! 605: ! 606: return -1; ! 607: } ! 608: ! 609: /* ObtainSocket(id, domain, type, protocol)(d0/d1/d2/d3) */ ! 610: static uae_u32 bsdsocklib_ObtainSocket (void) ! 611: { ! 612: SB = SOCKETBASE; ! 613: int sd; ! 614: long id; ! 615: int s; ! 616: int i; ! 617: ! 618: id = m68k_dreg (regs, 0); ! 619: ! 620: TRACE (("ReleaseSocket(%d,%d,%d,%d) -> ", id, m68k_dreg (regs, 1), m68k_dreg (regs, 2), m68k_dreg (regs, 3))); ! 621: ! 622: i = sockpoolindex (id); ! 623: ! 624: if (i == -1) { ! 625: TRACE (("[invalid key]\n")); ! 626: return -1; ! 627: } ! 628: s = sockpoolsocks[i]; ! 629: ! 630: sd = getsd (sb, s); ! 631: sb->ftable[sd - 1] = sockpoolflags[i]; ! 632: ! 633: TRACE (("%d\n", sd)); ! 634: ! 635: sockpoolids[i] = UNIQUE_ID; ! 636: ! 637: return sd; ! 638: } ! 639: ! 640: /* ReleaseSocket(fd, id)(d0/d1) */ ! 641: static uae_u32 bsdsocklib_ReleaseSocket (void) ! 642: { ! 643: SB = SOCKETBASE; ! 644: int sd; ! 645: long id; ! 646: int s; ! 647: int i; ! 648: uae_u32 flags; ! 649: ! 650: sd = m68k_dreg (regs, 0); ! 651: id = m68k_dreg (regs, 1); ! 652: ! 653: TRACE (("ReleaseSocket(%d,%d) -> ", sd, id)); ! 654: ! 655: s = getsock (sb, sd); ! 656: ! 657: if (s != -1) { ! 658: flags = sb->ftable[sd - 1]; ! 659: ! 660: if (flags & REP_ALL) { ! 661: write_log ("bsdsocket: ERROR: ReleaseSocket() is not supported for sockets with async event notification enabled!\n"); ! 662: return -1; ! 663: } ! 664: releasesock (sb, sd); ! 665: ! 666: if (id == UNIQUE_ID) { ! 667: for (;;) { ! 668: if (sockpoolindex (curruniqid) == -1) ! 669: break; ! 670: curruniqid += 129; ! 671: if ((unsigned long) (curruniqid + 1) < 65536) ! 672: curruniqid += 65537; ! 673: } ! 674: ! 675: id = curruniqid; ! 676: } else if (id < 0 && id > 65535) { ! 677: if (sockpoolindex (id) != -1) { ! 678: TRACE (("[unique ID already exists]\n")); ! 679: return -1; ! 680: } ! 681: } ! 682: i = sockpoolindex (-1); ! 683: ! 684: if (i == -1) { ! 685: TRACE (("-1\n")); ! 686: write_log (("bsdsocket: ERROR: Global socket pool overflow\n")); ! 687: return -1; ! 688: } ! 689: sockpoolids[i] = id; ! 690: sockpoolsocks[i] = s; ! 691: sockpoolflags[i] = flags; ! 692: ! 693: TRACE (("%d\n", id)); ! 694: } else { ! 695: TRACE (("[invalid socket descriptor]\n")); ! 696: return -1; ! 697: } ! 698: ! 699: return id; ! 700: } ! 701: ! 702: /* ReleaseCopyOfSocket(fd, id)(d0/d1) */ ! 703: static uae_u32 bsdsocklib_ReleaseCopyOfSocket (void) ! 704: { ! 705: write_log ("bsdsocket: UNSUPPORTED: ReleaseCopyOfSocket()\n"); ! 706: return 0; ! 707: } ! 708: ! 709: /* Errno()() */ ! 710: static uae_u32 bsdsocklib_Errno (void) ! 711: { ! 712: SB = get_socketbase (); ! 713: TRACE (("Errno() -> %d\n", sb->sb_errno)); ! 714: return sb->sb_errno; ! 715: } ! 716: ! 717: /* SetErrnoPtr(errno_p, size)(a0/d0) */ ! 718: static uae_u32 bsdsocklib_SetErrnoPtr (void) ! 719: { ! 720: SB = get_socketbase (); ! 721: uae_u32 errnoptr = m68k_areg (regs, 0), size = m68k_dreg (regs, 0); ! 722: ! 723: TRACE (("SetErrnoPtr(0x%lx,%d) -> ", errnoptr, size)); ! 724: ! 725: if (size == 1 || size == 2 || size == 4) { ! 726: sb->errnoptr = errnoptr; ! 727: sb->errnosize = size; ! 728: TRACE (("OK\n")); ! 729: return 0; ! 730: } ! 731: seterrno (sb, 22); /* EINVAL */ ! 732: ! 733: return -1; ! 734: } ! 735: ! 736: /* *------ inet library calls related to inet address manipulation */ ! 737: /* Inet_NtoA(in)(d0) */ ! 738: static uae_u32 bsdsocklib_Inet_NtoA (void) ! 739: { ! 740: return host_Inet_NtoA (SOCKETBASE, m68k_dreg (regs, 0)); ! 741: } ! 742: ! 743: /* inet_addr(cp)(a0) */ ! 744: static uae_u32 bsdsocklib_inet_addr (void) ! 745: { ! 746: return host_inet_addr (m68k_areg (regs, 0)); ! 747: } ! 748: ! 749: /* Inet_LnaOf(in)(d0) */ ! 750: static uae_u32 bsdsocklib_Inet_LnaOf (void) ! 751: { ! 752: write_log ("bsdsocket: UNSUPPORTED: Inet_LnaOf()\n"); ! 753: return 0; ! 754: } ! 755: ! 756: /* Inet_NetOf(in)(d0) */ ! 757: static uae_u32 bsdsocklib_Inet_NetOf (void) ! 758: { ! 759: write_log ("bsdsocket: UNSUPPORTED: Inet_NetOf()\n"); ! 760: return 0; ! 761: } ! 762: ! 763: /* Inet_MakeAddr(net, host)(d0/d1) */ ! 764: static uae_u32 bsdsocklib_Inet_MakeAddr (void) ! 765: { ! 766: write_log ("bsdsocket: UNSUPPORTED: Inet_MakeAddr()\n"); ! 767: return 0; ! 768: } ! 769: ! 770: /* inet_network(cp)(a0) */ ! 771: static uae_u32 bsdsocklib_inet_network (void) ! 772: { ! 773: return host_inet_addr (m68k_areg (regs, 0)); ! 774: } ! 775: ! 776: /* *------ gethostbyname etc */ ! 777: /* gethostbyname(name)(a0) */ ! 778: static uae_u32 bsdsocklib_gethostbyname (void) ! 779: { ! 780: SB = get_socketbase (); ! 781: host_gethostbynameaddr (sb, m68k_areg (regs, 0), 0, -1); ! 782: return sb->sb_errno ? 0 : sb->hostent; ! 783: } ! 784: ! 785: /* gethostbyaddr(addr, len, type)(a0/d0/d1) */ ! 786: static uae_u32 bsdsocklib_gethostbyaddr (void) ! 787: { ! 788: SB = get_socketbase (); ! 789: host_gethostbynameaddr (sb, m68k_areg (regs, 0), m68k_dreg (regs, 0), m68k_dreg (regs, 1)); ! 790: return sb->sb_errno ? 0 : sb->hostent; ! 791: } ! 792: ! 793: /* getnetbyname(name)(a0) */ ! 794: static uae_u32 bsdsocklib_getnetbyname (void) ! 795: { ! 796: write_log ("bsdsocket: UNSUPPORTED: getnetbyname()\n"); ! 797: return 0; ! 798: } ! 799: ! 800: /* getnetbyaddr(net, type)(d0/d1) */ ! 801: static uae_u32 bsdsocklib_getnetbyaddr (void) ! 802: { ! 803: write_log ("bsdsocket: UNSUPPORTED: getnetbyaddr()\n"); ! 804: return 0; ! 805: } ! 806: ! 807: /* getservbyname(name, proto)(a0/a1) */ ! 808: static uae_u32 bsdsocklib_getservbyname (void) ! 809: { ! 810: SB = get_socketbase (); ! 811: host_getservbynameport (sb, m68k_areg (regs, 0), m68k_areg (regs, 1), 0); ! 812: return sb->sb_errno ? 0 : sb->servent; ! 813: } ! 814: ! 815: /* getservbyport(port, proto)(d0/a0) */ ! 816: static uae_u32 bsdsocklib_getservbyport (void) ! 817: { ! 818: SB = get_socketbase (); ! 819: host_getservbynameport (sb, m68k_dreg (regs, 0), m68k_areg (regs, 0), 1); ! 820: return sb->sb_errno ? 0 : sb->servent; ! 821: } ! 822: ! 823: /* getprotobyname(name)(a0) */ ! 824: static uae_u32 bsdsocklib_getprotobyname (void) ! 825: { ! 826: SB = get_socketbase (); ! 827: host_getprotobyname (sb, m68k_areg (regs, 0)); ! 828: return sb->sb_errno ? 0 : sb->protoent; ! 829: } ! 830: ! 831: /* getprotobynumber(proto)(d0) */ ! 832: static uae_u32 bsdsocklib_getprotobynumber (void) ! 833: { ! 834: write_log ("bsdsocket: UNSUPPORTED: getprotobynumber()\n"); ! 835: return 0; ! 836: } ! 837: ! 838: /* *------ syslog functions */ ! 839: /* Syslog(level, format, ap)(d0/a0/a1) */ ! 840: static uae_u32 bsdsocklib_vsyslog (void) ! 841: { ! 842: write_log ("bsdsocket: UNSUPPORTED: vsyslog()\n"); ! 843: return 0; ! 844: } ! 845: ! 846: /* *------ AmiTCP/IP 1.1 extensions */ ! 847: /* Dup2Socket(fd1, fd2)(d0/d1) */ ! 848: static uae_u32 bsdsocklib_Dup2Socket (void) ! 849: { ! 850: write_log ("bsdsocket: UNSUPPORTED: Dup2Socket()\n"); ! 851: return 0; ! 852: } ! 853: ! 854: static uae_u32 bsdsocklib_sendmsg (void) ! 855: { ! 856: write_log ("bsdsocket: UNSUPPORTED: sendmsg()\n"); ! 857: return 0; ! 858: } ! 859: ! 860: static uae_u32 bsdsocklib_recvmsg (void) ! 861: { ! 862: write_log ("bsdsocket: UNSUPPORTED: recvmsg()\n"); ! 863: return 0; ! 864: } ! 865: ! 866: static uae_u32 bsdsocklib_gethostname (void) ! 867: { ! 868: return host_gethostname (m68k_areg (regs, 0), m68k_dreg (regs, 0)); ! 869: } ! 870: ! 871: static uae_u32 bsdsocklib_gethostid (void) ! 872: { ! 873: write_log ("bsdsocket: WARNING: Process '%s' calls deprecated function gethostid() - returning 127.0.0.1\n", get_real_address (get_long (gettask () + 10))); ! 874: return 0x7f000001; ! 875: } ! 876: ! 877: char *errortexts[] = ! 878: {"No error", "Operation not permitted", "No such file or directory", ! 879: "No such process", "Interrupted system call", "Input/output error", "Device not configured", ! 880: "Argument list too long", "Exec format error", "Bad file descriptor", "No child processes", ! 881: "Resource deadlock avoided", "Cannot allocate memory", "Permission denied", "Bad address", ! 882: "Block device required", "Device busy", "Object exists", "Cross-device link", ! 883: "Operation not supported by device", "Not a directory", "Is a directory", "Invalid argument", ! 884: "Too many open files in system", "Too many open files", "Inappropriate ioctl for device", ! 885: "Text file busy", "File too large", "No space left on device", "Illegal seek", ! 886: "Read-only file system", "Too many links", "Broken pipe", "Numerical argument out of domain", ! 887: "Result too large", "Resource temporarily unavailable", "Operation now in progress", ! 888: "Operation already in progress", "Socket operation on non-socket", "Destination address required", ! 889: "Messbge too long", "Protocol wrong type for socket", "Protocol not available", ! 890: "Protocol not supported", "Socket type not supported", "Operation not supported", ! 891: "Protocol family not supported", "Address family not supported by protocol family", ! 892: "Address already in use", "Can't assign requested address", "Network is down", ! 893: "Network is unreachable", "Network dropped connection on reset", "Software caused connection abort", ! 894: "Connection reset by peer", "No buffer space available", "Socket is already connected", ! 895: "Socket is not connected", "Can't send after socket shutdown", "Too many references: can't splice", ! 896: "Connection timed out", "Connection refused", "Too many levels of symbolic links", ! 897: "File name too long", "Host is down", "No route to host", "Directory not empty", ! 898: "Too many processes", "Too many users", "Disc quota exceeded", "Stale NFS file handle", ! 899: "Too many levels of remote in path", "RPC struct is bad", "RPC version wrong", ! 900: "RPC prog. not avail", "Program version wrong", "Bad procedure for program", "No locks available", ! 901: "Function not implemented", "Inappropriate file type or format", "PError 0", ! 902: "No error", "Unknown host", "Host name lookup failure", "Unknown server error", ! 903: "No address associated with name"}; ! 904: ! 905: uae_u32 errnotextptrs[sizeof (errortexts) / sizeof (*errortexts)]; ! 906: ! 907: #define TAG_DONE (0L) /* terminates array of TagItems. ti_Data unused */ ! 908: #define TAG_IGNORE (1L) /* ignore this item, not end of array */ ! 909: #define TAG_MORE (2L) /* ti_Data is pointer to another array of TagItems */ ! 910: #define TAG_SKIP (3L) /* skip this and the next ti_Data items */ ! 911: #define TAG_USER ((uae_u32)(1L<<31)) ! 912: ! 913: #define SBTF_VAL 0x0000 ! 914: #define SBTF_REF 0x8000 ! 915: #define SBTB_CODE 1 ! 916: #define SBTS_CODE 0x3FFF ! 917: #define SBTM_CODE(tag) ((((UWORD)(tag))>>SBTB_CODE) & SBTS_CODE) ! 918: #define SBTF_GET 0x0 ! 919: #define SBTF_SET 0x1 ! 920: #define SBTM_GETREF(code) \ ! 921: (TAG_USER | SBTF_REF | (((code) & SBTS_CODE) << SBTB_CODE)) ! 922: #define SBTM_GETVAL(code) (TAG_USER | (((code) & SBTS_CODE) << SBTB_CODE)) ! 923: #define SBTM_SETREF(code) \ ! 924: (TAG_USER | SBTF_REF | (((code) & SBTS_CODE) << SBTB_CODE) | SBTF_SET) ! 925: #define SBTM_SETVAL(code) \ ! 926: (TAG_USER | (((code) & SBTS_CODE) << SBTB_CODE) | SBTF_SET) ! 927: #define SBTC_BREAKMASK 1 ! 928: #define SBTC_SIGIOMASK 2 ! 929: #define SBTC_SIGURGMASK 3 ! 930: #define SBTC_SIGEVENTMASK 4 ! 931: #define SBTC_ERRNO 6 ! 932: #define SBTC_HERRNO 7 ! 933: #define SBTC_DTABLESIZE 8 ! 934: #define SBTC_FDCALLBACK 9 ! 935: #define SBTC_LOGSTAT 10 ! 936: #define SBTC_LOGTAGPTR 11 ! 937: #define SBTC_LOGFACILITY 12 ! 938: #define SBTC_LOGMASK 13 ! 939: #define SBTC_ERRNOSTRPTR 14 /* <sys/errno.h> */ ! 940: #define SBTC_HERRNOSTRPTR 15 /* <netdb.h> */ ! 941: #define SBTC_IOERRNOSTRPTR 16 /* <exec/errors.h> */ ! 942: #define SBTC_S2ERRNOSTRPTR 17 /* <devices/sbna2.h> */ ! 943: #define SBTC_S2WERRNOSTRPTR 18 /* <devices/sbna2.h> */ ! 944: #define SBTC_ERRNOBYTEPTR 21 ! 945: #define SBTC_ERRNOWORDPTR 22 ! 946: #define SBTC_ERRNOLONGPTR 24 ! 947: #define SBTC_HERRNOLONGPTR 25 ! 948: #define SBTC_RELEASESTRPTR 29 ! 949: ! 950: static void tagcopy (uae_u32 currtag, uae_u32 currval, uae_u32 tagptr, uae_u32 * ptr) ! 951: { ! 952: switch (currtag & 0x8001) { ! 953: case 0x0000: /* SBTM_GETVAL */ ! 954: ! 955: put_long (tagptr + 4, *ptr); ! 956: break; ! 957: case 0x8000: /* SBTM_GETREF */ ! 958: ! 959: put_long (currval, *ptr); ! 960: break; ! 961: case 0x0001: /* SBTM_SETVAL */ ! 962: ! 963: *ptr = currval; ! 964: break; ! 965: default: /* SBTM_SETREF */ ! 966: ! 967: *ptr = get_long (currval); ! 968: } ! 969: } ! 970: ! 971: static uae_u32 bsdsocklib_SocketBaseTagList (void) ! 972: { ! 973: SB = SOCKETBASE; ! 974: uae_u32 tagptr = m68k_areg (regs, 0); ! 975: uae_u32 tagsprocessed = 1; ! 976: uae_u32 currtag; ! 977: uae_u32 currval; ! 978: ! 979: TRACE (("SocketBaseTagList(")); ! 980: ! 981: for (;;) { ! 982: currtag = get_long (tagptr); ! 983: currval = get_long (tagptr + 4); ! 984: tagsprocessed++; ! 985: ! 986: switch (currtag) { ! 987: case TAG_DONE: ! 988: TRACE (("TAG_DONE")); ! 989: tagsprocessed = 0; ! 990: goto done; ! 991: case TAG_IGNORE: ! 992: TRACE (("TAG_IGNORE")); ! 993: break; ! 994: case TAG_MORE: ! 995: TRACE (("TAG_MORE(0x%lx)", currval)); ! 996: tagptr = currval; ! 997: break; ! 998: case TAG_SKIP: ! 999: TRACE (("TAG_SKIP(%d)", currval)); ! 1000: tagptr += currval * 8; ! 1001: break; ! 1002: ! 1003: default: ! 1004: if (currtag & TAG_USER) { ! 1005: TRACE (("SBTM_")); ! 1006: TRACE ((currtag & 0x0001 ? "SET" : "GET")); ! 1007: TRACE ((currtag & 0x8000 ? "REF(" : "VAL(")); ! 1008: ! 1009: switch ((currtag >> 1) & SBTS_CODE) { ! 1010: case SBTC_BREAKMASK: ! 1011: TRACE (("SBTC_BREAKMASK),0x%lx", currval)); ! 1012: tagcopy (currtag, currval, tagptr, &sb->eintrsigs); ! 1013: break; ! 1014: case SBTC_SIGEVENTMASK: ! 1015: TRACE (("SBTC_SIGEVENTMASK),0x%lx", currval)); ! 1016: tagcopy (currtag, currval, tagptr, &sb->eventsigs); ! 1017: break; ! 1018: case SBTC_ERRNO: ! 1019: TRACE (("SBTC_ERRNO),%d", currval)); ! 1020: tagcopy (currtag, currval, tagptr, &sb->sb_errno); ! 1021: break; ! 1022: case SBTC_HERRNO: ! 1023: TRACE (("SBTC_HERRNO),%d", currval)); ! 1024: tagcopy (currtag, currval, tagptr, &sb->sb_herrno); ! 1025: break; ! 1026: case SBTC_ERRNOSTRPTR: ! 1027: if (currtag & 1) { ! 1028: TRACE (("ERRNOSTRPTR),invalid")); ! 1029: } else { ! 1030: TRACE (("ERRNOSTRPTR),%d", currval)); ! 1031: put_long (tagptr + 4, errnotextptrs[currval]); ! 1032: } ! 1033: break; ! 1034: case SBTC_HERRNOSTRPTR: ! 1035: if (currtag & 1) { ! 1036: TRACE (("HERRNOSTRPTR),invalid")); ! 1037: } else { ! 1038: TRACE (("HERRNOSTRPTR),%d", currval)); ! 1039: put_long (tagptr + 4, errnotextptrs[currval + sizeof (errortexts) / sizeof (*errortexts) - 6]); ! 1040: } ! 1041: break; ! 1042: case SBTC_ERRNOBYTEPTR: ! 1043: TRACE (("SBTC_ERRNOBYTEPTR),0x%lx", currval)); ! 1044: tagcopy (currtag, currval, tagptr, &sb->errnoptr); ! 1045: sb->errnosize = 1; ! 1046: break; ! 1047: case SBTC_ERRNOWORDPTR: ! 1048: TRACE (("SBTC_ERRNOWORDPTR),0x%lx", currval)); ! 1049: tagcopy (currtag, currval, tagptr, &sb->errnoptr); ! 1050: sb->errnosize = 2; ! 1051: break; ! 1052: case SBTC_ERRNOLONGPTR: ! 1053: TRACE (("SBTC_ERRNOLONGPTR),0x%lx", currval)); ! 1054: tagcopy (currtag, currval, tagptr, &sb->errnoptr); ! 1055: sb->errnosize = 4; ! 1056: break; ! 1057: case SBTC_HERRNOLONGPTR: ! 1058: TRACE (("SBTC_HERRNOLONGPTR),0x%lx", currval)); ! 1059: tagcopy (currtag, currval, tagptr, &sb->herrnoptr); ! 1060: sb->herrnosize = 4; ! 1061: break; ! 1062: default: ! 1063: write_log ("bsdsocket: WARNING: Unsupported tag type (%x) in SocketBaseTagList()\n", currtag); ! 1064: } ! 1065: } else { ! 1066: TRACE (("TAG_UNKNOWN(0x%x)", currtag)); ! 1067: } ! 1068: } ! 1069: ! 1070: TRACE ((",")); ! 1071: tagptr += 8; ! 1072: } ! 1073: ! 1074: done: ! 1075: TRACE ((") -> %d\n", tagsprocessed)); ! 1076: ! 1077: return tagsprocessed; ! 1078: } ! 1079: ! 1080: static uae_u32 bsdsocklib_GetSocketEvents (void) ! 1081: { ! 1082: SB = SOCKETBASE; ! 1083: int i; ! 1084: int flags; ! 1085: uae_u32 ptr = m68k_areg (regs, 0); ! 1086: ! 1087: TRACE (("GetSocketEvents(0x%x) -> ", ptr)); ! 1088: ! 1089: for (i = sb->dtablesize; i--; sb->eventindex++) { ! 1090: if (sb->eventindex >= sb->dtablesize) ! 1091: sb->eventindex = 0; ! 1092: ! 1093: if (sb->mtable[sb->eventindex]) { ! 1094: flags = sb->ftable[sb->eventindex] & SET_ALL; ! 1095: ! 1096: if (flags) { ! 1097: sb->ftable[sb->eventindex] &= ~SET_ALL; ! 1098: put_long (m68k_areg (regs, 0), flags >> 8); ! 1099: TRACE (("%d (0x%x)\n", sb->eventindex + 1, flags >> 8)); ! 1100: return sb->eventindex + 1; ! 1101: } ! 1102: } ! 1103: } ! 1104: ! 1105: TRACE (("-1\n")); ! 1106: return -1; ! 1107: } ! 1108: ! 1109: static uae_u32 bsdsocklib_getdtablesize (void) ! 1110: { ! 1111: return get_socketbase ()->dtablesize; ! 1112: } ! 1113: ! 1114: static uae_u32 bsdsocklib_null (void) ! 1115: { ! 1116: return 0; ! 1117: } ! 1118: ! 1119: extern uae_u32 sockfuncvecs[]; ! 1120: ! 1121: static uae_u32 bsdsocklib_init (void) ! 1122: { ! 1123: uae_u32 tmp1; ! 1124: int i; ! 1125: write_log ("Creating UAE bsdsocket.library 4.1\n"); ! 1126: if (SockLibBase) ! 1127: bsdlib_reset (); ! 1128: ! 1129: m68k_areg (regs, 0) = functable; ! 1130: m68k_areg (regs, 1) = datatable; ! 1131: m68k_areg (regs, 2) = 0; ! 1132: m68k_dreg (regs, 0) = LIBRARY_SIZEOF; ! 1133: m68k_dreg (regs, 1) = 0; ! 1134: tmp1 = CallLib (m68k_areg (regs, 6), -0x54); ! 1135: ! 1136: if (!tmp1) { ! 1137: write_log ("bsdoscket: FATAL: Cannot create bsdsocket.library!\n"); ! 1138: return 0; ! 1139: } ! 1140: m68k_areg (regs, 1) = tmp1; ! 1141: CallLib (m68k_areg (regs, 6), -0x18c); ! 1142: SockLibBase = tmp1; ! 1143: #if 0 ! 1144: m68k_areg (regs, 1) = ds ("dos.library"); ! 1145: m68k_dreg (regs, 0) = 0; ! 1146: dosbase = CallLib (m68k_areg (regs, 6), -552); ! 1147: printf ("%08lx\n", dosbase); ! 1148: #endif ! 1149: ! 1150: /* Install error strings in Amiga memory */ ! 1151: for (tmp1 = i = sizeof (errortexts) / sizeof (*errortexts); i--;) ! 1152: tmp1 += strlen (errortexts[i]); ! 1153: ! 1154: m68k_dreg (regs, 0) = tmp1; ! 1155: m68k_dreg (regs, 1) = 0; ! 1156: tmp1 = CallLib (get_long (4), -0xC6); ! 1157: ! 1158: if (!tmp1) { ! 1159: write_log ("bsdsocket: FATAL: Ran out of memory while creating bsdsocket.library!\n"); ! 1160: return 0; ! 1161: } ! 1162: for (i = 0; i < (int) (sizeof (errortexts) / sizeof (*errortexts)); i++) ! 1163: errnotextptrs[i] = addstr (&tmp1, errortexts[i]); ! 1164: ! 1165: /* @@@ someone please implement a proper interrupt handler setup here :) */ ! 1166: tmp1 = here (); ! 1167: calltrap (deftrap2 (bsdsock_int_handler, TRAPFLAG_EXTRA_STACK | TRAPFLAG_NO_RETVAL, "")); ! 1168: dw (0x4ef9); ! 1169: dl (get_long (regs.vbr + 0x78)); ! 1170: put_long (regs.vbr + 0x78, tmp1); ! 1171: ! 1172: m68k_dreg (regs, 0) = 1; ! 1173: return 0; ! 1174: } ! 1175: ! 1176: void bsdlib_reset (void) ! 1177: { ! 1178: SB, *nsb; ! 1179: int i; ! 1180: ! 1181: SockLibBase = 0; ! 1182: ! 1183: for (sb = socketbases; sb; sb = nsb) { ! 1184: nsb = sb->next; ! 1185: ! 1186: host_sbcleanup (sb); ! 1187: ! 1188: free (sb->dtable); ! 1189: free (sb->ftable); ! 1190: ! 1191: free (sb); ! 1192: } ! 1193: ! 1194: socketbases = NULL; ! 1195: sbsigqueue = NULL; ! 1196: ! 1197: for (i = 0; i < SOCKPOOLSIZE; i++) { ! 1198: if (sockpoolids[i] != UNIQUE_ID) { ! 1199: sockpoolids[i] = UNIQUE_ID; ! 1200: host_closesocketquick (sockpoolsocks[i]); ! 1201: } ! 1202: } ! 1203: ! 1204: host_sbreset (); ! 1205: } ! 1206: ! 1207: uae_u32 (*sockfuncs[])(void) = { ! 1208: bsdsocklib_init, bsdsocklib_Open, bsdsocklib_Close, bsdsocklib_Expunge, ! 1209: bsdsocklib_socket, bsdsocklib_bind, bsdsocklib_listen, bsdsocklib_accept, ! 1210: bsdsocklib_connect, bsdsocklib_sendto, bsdsocklib_send, bsdsocklib_recvfrom, bsdsocklib_recv, ! 1211: bsdsocklib_shutdown, bsdsocklib_setsockopt, bsdsocklib_getsockopt, bsdsocklib_getsockname, ! 1212: bsdsocklib_getpeername, bsdsocklib_IoctlSocket, bsdsocklib_CloseSocket, bsdsocklib_WaitSelect, ! 1213: bsdsocklib_SetSocketSignals, bsdsocklib_SetDTableSize, bsdsocklib_ObtainSocket, bsdsocklib_ReleaseSocket, ! 1214: bsdsocklib_ReleaseCopyOfSocket, bsdsocklib_Errno, bsdsocklib_SetErrnoPtr, bsdsocklib_Inet_NtoA, ! 1215: bsdsocklib_inet_addr, bsdsocklib_Inet_LnaOf, bsdsocklib_Inet_NetOf, bsdsocklib_Inet_MakeAddr, ! 1216: bsdsocklib_inet_network, bsdsocklib_gethostbyname, bsdsocklib_gethostbyaddr, bsdsocklib_getnetbyname, ! 1217: bsdsocklib_getnetbyaddr, bsdsocklib_getservbyname, bsdsocklib_getservbyport, bsdsocklib_getprotobyname, ! 1218: bsdsocklib_getprotobynumber, bsdsocklib_vsyslog, bsdsocklib_Dup2Socket, bsdsocklib_sendmsg, ! 1219: bsdsocklib_recvmsg, bsdsocklib_gethostname, bsdsocklib_gethostid, bsdsocklib_SocketBaseTagList, ! 1220: bsdsocklib_GetSocketEvents ! 1221: }; ! 1222: ! 1223: uae_u32 sockfuncvecs[sizeof (sockfuncs) / sizeof (*sockfuncs)]; ! 1224: ! 1225: void bsdlib_install (void) ! 1226: { ! 1227: uae_u32 resname, resid; ! 1228: uae_u32 begin, end, inittable; ! 1229: uae_u32 func_place, data_place, init_place; ! 1230: int i; ! 1231: ! 1232: if (!init_socket_layer ()) ! 1233: return; ! 1234: ! 1235: memset (sockpoolids, UNIQUE_ID, sizeof (sockpoolids)); ! 1236: ! 1237: resname = ds ("bsdsocket.library"); ! 1238: resid = ds ("UAE bsdsocket.library 4.1"); ! 1239: ! 1240: begin = here (); ! 1241: dw (0x4AFC); /* RT_MATCHWORD */ ! 1242: dl (begin); /* RT_MATCHTAG */ ! 1243: dl (0); /* RT_ENDSKIP */ ! 1244: dw (0x8004); /* RTF_AUTOINIT, RT_VERSION */ ! 1245: dw (0x0970); /* NT_LIBRARY, RT_PRI */ ! 1246: dl (resname); /* RT_NAME */ ! 1247: dl (resid); /* RT_IDSTRING */ ! 1248: dl (here () + 4); /* RT_INIT */ ! 1249: dl (512); ! 1250: func_place = here (); ! 1251: dl (0); ! 1252: data_place = here (); ! 1253: dl (0); ! 1254: init_place = here (); ! 1255: dl (0); ! 1256: ! 1257: for (i = 0; i < (int) (sizeof (sockfuncs) / sizeof (sockfuncs[0])); i++) { ! 1258: sockfuncvecs[i] = here (); ! 1259: calltrap (deftrap2 (sockfuncs[i], TRAPFLAG_EXTRA_STACK, "")); ! 1260: dw (RTS); ! 1261: } ! 1262: ! 1263: /* FuncTable */ ! 1264: functable = here (); ! 1265: for (i = 1; i < 4; i++) ! 1266: dl (sockfuncvecs[i]); /* Open / Close / Expunge */ ! 1267: dl (EXPANSION_nullfunc); /* Null */ ! 1268: for (i = 4; i < (int) (sizeof (sockfuncs) / sizeof (sockfuncs[0])); i++) ! 1269: dl (sockfuncvecs[i]); ! 1270: dl (0xFFFFFFFF); /* end of table */ ! 1271: ! 1272: /* DataTable */ ! 1273: datatable = here (); ! 1274: dw (0xE000); /* INITBYTE */ ! 1275: dw (0x0008); /* LN_TYPE */ ! 1276: dw (0x0900); /* NT_LIBRARY */ ! 1277: dw (0xC000); /* INITLONG */ ! 1278: dw (0x000A); /* LN_NAME */ ! 1279: dl (resname); ! 1280: dw (0xE000); /* INITBYTE */ ! 1281: dw (0x000E); /* LIB_FLAGS */ ! 1282: dw (0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */ ! 1283: dw (0xD000); /* INITWORD */ ! 1284: dw (0x0014); /* LIB_VERSION */ ! 1285: dw (0x0004); ! 1286: dw (0xD000); ! 1287: dw (0x0016); /* LIB_REVISION */ ! 1288: dw (0x0001); ! 1289: dw (0xC000); ! 1290: dw (0x0018); /* LIB_IDSTRING */ ! 1291: dl (resid); ! 1292: dl (0x00000000); /* end of table */ ! 1293: ! 1294: end = here (); ! 1295: ! 1296: org (begin + 6); /* Load END value */ ! 1297: dl (end); ! 1298: ! 1299: org (data_place); ! 1300: dl (datatable); ! 1301: ! 1302: org (func_place); ! 1303: dl (functable); ! 1304: ! 1305: org (init_place); ! 1306: dl (*sockfuncvecs); ! 1307: ! 1308: org (end); ! 1309: } ! 1310: ! 1311: #else /* ! BSDSOCKET_SUPPORTED */ ! 1312: ! 1313: void bsdlib_reset (void) ! 1314: { ! 1315: } ! 1316: ! 1317: #endif /* ! BSDSOCKET_SUPPORTED */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.