tools/adflib: build only host variant which is used by Sam440 target
[AROS.git] / workbench / network / stacks / AROSTCP / bsdsocket / api / amiga_api.c
blobf3c80a8549e43ae131aa37967270ffa13d68e570
1 /*
2 * Copyright (C) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
3 * Helsinki University of Technology, Finland.
4 * All rights reserved.
5 * Copyright (C) 2005 - 2010 The AROS Dev Team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 * MA 02111-1307, USA.
24 * NOTE: Exec has turned off task switching while in Open, Close, Expunge and
25 * Reserved functions (via Forbid()/Permit()) so we should not take
26 * too long in them.
29 #include <conf.h>
30 #include <version.h>
32 #include <aros/libcall.h>
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/syslog.h>
38 #include <kern/amiga_includes.h>
40 #include <api/amiga_api.h>
41 #include <api/allocdatabuffer.h>
42 #include <api/amiga_libcallentry.h>
43 #include <api/apicalls.h>
45 #include <kern/amiga_subr.h>
46 #include <kern/amiga_log.h>
48 #if 0
49 /*#if sizeof (fd_mask) != 4 || sizeof (long) != 4*/
50 #error AmiTCP/IP currently depends on fd_mask and longword size of 32 bits.
51 #endif
54 * Semaphore to prevent simultaneous access to library functions.
56 struct SignalSemaphore syscall_semaphore = { {0} };
59 * some globals.
61 struct Library *MasterSocketBase = NULL;
62 struct Library *MasterMiamiBase = NULL;
63 struct List socketBaseList; /* list of opened socket library bases */
64 struct List garbageSocketBaseList; /* list of libray bases not active
65 anymore (NOT YET IMPLEMENTED) */
66 struct List releasedSocketList; /* List for sockets that are in no-one's
67 context, waiting for Obtain */
69 extern struct Task * AROSTCP_Task; /* reference to AmiTCP/IP task information */
70 extern f_void UserLibrary_funcTable[];
73 * Declaration of variable to hold message format string when one
74 * task tries to use other tasks' library base pointer. moved here
75 * from amiga_libcallentry.h so it doens't generate code.
77 const char wrongTaskErrorFmt[] =
78 "Task %ld (%s) attempted to use library base of Task %ld (%s).";
80 #if !defined(__AROS__)
82 * Instead of using exec/initializers.h we looked it as a reference
83 * and wrote InitTable by hand
87 * OFFSET needed to be casted LONG so compiler doesn't give warning
88 * about casting pointer to UWORD
90 #undef OFFSET
91 #define OFFSET(structName, structEntry) \
92 ((LONG)(&(((struct structName *) 0)->structEntry)))
95 * original initTable of only UWORD items doesn't work, since compiler
96 * doesn't know address of SOCNAME and VSTRING at compile time, and
97 * those are broken to 2 WORDS. therefore initTable is a structure
98 * constructed by hand, and those (LONG) values are set longword aligned.
100 #define id_byte 0xa0
101 #define id_word 0x90
102 #define id_long 0x80
104 struct LibInitTable Library_initTable = {
105 id_byte, OFFSET(Node, ln_Type), NT_LIBRARY, 0,
106 id_byte, OFFSET(Library, lib_Flags), (LIBF_SUMUSED|LIBF_CHANGED), 0,
107 id_long, OFFSET(Node, ln_Name), (ULONG)SOCLIBNAME,
108 id_word, OFFSET(Library, lib_Version), VERSION,
109 id_word, OFFSET(Library, lib_Revision), REVISION,
110 id_long, OFFSET(Library, lib_IdString), (ULONG)RELEASESTRING VSTRING,
111 0x00
114 struct LibInitTable Miami_initTable = {
115 id_byte, OFFSET(Node, ln_Type), NT_LIBRARY, 0,
116 id_byte, OFFSET(Library, lib_Flags), (LIBF_SUMUSED|LIBF_CHANGED), 0,
117 id_long, OFFSET(Node, ln_Name), (ULONG)MIAMILIBNAME,
118 id_word, OFFSET(Library, lib_Version), MIAMI_VERSION,
119 id_word, OFFSET(Library, lib_Revision), MIAMI_REVISION,
120 id_long, OFFSET(Library, lib_IdString), (ULONG)RELEASESTRING MIAMI_VSTRING,
121 0x00
123 #undef id_byte
124 #undef id_word
125 #undef id_long
126 #endif
129 * API Show and Hide functions.. during these calls system is not
130 * inside Forbid()/Permit() pair
133 enum apistate api_state = API_SCRATCH;
136 * Setting the following variable to FALSE just before making
137 * new socket Library base prevents ELL_Expunge, the final
138 * expunging function to remove library base from memory
140 BOOL AROSTCP_FLAG_CANEXPUNGE = FALSE;
142 BOOL SB_Expunged = FALSE; /* boolean value set by ELL_Expunge */
145 AROS_LH1 (struct Library *, Open,
146 AROS_LHA(ULONG, version, D0),
147 struct Library *, libPtr, 1, ELL)
149 AROS_LIBFUNC_INIT
150 struct SocketBase * newBase;
151 LONG error;
152 WORD * i;
154 #if defined(__AROS__)
155 D(bug("[AROSTCP](amiga_api.c) ELL_Open()\n[AROSTCP](amiga_api.c) ELL_Open: version=%lu, libPtr=0x%p\n", version, libPtr));
156 #else
157 D(KPrintF("ELL_Open: version=%lu, libPtr=0x%p\n", version, libPtr);)
158 #endif
160 * One task may open socket library more than once. In that case caller
161 * receives the base it has opened already.
163 if ((newBase = FindSocketBase(FindTask(NULL))) != NULL) {
164 newBase->libNode.lib_OpenCnt++;
165 return (struct Library *)newBase;
168 * Create new library base.
169 * All fields in the base will first be initialized to zero and then
170 * modified by initializers in initTable.
172 newBase = (struct SocketBase *)MakeLibrary(UserLibrary_funcTable,
173 #if !defined(__AROS__)
174 (UWORD *)&Library_initTable,
175 #else
176 NULL,
177 #endif
178 NULL,
179 sizeof(struct SocketBase),
180 BNULL);
181 #if defined(__AROS__)
183 ((struct Library *)newBase)->lib_Node.ln_Type = NT_LIBRARY;
184 ((struct Library *)newBase)->lib_Node.ln_Name = (APTR)SOCLIBNAME;
185 ((struct Library *)newBase)->lib_Flags = (LIBF_SUMUSED|LIBF_CHANGED);
186 ((struct Library *)newBase)->lib_Version = VERSION;
187 ((struct Library *)newBase)->lib_Revision = REVISION;
188 ((struct Library *)newBase)->lib_IdString = (APTR)RELEASESTRING VSTRING;
190 D(bug("[AROSTCP](amiga_api.c) ELL_Open: Created user library base @ 0x%p\n", newBase));
191 #endif
192 D(__log(LOG_DEBUG,"Created user library base: 0x%p\n", newBase);)
193 if (newBase == NULL)
194 return NULL;
197 * add this newly allocated library base to our list of opened
198 * socket libraries
200 AddTail(&socketBaseList, (struct Node *)newBase);
203 * Modify some MASTER library base fields
205 libPtr->lib_OpenCnt++; /* mark us as having another opener */
206 libPtr->lib_Flags&= ~LIBF_DELEXP; /* prevent delayed expunges */
209 * Initialize new library base
211 for (i = (WORD *)((struct Library *)newBase + 1);
212 i < (WORD *)(newBase + 1);
213 i++)
214 *i = 0L;
215 newBase->libNode.lib_OpenCnt = 1;
216 newBase->errnoPtr = (VOID *)&newBase->defErrno;
217 newBase->errnoSize = sizeof newBase->defErrno;
218 newBase->thisTask = FindTask(NULL);
219 newBase->sigIntrMask = SIGBREAKF_CTRL_C;
221 /* initialize syslog variables */
222 #if 0 /* initialization to zero is implicit */
223 newBase->LogTag = NULL; /* no tag by default, old apps print a tag already */
224 #endif
225 newBase->LogFacility = LOG_USER;
226 newBase->LogMask = 0xff;
228 /* initialize resolver variables */
229 newBase->hErrnoPtr = &newBase->defHErrno;
230 newBase->res_socket = -1;
231 //res_init(&newBase->res_state);
233 /* Initialize events list */
234 InitSemaphore(&newBase->EventLock);
235 NewList((struct List *)&newBase->EventList);
237 /* initialize dtable variables */
238 #if 0 /* initialization to zero is implicit */
239 newBase->fdCallback = NULL;
240 #endif
241 newBase->dTableSize = FD_SETSIZE;
242 if ((newBase->dTable =
243 AllocMem(newBase->dTableSize * sizeof (struct socket *) +
244 ((newBase->dTableSize - 1) / NFDBITS + 1) * sizeof (fd_mask),
245 MEMF_CLEAR|MEMF_PUBLIC)) != NULL) {
247 * allocate and initialize the timer message reply port
249 newBase->timerPort = CreateMsgPort();
250 if (newBase->timerPort != NULL) {
252 * Disable signalling for now
254 newBase->timerPort->mp_Flags = PA_IGNORE;
256 * allocate and initialize the timerequest
258 newBase->tsleep_timer = (struct timerequest *)
259 CreateIORequest(newBase->timerPort, sizeof(struct timerequest));
260 if (newBase->tsleep_timer != NULL) {
261 error = OpenDevice(TIMERNAME, UNIT_VBLANK,
262 (struct IORequest *)newBase->tsleep_timer, 0);
263 if (error == 0) {
265 * Initialize some fields of the IO request to common values
267 newBase->tsleep_timer->tr_node.io_Command = TR_ADDREQUEST;
268 newBase->tsleep_timer->tr_node.io_Message.mn_Node.ln_Type = NT_UNKNOWN;
269 return (struct Library *)newBase;
275 * There was some error if we reached here. Call Close to clean up.
278 extern ULONG* __UL_Close(struct SocketBase *);
279 __UL_Close(newBase);
281 return NULL;
282 AROS_LIBFUNC_EXIT
285 ULONG *__ELL_Expunge(struct Library *libPtr)
287 #if defined(__AROS__)
288 D(bug("[AROSTCP](amiga_api.c) __ELL_Expunge()\n"));
289 #endif
291 * Since every user gets her own library base, Major library base
292 * can be removed immediately after
294 if (libPtr->lib_OpenCnt == 0 && AROSTCP_FLAG_CANEXPUNGE) {
295 VOID * freestart;
296 ULONG size;
298 #if 0 /* Currently done already */
300 * unlink SocketBase from System Library list
302 Remove((struct Node *)libPtr);
303 #endif
305 freestart = (void *)((IPTR)libPtr - (IPTR)libPtr->lib_NegSize);
306 size = libPtr->lib_NegSize + libPtr->lib_PosSize;
307 FreeMem(freestart, size);
309 return NULL; /* no AmigaDos seglist there (for system use) */
312 * here if someone still has us open, or AmiTCP won't let us expunge yet
314 libPtr->lib_Flags |= LIBF_DELEXP; /* set delayed expunge flag */
315 SB_Expunged = FALSE;
316 return NULL;
319 AROS_LH0(ULONG *, Expunge, struct Library *, libPtr, 3, ELL)
321 AROS_LIBFUNC_INIT
322 #if defined(__AROS__)
323 D(bug("[AROSTCP](amiga_api.c) ELL_Expunge()\n"));
324 #endif
325 return __ELL_Expunge(libPtr);
326 AROS_LIBFUNC_EXIT
329 AROS_LH0I(LONG, Null, struct Library *, libPtr, 0, LIB)
331 AROS_LIBFUNC_INIT
332 #if defined(__AROS__)
333 D(bug("[AROSTCP](amiga_api.c) ELL_Null: WARNING!!! Null() called\n"));
334 #else
335 D(KPrintF("WARNING!!! Null() called\n");)
336 #endif
338 return 0L;
339 AROS_LIBFUNC_EXIT
342 ULONG *__UL_Close(struct SocketBase *libPtr)
344 VOID * freestart;
345 ULONG size;
346 int i;
349 * one task may have SocketLibrary opened more than once.
351 if (--libPtr->libNode.lib_OpenCnt > 0)
352 return NULL;
353 #ifdef DEBUG
354 #if defined(__AROS__)
355 D(bug("[AROSTCP](amiga_api.c) __UL_Close: Closing proc 0x%lx base 0x%lx\n", libPtr->thisTask, libPtr));
356 #endif
357 /* Do not call __log here. If NETTRACE is calling CloseLibrary
358 __log will call back on NETTRACE which will cause hang in close
359 procedure. This was affecting normal and debug build because
360 DEBUG is always defined in conf.h */
361 /*__log(LOG_DEBUG, "Closing proc 0x%lx base 0x%lx\n",
362 libPtr->thisTask, libPtr);*/
363 #endif
366 * Since library base is to be closed, all sockets referenced by this
367 * library base must be closed too. Next piece of code searches for open
368 * sockets and calls CloseSocket() on our own library base. It is safe
369 * to call since Forbid() state is broken if semaphore needs to be waited.
371 * Note that the close may linger. In such case the linger time will be
372 * waited. The linger may be interrupted by any signal in sigIntrMask.
374 libPtr->fdCallback = NULL; /* don't call the callback any more */
375 for (i = 0; i < libPtr->dTableSize; i++)
376 if (libPtr->dTable[i] != NULL)
377 __CloseSocket(i, libPtr);
379 Remove((struct Node *)libPtr); /* remove this librarybase from our list
380 of opened library bases */
382 if (libPtr->tsleep_timer) {
383 if (libPtr->tsleep_timer->tr_node.io_Device != NULL) {
384 if (libPtr->tsleep_timer->tr_node.io_Message.mn_Node.ln_Type != NT_UNKNOWN) {
385 /* NC: must check if request has been used */
386 AbortIO((struct IORequest *)(libPtr->tsleep_timer));
387 WaitIO((struct IORequest *)(libPtr->tsleep_timer));
389 CloseDevice((struct IORequest *)libPtr->tsleep_timer);
391 DeleteIORequest((struct IORequest *)libPtr->tsleep_timer);
393 if (libPtr->timerPort)
394 DeleteMsgPort(libPtr->timerPort);
396 freeDataBuffer(&libPtr->selitems);
397 freeDataBuffer(&libPtr->hostents);
398 freeDataBuffer(&libPtr->netents);
399 freeDataBuffer(&libPtr->protoents);
400 freeDataBuffer(&libPtr->servents);
402 if (libPtr->dTable)
403 FreeMem(libPtr->dTable, libPtr->dTableSize * sizeof (struct socket *) +
404 ((libPtr->dTableSize - 1) / NFDBITS + 1) * sizeof (fd_mask));
406 res_cleanup_db(&libPtr->res_state);
408 freestart = (void *)((IPTR)libPtr - (IPTR)libPtr->libNode.lib_NegSize);
409 size = libPtr->libNode.lib_NegSize + libPtr->libNode.lib_PosSize;
410 bzero(freestart, size);
411 FreeMem(freestart, size);
413 MasterSocketBase->lib_OpenCnt--;
415 * If no more libraries are open and delayed expunge is asked,
416 * ELL_expunge() is called.
418 if (MasterSocketBase->lib_OpenCnt == 0 &&
419 (MasterSocketBase->lib_Flags & LIBF_DELEXP)) {
420 return __ELL_Expunge(MasterSocketBase);
423 return NULL; /* always return null */
426 AROS_LH0(ULONG *, Close, struct SocketBase *, libPtr, 2, UL)
428 AROS_LIBFUNC_INIT
429 #if defined(__AROS__)
430 D(bug("[AROSTCP](amiga_api.c) ELL_Close()\n"));
431 #endif
432 return __UL_Close(libPtr);
433 AROS_LIBFUNC_EXIT
437 BOOL api_init()
439 extern void select_init(void);
440 extern f_void ExecLibraryList_funcTable[];
441 extern ULONG Miami_InitFuncTable[];
443 #if defined(__AROS__)
444 D(bug("[AROSTCP](amiga_api.c) api_init()\n"));
445 #endif
447 if (api_state != API_SCRATCH)
448 return TRUE;
450 AROSTCP_FLAG_CANEXPUNGE = FALSE;
452 MasterSocketBase = MakeLibrary(ExecLibraryList_funcTable,
453 #if !defined(__AROS__)
454 (UWORD *)&Library_initTable,
455 #else
456 NULL,
457 #endif
458 NULL,
459 sizeof(struct Library),
460 BNULL);
461 #if defined(__AROS__)
462 ((struct Library *)MasterSocketBase)->lib_Node.ln_Type = NT_LIBRARY;
463 ((struct Library *)MasterSocketBase)->lib_Node.ln_Name = (APTR)SOCLIBNAME;
464 ((struct Library *)MasterSocketBase)->lib_Flags = (LIBF_SUMUSED|LIBF_CHANGED);
465 ((struct Library *)MasterSocketBase)->lib_Version = VERSION;
466 ((struct Library *)MasterSocketBase)->lib_Revision = REVISION;
467 ((struct Library *)MasterSocketBase)->lib_IdString = (APTR)RELEASESTRING VSTRING;
469 D(bug("[AROSTCP](amiga_api.c) api_init: Created master library base: 0x%p\n", MasterSocketBase));
470 #endif
471 D(Printf("Created master library base: 0x%p\n", MasterSocketBase);)
472 if (MasterSocketBase == NULL)
473 return FALSE;
475 MasterMiamiBase = MakeLibrary(Miami_InitFuncTable,
476 #if !defined(__AROS__)
477 (UWORD *)&Miami_initTable,
478 #else
479 NULL,
480 #endif
481 NULL,
482 sizeof(struct Library),
483 BNULL);
484 #if defined(__AROS__)
485 ((struct Library *)MasterMiamiBase)->lib_Node.ln_Type = NT_LIBRARY;
486 ((struct Library *)MasterMiamiBase)->lib_Node.ln_Name = (APTR)MIAMILIBNAME;
487 ((struct Library *)MasterMiamiBase)->lib_Flags = (LIBF_SUMUSED|LIBF_CHANGED);
488 ((struct Library *)MasterMiamiBase)->lib_Version = MIAMI_VERSION;
489 ((struct Library *)MasterMiamiBase)->lib_Revision = MIAMI_REVISION;
490 ((struct Library *)MasterMiamiBase)->lib_IdString = (APTR)RELEASESTRING MIAMI_VSTRING;
492 D(bug("[AROSTCP](amiga_api.c) api_init: Created MIAMI library base: 0x%p\n", MasterMiamiBase));
493 #endif
494 D(Printf("Created master miami.library base: 0x%p\n", MasterMiamiBase);)
495 if (MasterMiamiBase == NULL)
496 return FALSE;
498 InitSemaphore(&syscall_semaphore);
499 select_init(); /* initializes data Select() needs */
500 NewList(&socketBaseList);
501 NewList(&garbageSocketBaseList);
502 NewList(&releasedSocketList);
504 api_state = API_INITIALIZED;
505 return TRUE;
508 LONG nthLibrary = 0;
510 BOOL api_show()
512 struct Node * libNode;
513 STRPTR libName = SOCLIBNAME;
515 #if defined(__AROS__)
516 D(bug("[AROSTCP](amiga_api.c) api_show()\n"));
517 #endif
519 if (api_state == API_SHOWN)
520 return TRUE;
521 if (api_state == API_SCRATCH)
522 return FALSE;
524 Forbid();
525 for (libNode = SysBase->LibList.lh_Head; libNode->ln_Succ;
526 libNode = libNode->ln_Succ) {
527 if (!strncmp(libNode->ln_Name, libName, sizeof (SOCLIBNAME) - 3)) {
528 #ifdef DEBUG
529 int i;
530 if (libNode->ln_Name[sizeof (SOCLIBNAME) - 3] == '\0')
531 i = 1;
532 else
533 i = (BYTE)(libNode->ln_Name[sizeof (SOCLIBNAME) - 2] - '0' + 1);
534 if (nthLibrary < i)
535 nthLibrary = i;
536 #else
537 Permit();
538 return FALSE;
539 #endif
542 Permit();
543 #ifdef DEBUG
544 if (nthLibrary > 8)
545 return FALSE;
546 if (nthLibrary) {
547 libName[sizeof (SOCLIBNAME) - 3] = '.';
548 libName[sizeof (SOCLIBNAME) - 2] = '0' + nthLibrary;
549 libName[sizeof (SOCLIBNAME) - 1] = '\0';
550 MasterSocketBase->lib_Node.ln_Name = libName;
552 #endif
553 AddLibrary(MasterSocketBase);
554 AddLibrary(MasterMiamiBase);
555 api_state = API_SHOWN;
557 return TRUE;
560 VOID api_hide()
562 #if defined(__AROS__)
563 D(bug("[AROSTCP](amiga_api.c) api_hide()\n"));
564 #endif
566 if (api_state != API_SHOWN)
567 return;
568 Forbid();
569 /* unlink Master SocketBase from System Library list */
570 Remove((struct Node*)MasterSocketBase);
571 Remove((struct Node*)MasterMiamiBase);
572 Permit();
573 api_state = API_HIDDEN;
576 VOID api_setfunctions() /* DOES NOTHING NOW */
578 /* struct Node *node2move; */
580 #if defined(__AROS__)
581 D(bug("[AROSTCP](amiga_api.c) api_setfunctions()\n"));
582 #endif
584 if (api_state == API_SCRATCH)
585 return;
586 if (api_state == API_SHOWN) {
587 /* unlink Master SocketBase from System Library list */
588 Forbid();
589 Remove((struct Node*)MasterMiamiBase);
590 Remove((struct Node*)MasterSocketBase);
591 Permit();
594 /* here SetFunction()s to patch libray calls (forbid()/permit()) */
595 /* while(node2move = RemHead(&socketBaseList))
596 AddTail(&garbageSocketBaseList, node2move); */
597 api_state = API_FUNCTIONPATCHED;
601 * Send CTRL_C to all tasks having socketbase open.
603 VOID api_sendbreaktotasks()
605 extern struct List socketBaseList; /* :/ */
606 struct Node * libNode;
608 #if defined(__AROS__)
609 D(bug("[AROSTCP](amiga_api.c) api_sendbreaktotask()\n"));
610 #endif
612 Forbid();
613 for (libNode = socketBaseList.lh_Head; libNode->ln_Succ;
614 libNode = libNode->ln_Succ)
615 if (((struct SocketBase *)libNode)->thisTask != Nettrace_Task)
616 Signal(((struct SocketBase *)libNode)->thisTask, SIGBREAKF_CTRL_C);
618 Permit();
622 VOID api_deinit()
624 #if defined(__AROS__)
625 D(bug("[AROSTCP](amiga_api.c) api_deinit()\n"));
626 #endif
627 #if DIAGNOSTIC
628 if (FindTask(NULL) != AROSTCP_Task)
630 #if defined(__AROS__)
631 D(bug("[AROSTCP](amiga_api.c) api_deinit: The calling task of api_deinit() was not bsdsocket.library's"));
632 #endif
633 __log(LOG_ERR,
634 "The calling task of api_deinit() was not bsdsocket.library's");
636 #endif
637 if (api_state == API_SHOWN || api_state == API_HIDDEN)
638 api_setfunctions();
639 if (api_state == API_SCRATCH)
640 return;
642 Forbid();
643 if (MasterMiamiBase) {
644 __ELL_Expunge(MasterMiamiBase);
645 MasterMiamiBase = NULL;
647 if (MasterSocketBase) {
648 AROSTCP_FLAG_CANEXPUNGE = TRUE;
649 __ELL_Expunge(MasterSocketBase);
650 MasterSocketBase = NULL;
651 SB_Expunged = TRUE;
652 Signal(AROSTCP_Task, SIGBREAKF_CTRL_F);
654 Permit();
657 * if SB_Expunged == FALSE, waiting until last UL_Close() expunges
658 * our library.
660 while(SB_Expunged == FALSE)
661 Wait(SIGBREAKF_CTRL_F);
663 api_state = API_SCRATCH;
666 VOID writeErrnoValue(struct SocketBase * libPtr, int error)
668 #if defined(__AROS__)
669 D(bug("[AROSTCP](amiga_api.c) writeErrnoValue()\n"));
670 #endif
672 * errnoSize is now restricted to 1, 2 or 4
674 BYTE erri = libPtr->errnoSize;
676 if (erri == 4) {
677 *(ULONG *)libPtr->errnoPtr = (ULONG)error;
678 return;
680 if (erri == 2) {
681 *(UWORD *)libPtr->errnoPtr = (UWORD)error;
682 return;
684 /* size must be 1 */
685 *(UBYTE *)libPtr->errnoPtr = (UBYTE)error;
686 return;
689 int readErrnoValue(struct SocketBase * libPtr)
691 #if defined(__AROS__)
692 D(bug("[AROSTCP](amiga_api.c) readErrnoValue()\n"));
693 #endif
695 * errnoSize is now restricted to 1, 2 or 4
697 BYTE erri = libPtr->errnoSize;
699 if (erri == 4) {
700 return *(ULONG *)libPtr->errnoPtr;
702 if (erri == 2) {
703 return *(UWORD *)libPtr->errnoPtr;
705 /* size must be 1 */
706 return *(UBYTE *)libPtr->errnoPtr;