set rpm package release in configure.in. nowhere else.
[privoxy.git] / amiga.c
1 const char amiga_rcs[] = "$Id: amiga.c,v 1.6 2002/03/09 20:03:52 jongfoster Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/amiga.c,v $
5  *
6  * Purpose     :  Amiga-specific declarations.
7  *
8  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
9  *                Privoxy team.  http://ijbswa.sourceforge.net
10  *
11  *                This program is free software; you can redistribute it 
12  *                and/or modify it under the terms of the GNU General
13  *                Public License as published by the Free Software
14  *                Foundation; either version 2 of the License, or (at
15  *                your option) any later version.
16  *
17  *                This program is distributed in the hope that it will
18  *                be useful, but WITHOUT ANY WARRANTY; without even the
19  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
20  *                PARTICULAR PURPOSE.  See the GNU General Public
21  *                License for more details.
22  *
23  *                The GNU General Public License should be included with
24  *                this file.  If not, you can view it at
25  *                http://www.gnu.org/copyleft/gpl.html
26  *                or write to the Free Software Foundation, Inc., 59
27  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28  *
29  * Revisions   :
30  *    $Log: amiga.c,v $
31  *    Revision 1.6  2002/03/09 20:03:52  jongfoster
32  *    - Making various functions return int rather than size_t.
33  *      (Undoing a recent change).  Since size_t is unsigned on
34  *      Windows, functions like read_socket that return -1 on
35  *      error cannot return a size_t.
36  *
37  *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
38  *      crashes, and also frequently caused JB to jump to 100%
39  *      CPU and stay there.  (Because it thought it had just
40  *      read ((unsigned)-1) == 4Gb of data...)
41  *
42  *    - The signature of write_socket has changed, it now simply
43  *      returns success=0/failure=nonzero.
44  *
45  *    - Trying to get rid of a few warnings --with-debug on
46  *      Windows, I've introduced a new type "jb_socket".  This is
47  *      used for the socket file descriptors.  On Windows, this
48  *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
49  *      an int.  The error value can't be -1 any more, so it's
50  *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
51  *      Windows it maps to the #define INVALID_SOCKET.)
52  *
53  *    - The signature of bind_port has changed.
54  *
55  *    Revision 1.5  2002/03/03 09:18:03  joergs
56  *    Made jumbjuster work on AmigaOS again.
57  *
58  *    Revision 1.4  2001/10/07 15:35:13  oes
59  *    Replaced 6 boolean members of csp with one bitmap (csp->flags)
60  *
61  *    Revision 1.3  2001/09/12 22:54:51  joergs
62  *    Stacksize of main thread increased.
63  *
64  *    Revision 1.2  2001/05/23 00:13:58  joergs
65  *    AmigaOS support fixed.
66  *
67  *    Revision 1.1.1.1  2001/05/15 13:58:46  oes
68  *    Initial import of version 2.9.3 source tree
69  *
70  *
71  *********************************************************************/
72 \f
73
74 #include "config.h"
75
76 #ifdef AMIGA
77
78 #include <stdio.h>
79 #include <signal.h>
80
81 #include "project.h"
82
83 const char amiga_h_rcs[] = AMIGA_H_VERSION;
84
85 unsigned long __stack = 100*1024;
86 static char ver[] = "$VER: junkbuster " __AMIGAVERSION__ " (" __AMIGADATE__ ")";
87 struct Task *main_task = NULL;
88 int childs = 0;
89
90 void serve(struct client_state *csp);
91
92 __saveds ULONG server_thread(void)
93 {
94    struct client_state *local_csp;
95    struct UserData UserData;
96    struct Task *me=FindTask(NULL);
97
98    Wait(SIGF_SINGLE);
99    local_csp=(struct client_state *)(me->tc_UserData);
100    me->tc_UserData=&UserData;
101    SocketBase=(APTR)OpenLibrary("bsdsocket.library",3);
102    if(SocketBase)
103    {
104       SetErrnoPtr(&(UserData.eno),sizeof(int));
105       local_csp->cfd=ObtainSocket(local_csp->cfd, AF_INET, SOCK_STREAM, 0);
106       if(JB_INVALID_SOCKET!=local_csp->cfd)
107       {
108          Signal(main_task,SIGF_SINGLE);
109          serve((struct client_state *) local_csp);
110       } else {
111          local_csp->flags &= ~CSP_FLAG_ACTIVE;
112          Signal(main_task,SIGF_SINGLE);
113       }
114       CloseLibrary(SocketBase);
115    } else {
116       local_csp->flags &= ~CSP_FLAG_ACTIVE;
117       Signal(main_task,SIGF_SINGLE);
118    }
119    childs--;
120    return 0;
121 }
122
123 static BPTR olddir;
124
125 void amiga_exit(void)
126 {
127    if(SocketBase)
128    {
129       CloseLibrary(SocketBase);
130    }
131    CurrentDir(olddir);
132 }
133
134 static struct SignalSemaphore memsem;
135 static struct SignalSemaphore *memsemptr = NULL;
136 static struct UserData GlobalUserData;
137
138 void InitAmiga(void)
139 {
140    main_task = FindTask(NULL);
141    main_task->tc_UserData = &GlobalUserData;
142
143    if (((struct Library *)SysBase)->lib_Version < 39)
144    {
145       exit(RETURN_FAIL);
146    }
147
148    signal(SIGINT,SIG_IGN);
149    SocketBase = (APTR)OpenLibrary("bsdsocket.library",3);
150    if (!SocketBase)
151    {
152       fprintf(stderr, "Can't open bsdsocket.library V3+\n");
153       exit(RETURN_ERROR);
154    }
155    SetErrnoPtr(&(GlobalUserData.eno),sizeof(int));
156    InitSemaphore(&memsem);
157    memsemptr = &memsem;
158
159    olddir=CurrentDir(GetProgramDir());
160    atexit(amiga_exit);
161 }
162
163 #ifdef __GNUC__
164 #ifdef libnix
165 /* multithreadingsafe libnix replacements */
166 static void *memPool=NULL;
167
168 void *malloc (size_t s)
169 {
170    ULONG *mem;
171    LONG size = s;
172
173    if (size<=0)
174    {
175       return NULL;
176    }
177    if (!memPool)
178    {
179       if (!(memPool=CreatePool(MEMF_ANY,32*1024,8*1024)))
180       {
181          return NULL;
182       }
183    }
184    size += sizeof(ULONG) + MEM_BLOCKMASK;
185    size &= ~MEM_BLOCKMASK;
186    if (memsemptr)
187    {
188       ObtainSemaphore(memsemptr);
189    }
190    if ((mem=AllocPooled(memPool,size)))
191    {
192       *mem++=size;
193    }
194    if (memsemptr)
195    {
196       ReleaseSemaphore(memsemptr);
197    }
198    return mem;
199 }
200
201 void free (void *m)
202 {
203    ULONG *mem = m;
204
205    if(mem && memPool)
206    {
207       ULONG size=*--mem;
208
209       if (memsemptr)
210       {
211          ObtainSemaphore(memsemptr);
212       }
213       FreePooled(memPool,mem,size);
214       if (memsemptr)
215       {
216          ReleaseSemaphore(memsemptr);
217       }
218    }
219 }
220
221 void *realloc (void *old, size_t ns)
222 {
223    void *new;
224    LONG osize, *o = old;
225    LONG nsize = ns;
226
227    if (!old)
228    {
229       return malloc(nsize);
230    }
231    osize = (*(o-1)) - sizeof(ULONG);
232    if (nsize <= osize)
233    {
234       return old;
235    }
236    if ((new = malloc(nsize)))
237    {
238       ULONG *n = new;
239
240       osize >>= 2;
241       while(osize--)
242       {
243          *n++ = *o++;
244       }
245       free(old);
246    }
247    return new;
248 }
249
250 void __memCleanUp (void)
251 {
252    if (memsemptr)
253    {
254       ObtainSemaphore(memsemptr);
255    }
256    if (memPool)
257    {
258       DeletePool(memPool);
259    }
260    if (memsemptr)
261    {
262       ReleaseSemaphore(memsemptr);
263    }
264 }
265
266 #define ADD2LIST(a,b,c) asm(".stabs \"_" #b "\"," #c ",0,0,_" #a )
267 #define ADD2EXIT(a,pri) ADD2LIST(a,__EXIT_LIST__,22); \
268                         asm(".stabs \"___EXIT_LIST__\",20,0,0," #pri "+128")
269 ADD2EXIT(__memCleanUp,-50);
270 #elif !defined(ixemul)
271 #error No libnix and no ixemul!?
272 #endif /* libnix */
273 #else
274 #error Only GCC is supported, multithreading safe malloc/free required.
275 #endif /* __GNUC__ */
276
277 #endif /* def AMIGA */