Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / network / stacks / AROSTCP / netlib / _chkufb.c
blobe464e0456e01d9ce118e3f394b90559bee8fc416
1 /* $Id$
3 * _chkufb.c - return struct ufb * from a file handle (SAS/C)
5 * Copyright © 1994 AmiTCP/IP Group,
6 * Network Solutions Development Inc.
7 * All rights reserved.
8 */
10 #include <ios1.h>
11 #include <stdlib.h>
12 #include <errno.h>
13 #include <bsdsocket.h>
14 #include <sys/cdefs.h>
15 #include <amitcp/socketbasetags.h>
16 #include <syslog.h>
18 extern unsigned long __fmask;
19 extern int (*__closefunc)(int);
21 long ASM fdCallback(REG(d0) int fd, REG(d1) int action);
24 * The initializator priority is just above the standard I/O, so that this
25 * will be called after the standard I/O is initialized
27 long __stdargs
28 _STI_510_install_AmiTCP_callback(void)
30 if (SocketBaseTags(SBTM_SETVAL(SBTC_FDCALLBACK), &fdCallback, TAG_END)) {
31 syslog(LOG_ERR, "Cannot install fdCallback!");
32 #if __VERSION__ > 6 || __REVISION__ > 3
33 return 1;
34 #else
35 exit(20);
36 #endif
40 * Set up __closefunc (which is used at stdio cleanup)
42 __closefunc = __close;
45 * Set default file mask to UNIX style
47 __fmask = 0644;
49 return 0;
52 long ASM SAVEDS
53 fdCallback(REG(d0) int fd, REG(d1) int action)
55 struct UFB *ufb;
56 int fd2;
58 #ifdef DEBUG
59 syslog(LOG_INFO, "fdCallback(fd: %d, action: %d)", fd, action);
60 #endif
62 switch (action) {
63 case FDCB_FREE:
64 ufb = __chkufb(fd);
65 if (ufb == NULL)
66 return EBADF;
68 if (!(ufb->ufbflg & UFB_SOCK) && ufb->ufbflg != 0) {
69 #ifdef DEBUG
70 syslog(LOG_ERR, "fdCallback: fd (%d) is not a socket!", fd);
71 #endif
72 return ENOTSOCK;
75 ufb->ufbflg = 0;
76 return 0;
78 case FDCB_ALLOC:
79 do {
80 ufb = __allocufb(&fd2);
81 if (ufb == NULL)
82 return ENOMEM;
83 #ifdef DEBUG
84 if (fd2 > fd) {
85 syslog(LOG_ERR, "fdCallback: fd2(%d) > fd(%d)!", fd2, fd);
86 return EINVAL;
88 #endif
89 ufb->ufbflg = UFB_SOCK | UFB_WA | UFB_RA; /* read/write socket */
90 ufb->ufbfh = NULL; /* no file handle */
91 ufb->ufbfn = NULL; /* no name */
92 } while (fd2 < fd);
93 return 0;
95 case FDCB_CHECK:
96 ufb = __chkufb(fd);
97 if (ufb != NULL && ufb->ufbflg != 0)
98 return EBADF;
100 return 0;
102 default:
103 #ifdef DEBUG
104 syslog(LOG_ERR, "fdCallback: invalid action.");
105 #endif
106 return EINVAL;
111 struct UFB *
112 __chkufb(int fd)
114 struct UFB *ufb;
116 /* a single element cache */
117 static struct UFB *last_ufb = NULL;
118 static int last_fd = -1;
120 _OSERR = 0;
122 if ((unsigned int)fd >= __nufbs) { /* unsigned cast checks for (fd < 0) */
123 errno = EBADF;
124 return NULL;
128 * Check the cache first
130 if (fd == last_fd)
131 return last_ufb;
133 last_fd = fd; /* update cache */
134 ufb = __ufbs;
135 while (fd > 0 && ufb != NULL) {
136 fd--;
137 ufb = ufb->ufbnxt;
139 last_ufb = ufb; /* update cache */
141 if (ufb == NULL) {
142 last_fd = -1; /* invalidate cache */
143 errno = EIO;
144 return NULL;
146 else
147 return ufb;