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