add a comment about the cygwin -mwindows build flag
[privoxy.git] / amiga.c
1 /*********************************************************************
2  *
3  * File        :  $Source: /cvsroot/ijbswa/current/amiga.c,v $
4  *
5  * Purpose     :  Amiga-specific declarations.
6  *
7  * Copyright   :  Written by and Copyright (C) 2001 members of the
8  *                Privoxy team. http://www.privoxy.org/
9  *
10  *                This program is free software; you can redistribute it
11  *                and/or modify it under the terms of the GNU General
12  *                Public License as published by the Free Software
13  *                Foundation; either version 2 of the License, or (at
14  *                your option) any later version.
15  *
16  *                This program is distributed in the hope that it will
17  *                be useful, but WITHOUT ANY WARRANTY; without even the
18  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
19  *                PARTICULAR PURPOSE.  See the GNU General Public
20  *                License for more details.
21  *
22  *                The GNU General Public License should be included with
23  *                this file.  If not, you can view it at
24  *                http://www.gnu.org/copyleft/gpl.html
25  *                or write to the Free Software Foundation, Inc., 59
26  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  *
28  *********************************************************************/
29
30
31 #include "config.h"
32
33 #ifdef AMIGA
34
35 #include <stdio.h>
36 #include <signal.h>
37
38 #include "project.h"
39
40 static char *ver USED = "$VER: Privoxy " __AMIGAVERSION__ " (" __AMIGADATE__ ")";
41 #ifdef __amigaos4__
42 static char *stack USED = "$STACK: 524288";
43 #else
44 unsigned long __stack = 100*1024;
45 #endif
46 struct Task *main_task = NULL;
47 int childs = 0;
48
49 void serve(struct client_state *csp);
50
51 SAVEDS ULONG server_thread(void)
52 {
53    struct client_state *local_csp;
54    struct UserData UserData;
55    struct Task *me=FindTask(NULL);
56 #ifdef __amigaos4__
57    struct Library *SocketBase;
58 #endif
59
60    Wait(SIGF_SINGLE);
61    local_csp=(struct client_state *)(me->tc_UserData);
62    me->tc_UserData=&UserData;
63    SocketBase=(APTR)OpenLibrary("bsdsocket.library",3);
64    if (SocketBase)
65 #ifdef __amigaos4__
66    {
67       ISocket = (struct SocketIFace *)GetInterface(SocketBase, "main", 1, NULL);
68    }
69    if (ISocket)
70 #endif
71    {
72       SetErrnoPtr(&(UserData.eno),sizeof(int));
73       local_csp->cfd=ObtainSocket(local_csp->cfd, AF_INET, SOCK_STREAM, 0);
74       if (JB_INVALID_SOCKET!=local_csp->cfd)
75       {
76          Signal(main_task,SIGF_SINGLE);
77          serve((struct client_state *) local_csp);
78       } else {
79          local_csp->flags &= ~CSP_FLAG_ACTIVE;
80          Signal(main_task,SIGF_SINGLE);
81       }
82 #ifdef __amigaos4__
83       DropInterface((struct Interface *)ISocket);
84 #endif
85       CloseLibrary(SocketBase);
86    } else {
87 #ifdef __amigaos4__
88       CloseLibrary(SocketBase);
89 #endif
90       local_csp->flags &= ~CSP_FLAG_ACTIVE;
91       Signal(main_task,SIGF_SINGLE);
92    }
93    childs--;
94    return 0;
95 }
96
97 static BPTR olddir;
98
99 void amiga_exit(void)
100 {
101 #ifdef __amigaos4__
102    if (ISocket)
103 #else
104    if (SocketBase)
105 #endif
106    {
107 #ifdef __amigaos4__
108       struct Library *SocketBase = ISocket->Data.LibBase;
109       DropInterface((struct Interface *)ISocket);
110 #endif
111       CloseLibrary(SocketBase);
112    }
113    CurrentDir(olddir);
114 }
115
116 #ifndef __amigaos4__
117 static struct SignalSemaphore memsem;
118 static struct SignalSemaphore *memsemptr = NULL;
119 #endif
120 static struct UserData GlobalUserData;
121
122 void InitAmiga(void)
123 {
124 #ifdef __amigaos4__
125    struct Library *SocketBase;
126 #endif
127
128    main_task = FindTask(NULL);
129    main_task->tc_UserData = &GlobalUserData;
130
131    if (((struct Library *)SysBase)->lib_Version < 39)
132    {
133       exit(RETURN_FAIL);
134    }
135
136    signal(SIGINT,SIG_IGN);
137    SocketBase = (APTR)OpenLibrary("bsdsocket.library",3);
138 #ifdef __amigaos4__
139    if (SocketBase)
140    {
141       ISocket = (struct SocketIFace *)GetInterface(SocketBase, "main", 1, NULL);
142    }
143    if (!ISocket)
144 #else
145    if (!SocketBase)
146 #endif
147    {
148 #ifdef __amigaos4__
149       CloseLibrary(SocketBase);
150 #endif
151       fprintf(stderr, "Can't open bsdsocket.library V3+\n");
152       exit(RETURN_ERROR);
153    }
154    SetErrnoPtr(&(GlobalUserData.eno),sizeof(int));
155 #ifndef __amigaos4__
156    InitSemaphore(&memsem);
157    memsemptr = &memsem;
158 #endif
159
160    olddir=CurrentDir(GetProgramDir());
161    atexit(amiga_exit);
162 }
163
164 #ifndef __amigaos4__
165 #ifdef __GNUC__
166 #ifdef libnix
167 /* multithreadingsafe libnix replacements */
168 static void *memPool=NULL;
169
170 void *malloc (size_t s)
171 {
172    ULONG *mem;
173    LONG size = s;
174
175    if (size<=0)
176    {
177       return NULL;
178    }
179    if (!memPool)
180    {
181       if (!(memPool=CreatePool(MEMF_ANY,32*1024,8*1024)))
182       {
183          return NULL;
184       }
185    }
186    size += sizeof(ULONG) + MEM_BLOCKMASK;
187    size &= ~MEM_BLOCKMASK;
188    if (memsemptr)
189    {
190       ObtainSemaphore(memsemptr);
191    }
192    if ((mem=AllocPooled(memPool,size)))
193    {
194       *mem++=size;
195    }
196    if (memsemptr)
197    {
198       ReleaseSemaphore(memsemptr);
199    }
200    return mem;
201 }
202
203 void free (void *m)
204 {
205    ULONG *mem = m;
206
207    if (mem && memPool)
208    {
209       ULONG size=*--mem;
210
211       if (memsemptr)
212       {
213          ObtainSemaphore(memsemptr);
214       }
215       FreePooled(memPool,mem,size);
216       if (memsemptr)
217       {
218          ReleaseSemaphore(memsemptr);
219       }
220    }
221 }
222
223 void *realloc (void *old, size_t ns)
224 {
225    void *new;
226    LONG osize, *o = old;
227    LONG nsize = ns;
228
229    if (!old)
230    {
231       return malloc(nsize);
232    }
233    osize = (*(o-1)) - sizeof(ULONG);
234    if (nsize <= osize)
235    {
236       return old;
237    }
238    if ((new = malloc(nsize)))
239    {
240       ULONG *n = new;
241
242       osize >>= 2;
243       while(osize--)
244       {
245          *n++ = *o++;
246       }
247       free(old);
248    }
249    return new;
250 }
251
252 void __memCleanUp (void)
253 {
254    if (memsemptr)
255    {
256       ObtainSemaphore(memsemptr);
257    }
258    if (memPool)
259    {
260       DeletePool(memPool);
261    }
262    if (memsemptr)
263    {
264       ReleaseSemaphore(memsemptr);
265    }
266 }
267
268 #define ADD2LIST(a,b,c) asm(".stabs \"_" #b "\"," #c ",0,0,_" #a)
269 #define ADD2EXIT(a,pri) ADD2LIST(a,__EXIT_LIST__,22); \
270                         asm(".stabs \"___EXIT_LIST__\",20,0,0," #pri "+128")
271 ADD2EXIT(__memCleanUp,-50);
272 #elif !defined(ixemul)
273 #error No libnix and no ixemul!?
274 #endif /* libnix */
275 #else
276 #error Only GCC is supported, multithreading safe malloc/free required.
277 #endif /* __GNUC__ */
278 #endif /* !__amigaos4__ */
279
280 #endif /* def AMIGA */