Index: rtl/unix/oscdeclh.inc =================================================================== --- rtl/unix/oscdeclh.inc (revision 12632) +++ rtl/unix/oscdeclh.inc (working copy) @@ -81,10 +81,10 @@ {$ifdef beos} {$ifdef haiku} Function FPSelect (N:cint;readfds,writefds,exceptfds:pfdSet;TimeOut:PTimeVal):cint; cdecl; external 'network' name 'select'; - Function FpPoll (fds: ppollfd; nfds: cuint; timeout: clong): cint; cdecl; external 'network' name 'poll'; + Function FpPoll (fds: ppollfd; nfds: cuint; timeout: clong): cint; cdecl; external clib name 'poll'; {$else} Function FPSelect (N:cint;readfds,writefds,exceptfds:pfdSet;TimeOut:PTimeVal):cint; cdecl; external 'net' name 'select'; - Function FpPoll (fds: ppollfd; nfds: cuint; timeout: clong): cint; cdecl; external 'net' name 'poll'; + Function FpPoll (fds: ppollfd; nfds: cuint; timeout: clong): cint; cdecl; external clib name 'poll'; {$endif} {$else} Function FPSelect (N:cint;readfds,writefds,exceptfds:pfdSet;TimeOut:PTimeVal):cint; cdecl; external clib name 'select'; Index: rtl/unix/cthreads.pp =================================================================== --- rtl/unix/cthreads.pp (revision 12632) +++ rtl/unix/cthreads.pp (working copy) @@ -47,7 +47,9 @@ {$ifndef dynpthreads} // If you have problems compiling this on FreeBSD 5.x {$linklib c} // try adding -Xf {$ifndef Darwin} - {$linklib pthread} + {$ifndef haiku} + {$linklib pthread} + {$endif haiku} {$endif darwin} {$endif} @@ -278,7 +280,9 @@ writeln('Starting new thread'); {$endif DEBUG_MT} pthread_attr_init(@thread_attr); + {$ifndef HAIKU} pthread_attr_setinheritsched(@thread_attr, PTHREAD_EXPLICIT_SCHED); + {$endif} // will fail under linux -- apparently unimplemented pthread_attr_setscope(@thread_attr, PTHREAD_SCOPE_PROCESS); Index: rtl/unix/cwstring.pp =================================================================== --- rtl/unix/cwstring.pp (revision 12632) +++ rtl/unix/cwstring.pp (working copy) @@ -26,8 +26,12 @@ {$linklib c} -{$if not defined(linux) and not defined(solaris) and not defined(haiku)} // Linux (and maybe glibc platforms in general), have iconv in glibc. - {$linklib iconv} +{$if not defined(linux) and not defined(solaris)} // Linux (and maybe glibc platforms in general), have iconv in glibc. + {$if defined(haiku)} + {$linklib textencoding} + {$else} + {$linklib iconv} + {$endif} {$define useiconv} {$endif linux} @@ -42,7 +46,11 @@ {$ifndef useiconv} libiconvname='c'; // is in libc under Linux. {$else} + {$ifdef haiku} + libiconvname='textencoding'; // is in libtextencoding under Haiku + {$else} libiconvname='iconv'; + {$endif} {$endif} { helper functions from libc } @@ -89,7 +97,11 @@ {$ifdef beos} {$warning check correct value for BeOS} CODESET=49; - LC_ALL = 6; // Checked for BeOS, but 0 under Haiku... + {$ifdef haiku} + LC_ALL = 0; // Checked for Haiku + {$else} + LC_ALL = 6; // Checked for BeOS + {$endif} ESysEILSEQ = EILSEQ; {$else} {$error lookup the value of CODESET in /usr/include/langinfo.h, and the value of LC_ALL in /usr/include/locale.h for your OS } @@ -124,7 +136,7 @@ function nl_langinfo(__item:nl_item):pchar;cdecl;external libiconvname name 'nl_langinfo'; {$endif} -{$if (not defined(bsd) and not defined(beos)) or defined(darwin) or defined(haiku)} +{$if (not defined(bsd) and not defined(beos)) or defined(darwin)} function iconv_open(__tocode:pchar; __fromcode:pchar):iconv_t;cdecl;external libiconvname name 'iconv_open'; function iconv(__cd:iconv_t; __inbuf:ppchar; __inbytesleft:psize_t; __outbuf:ppchar; __outbytesleft:psize_t):size_t;cdecl;external libiconvname name 'iconv'; function iconv_close(__cd:iconv_t):cint;cdecl;external libiconvname name 'iconv_close'; Index: rtl/beos/termios.inc =================================================================== --- rtl/beos/termios.inc (revision 12632) +++ rtl/beos/termios.inc (working copy) @@ -415,3 +415,9 @@ Chr(VINTR), Chr(VQUIT), Chr(VERASE), Chr(VKILL), Chr(VEOF), Chr(VEOL), Chr(VEOL2), Chr(VSWTCH), Chr(VSTART), Chr(VSTOP), Chr(VSUSP)); +{ + According to posix/sys/ioctl.h + /* these currently work only on sockets */ +} + FIONBIO = $be000000; + FIONREAD = $be000001; Index: rtl/beos/ostypes.inc =================================================================== --- rtl/beos/ostypes.inc (revision 12632) +++ rtl/beos/ostypes.inc (working copy) @@ -364,3 +364,28 @@ { Constansts for MMAP } const MAP_ANONYMOUS =$1000; + +const + POLLIN = $0001; + POLLOUT = $0002; + POLLERR = $0004; + POLLPRI = $0020; + POLLHUP = $0080; + POLLNVAL = $1000; + + { XOpen, XPG 4.2 } + POLLRDNORM = POLLIN; + POLLRDBAND = $0008; + POLLWRNORM = POLLOUT; + POLLWRBAND = $0010; + +type + pollfd = record + fd: cint; + events: cshort; + revents: cshort; + end; + tpollfd = pollfd; + ppollfd = ^pollfd; + + Index: rtl/haiku/signal.inc =================================================================== --- rtl/haiku/signal.inc (revision 12632) +++ rtl/haiku/signal.inc (working copy) @@ -15,31 +15,39 @@ Const { For sending a signal } - SA_NOCLDSTOP = 1; - - // does not exist under BeOS i think ! - SA_ONSTACK = $001; { take signal on signal stack } - SA_RESTART = $002; { restart system call on signal return } - SA_RESETHAND = $004; { reset to SIG_DFL when taking signal } - SA_NODEFER = $010; { don't mask the signal we're delivering } - SA_NOCLDWAIT = $020; { don't keep zombies around } - SA_SIGINFO = $040; { signal handler with SA_SIGINFO args } - SA_USERTRAMP = $100; { SUNOS compat: Do not bounce off kernel's sigtramp } + SA_NOCLDSTOP = $01; + SA_NOCLDWAIT = $02; + SA_RESETHAND = $03; + SA_NODEFER = $08; + SA_RESTART = $10; + SA_ONSTACK = $20; + SA_SIGINFO = $40; + SA_NOMASK = SA_NODEFER; + SA_STACK = SA_ONSTACK; + SA_ONESHOT = SA_RESETHAND; SIG_BLOCK = 1; SIG_UNBLOCK = 2; SIG_SETMASK = 3; - -{BeOS Checked} + +{ values for ss_flags } + SS_ONSTACK = $1; + SS_DISABLE = $2; + + MINSIGSTKSZ = 4096; + SIGSTKSZ = 16384; + +{Haiku Checked} { The numbering of signals for BeOS attempts to maintain some consistency with UN*X conventions so that things like "kill -9" do what you expect. } - SIG_DFL = 0 ; - SIG_IGN = 1 ; - SIG_ERR = -1 ; + SIG_DFL = 0; + SIG_IGN = 1; + SIG_ERR = -1; + SIG_HOLD = 3; SIGHUP = 1; SIGINT = 2; @@ -63,6 +71,14 @@ SIGWINCH = 20; SIGKILLTHR = 21; SIGTRAP = 22; + SIGPOLL = 23; + SIGPROF = 24; + SIGSYS = 25; + SIGURG = 26; + SIGVTALRM = 27; + SIGXCPU = 28; + SIGXFSZ = 29; + SIGBUS = SIGSEGV; { @@ -283,11 +299,20 @@ // end; sa_Mask : SigSet; sa_Flags : Longint; - sa_userdaa : pointer + sa_userdata : pointer end; PSigActionRec = ^SigActionRec; + pstack_t = ^stack_t; + stack_t = record + ss_sp: pChar; {* signal stack base *} + ss_size: size_t; {* signal stack length *} + ss_flags: cInt; {* SS_DISABLE and/or SS_ONSTACK *} + end; + TStack = stack_t; + PStack = pstack_t; + { Change action of process upon receipt of a signal. Signum specifies the signal (all except SigKill and SigStop). Index: rtl/haiku/termios.inc =================================================================== --- rtl/haiku/termios.inc (revision 12632) +++ rtl/haiku/termios.inc (working copy) @@ -415,3 +415,9 @@ Chr(VINTR), Chr(VQUIT), Chr(VERASE), Chr(VKILL), Chr(VEOF), Chr(VEOL), Chr(VEOL2), Chr(VSWTCH), Chr(VSTART), Chr(VSTOP), Chr(VSUSP)); +{ + According to posix/sys/ioctl.h + /* these currently work only on sockets */ +} + FIONBIO = $be000000; + FIONREAD = $be000001; Index: rtl/haiku/osdefs.inc =================================================================== --- rtl/haiku/osdefs.inc (revision 0) +++ rtl/haiku/osdefs.inc (revision 0) @@ -0,0 +1,23 @@ +{ + Copyright (c) 2000-2002 by Marco van de Voort + + Target dependent defines used when compileing the baseunix unit + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ****************************************************************************} + +{$define usedomain} // Allow uname with "domain" entry. + // (which is a GNU extension) Index: rtl/haiku/ostypes.inc =================================================================== --- rtl/haiku/ostypes.inc (revision 12632) +++ rtl/haiku/ostypes.inc (working copy) @@ -363,7 +363,10 @@ { Constansts for MMAP } const - MAP_ANONYMOUS =$1000; +{$ifdef FPC_IS_SYSTEM} + MAP_PRIVATE =2; +{$endif} + MAP_ANONYMOUS =$08; const POLLIN = $0001; Index: rtl/haiku/baseunix.pp =================================================================== --- rtl/haiku/baseunix.pp (revision 12632) +++ rtl/haiku/baseunix.pp (working copy) @@ -15,32 +15,28 @@ Unit BaseUnix; Interface +{$inline on} +Uses UnixType; -uses UnixType; +{$i osdefs.inc} { Compile time defines } {$i aliasptp.inc} {$packrecords C} -{$define oldreaddir} // Keep using readdir system call instead - // of userland getdents stuff. -{$define usedomain} // Allow uname with "domain" entry. - // (which is a GNU extension) -{$define posixworkaround} // Temporary ugly workaround for signal handler. - // (mainly until baseunix migration is complete) {$ifndef FPC_USE_LIBC} -{$define FPC_USE_SYSCALL} + {$define FPC_USE_SYSCALL} {$endif} -{$i errno.inc} { Error numbers } +{$i errno.inc} { Error numbers } {$i ostypes.inc} {$ifdef FPC_USE_LIBC} -const clib = 'root'; -const netlib = 'network'; -{$i oscdeclh.inc} + const clib = 'root'; + const netlib = 'network'; + {$i oscdeclh.inc} {$ELSE} -{$i bunxh.inc} { Functions} + {$i bunxh.inc} { Functions} {$ENDIF} function fpgeterrno:longint; @@ -62,6 +58,8 @@ {$endif} {$endif} +{$i genfunch.inc} + { Fairly portable constants. I'm not going to waste time to duplicate and alias them anywhere} @@ -83,14 +81,20 @@ implementation +{$ifdef hassysctl} +Uses Sysctl; +{$endif} + {$i genfuncs.inc} // generic calls. (like getenv) {$I gensigset.inc} // general sigset funcs implementation. {$I genfdset.inc} // general fdset funcs. -{$ifndef FPC_USE_LIBC} +{$ifdef FPC_USE_LIBC} + {$i oscdecl.inc} // implementation of wrappers in oscdeclh.inc +{$else} {$i syscallh.inc} // do_syscall declarations themselves {$i sysnr.inc} // syscall numbers. - {$i bsyscall.inc} // cpu specific syscalls + {$i bsyscall.inc} // cpu specific syscalls {$i bunxsysc.inc} // syscalls in system unit. // {$i settimeo.inc} {$endif} Index: rtl/haiku/pthread.inc =================================================================== --- rtl/haiku/pthread.inc (revision 12632) +++ rtl/haiku/pthread.inc (working copy) @@ -45,12 +45,10 @@ function pthread_setspecific (t : pthread_key_t;p:pointer):cint; cdecl; external; function pthread_key_create (p : ppthread_key_t;f: __destr_func_t):cint; cdecl;external; function pthread_attr_init (p : ppthread_attr_t):cint; cdecl; external; -{$ifndef haiku} -function pthread_attr_setinheritsched(p : ppthread_attr_t;i:cint):cint; cdecl; external; +//function pthread_attr_setinheritsched(p : ppthread_attr_t;i:cint):cint; cdecl; external; function pthread_attr_setscope (p : ppthread_attr_t;i:cint):cint;cdecl;external; function pthread_attr_setdetachstate (p : ppthread_attr_t;i:cint):cint;cdecl;external; function pthread_attr_setstacksize(p: ppthread_attr_t; stacksize: size_t):cint;cdecl;external; -{$endif} function pthread_create ( p: ppthread_t;attr : ppthread_attr_t;f:__startroutine_t;arg:pointer):cint;cdecl;external; procedure pthread_exit ( p: pointer); cdecl;external; function pthread_self:pthread_t; cdecl;external; @@ -68,7 +66,6 @@ function pthread_kill(__thread:pthread_t; __signo:cint):cint;cdecl;external; function pthread_sigmask(how: cint; nset: psigset; oset: psigset): cint; cdecl; external; -{$ifndef haiku} function sem_init(__sem:Psem_t; __pshared:cint;__value:dword):cint;cdecl; external; function sem_destroy(__sem:Psem_t):cint;cdecl;external ; function sem_close(__sem:Psem_t):cint;cdecl;external ; @@ -77,7 +74,7 @@ function sem_trywait(__sem:Psem_t):cint;cdecl;external ; function sem_post(__sem:Psem_t):cint;cdecl;external ; function sem_getvalue(__sem:Psem_t; __sval:Pcint):cint;cdecl;external; -{$endif} + function pthread_mutexattr_init(_para1:Ppthread_mutexattr_t):cint;cdecl;external; function pthread_mutexattr_destroy(_para1:Ppthread_mutexattr_t):cint;cdecl;external; function pthread_mutexattr_gettype(_para1:Ppthread_mutexattr_t; _para2:Pcint):cint;cdecl;external; Index: rtl/haiku/system.pp =================================================================== --- rtl/haiku/system.pp (revision 12632) +++ rtl/haiku/system.pp (working copy) @@ -314,21 +314,52 @@ {$i sighnd.inc} +//void set_signal_stack(void *ptr, size_t size); +//int sigaltstack(const stack_t *ss, stack_t *oss); + +procedure set_signal_stack(ptr : pointer; size : size_t); external 'root' name 'set_signal_stack'; +function sigaltstack(const ss : pstack_t; oss : pstack_t) : integer; external 'root' name 'sigaltstack'; + +type + TAlternateSignalStack = record + case Integer of + 0 : (buffer : array[0..SIGSTKSZ] of Char); + 1 : (ld : int64); + 2 : (l : integer); + 3 : (p : pointer); + end; + var act: SigActionRec; + alternate_signal_stack : TAlternateSignalStack; Procedure InstallSignals; +var + oldact: SigActionRec; + r : integer; + st : stack_t; begin + FillChar(st, sizeof(st), 0); + + st.ss_flags := 0; + st.ss_sp := alternate_signal_stack.buffer; + st.ss_size := SizeOf(alternate_signal_stack); + + r := sigaltstack(@st, nil); + + if (r <> 0) then + WriteLn('error sigalstack'); { Initialize the sigaction structure } { all flags and information set to zero } FillChar(act, sizeof(SigActionRec),0); { initialize handler } act.sa_handler := SigActionHandler(@SignalToRunError); - act.sa_flags:=SA_SIGINFO; - FpSigAction(SIGFPE,@act,nil); - FpSigAction(SIGSEGV,@act,nil); - FpSigAction(SIGBUS,@act,nil); - FpSigAction(SIGILL,@act,nil); + act.sa_flags := SA_ONSTACK; + + FpSigAction(SIGFPE,@act,@oldact); + FpSigAction(SIGSEGV,@act,@oldact); + FpSigAction(SIGBUS,@act,@oldact); + FpSigAction(SIGILL,@act,@oldact); end; procedure SysInitStdIO; @@ -352,7 +383,8 @@ IsConsole := TRUE; StackLength := CheckInitialStkLen(InitialStkLen); StackBottom := Sptr - StackLength; - + ReturnNilIfGrowHeapFails := False; + SysResetFPU; if not(IsLibrary) then SysInitFPU; @@ -362,11 +394,12 @@ SysInitStdIO; { Setup heap } - myheapsize:=4096*1;// $ 20000; - myheaprealsize:=4096*1;// $ 20000; + myheapsize:=4096*100;// $ 20000; + myheaprealsize:=4096*100;// $ 20000; heapstart:=nil; heapstartpointer := nil; - heapstartpointer := Sbrk2(4096*1); +// heapstartpointer := Sbrk2(4096*1); + heapstartpointer := SysOSAlloc(4096*100); {$IFDEF FPC_USE_LIBC} // heap_handle := create_area('fpcheap',heapstart,0,myheaprealsize,0,3);//!! {$ELSE} Index: rtl/haiku/tthread.inc =================================================================== --- rtl/haiku/tthread.inc (revision 12632) +++ rtl/haiku/tthread.inc (working copy) @@ -1,613 +0,0 @@ -{ - This file is part of the Free Component Library (FCL) - Copyright (c) 1999-2000 by Peter Vreman - - BeOS TThread implementation - - See the file COPYING.FPC, included in this distribution, - for details about the copyright. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - **********************************************************************} - - -{$IFDEF VER1_0} // leaving the old implementation in for now... -type - PThreadRec=^TThreadRec; - TThreadRec=record - thread : TThread; - next : PThreadRec; - end; - -var - ThreadRoot : PThreadRec; - ThreadsInited : boolean; -// MainThreadID: longint; - -Const - ThreadCount: longint = 0; - -function ThreadSelf:TThread; -var - hp : PThreadRec; - sp : Pointer; -begin - sp:=SPtr; - hp:=ThreadRoot; - while assigned(hp) do - begin - if (sp<=hp^.Thread.FStackPointer) and - (sp>(hp^.Thread.FStackPointer-hp^.Thread.FStackSize)) then - begin - Result:=hp^.Thread; - exit; - end; - hp:=hp^.next; - end; - Result:=nil; -end; - - -//function SIGCHLDHandler(Sig: longint): longint; cdecl;//this is std linux C declaration as function -procedure SIGCHLDHandler(Sig: longint); cdecl; - -begin - fpwaitpid(-1, nil, WNOHANG); -end; - -procedure InitThreads; -var - Act, OldAct: Baseunix.PSigActionRec; -begin - ThreadRoot:=nil; - ThreadsInited:=true; - - -// This will install SIGCHLD signal handler -// signal() installs "one-shot" handler, -// so it is better to install and set up handler with sigaction() - - GetMem(Act, SizeOf(SigActionRec)); - GetMem(OldAct, SizeOf(SigActionRec)); - - Act^.sa_handler := TSigAction(@SIGCHLDHandler); - Act^.sa_flags := SA_NOCLDSTOP {or SA_NOMASK or SA_RESTART}; - Fillchar(Act^.sa_mask,sizeof(Act^.sa_mask),0); //Do not block all signals ??. Don't need if SA_NOMASK in flags - FpSigAction(SIGCHLD, Act, OldAct); - - FreeMem(Act, SizeOf(SigActionRec)); - FreeMem(OldAct, SizeOf(SigActionRec)); -end; - - -procedure DoneThreads; -var - hp : PThreadRec; -begin - while assigned(ThreadRoot) do - begin - ThreadRoot^.Thread.Destroy; - hp:=ThreadRoot; - ThreadRoot:=ThreadRoot^.Next; - dispose(hp); - end; - ThreadsInited:=false; -end; - - -procedure AddThread(t:TThread); -var - hp : PThreadRec; -begin - { Need to initialize threads ? } - if not ThreadsInited then - InitThreads; - - { Put thread in the linked list } - new(hp); - hp^.Thread:=t; - hp^.next:=ThreadRoot; - ThreadRoot:=hp; - - inc(ThreadCount, 1); -end; - - -procedure RemoveThread(t:TThread); -var - lasthp,hp : PThreadRec; -begin - hp:=ThreadRoot; - lasthp:=nil; - while assigned(hp) do - begin - if hp^.Thread=t then - begin - if assigned(lasthp) then - lasthp^.next:=hp^.next - else - ThreadRoot:=hp^.next; - dispose(hp); - exit; - end; - lasthp:=hp; - hp:=hp^.next; - end; - - Dec(ThreadCount, 1); - if ThreadCount = 0 then DoneThreads; -end; - - -{ TThread } -function ThreadProc(args:pointer): Integer;//cdecl; -var - FreeThread: Boolean; - Thread : TThread absolute args; -begin - while Thread.FHandle = 0 do fpsleep(1); - if Thread.FSuspended then Thread.suspend(); - try - Thread.Execute; - except - Thread.FFatalException := TObject(AcquireExceptionObject); - end; - FreeThread := Thread.FFreeOnTerminate; - Result := Thread.FReturnValue; - Thread.FFinished := True; - Thread.DoTerminate; - if FreeThread then - Thread.Free; - fpexit(Result); -end; - - -constructor TThread.Create(CreateSuspended: Boolean); -var - Flags: Integer; -begin - inherited Create; - AddThread(self); - FSuspended := CreateSuspended; - Flags := CLONE_VM + CLONE_FS + CLONE_FILES + CLONE_SIGHAND + SIGCHLD; - { Setup 16k of stack } - FStackSize:=16384; - Getmem(FStackPointer,FStackSize); - inc(FStackPointer,FStackSize); - FCallExitProcess:=false; - { Clone } - FHandle:= Clone(@ThreadProc,FStackPointer,Flags,self); -// if FSuspended then Suspend; - FThreadID := FHandle; - IsMultiThread := TRUE; - FFatalException := nil; -end; - - -destructor TThread.Destroy; -begin - if not FFinished and not Suspended then - begin - Terminate; - WaitFor; - end; - if FHandle <> -1 then - fpkill(FHandle, SIGKILL); - dec(FStackPointer,FStackSize); - Freemem(FStackPointer); - FFatalException.Free; - FFatalException := nil; - inherited Destroy; - RemoveThread(self); -end; - - -procedure TThread.CallOnTerminate; -begin - FOnTerminate(Self); -end; - -procedure TThread.DoTerminate; -begin - if Assigned(FOnTerminate) then - Synchronize(@CallOnTerminate); -end; - - -const -{ I Don't know idle or timecritical, value is also 20, so the largest other - possibility is 19 (PFV) } - Priorities: array [TThreadPriority] of Integer = - (-20,-19,-10,9,10,19,20); - -function TThread.GetPriority: TThreadPriority; -var - P: Integer; - I: TThreadPriority; -begin - P := fpGetPriority(Prio_Process,FHandle); - Result := tpNormal; - for I := Low(TThreadPriority) to High(TThreadPriority) do - if Priorities[I] = P then - Result := I; -end; - - -procedure TThread.SetPriority(Value: TThreadPriority); -begin - fpSetPriority(Prio_Process,FHandle,Priorities[Value]); -end; - - -procedure TThread.Synchronize(Method: TThreadMethod); -begin - FSynchronizeException := nil; - FMethod := Method; -{ SendMessage(ThreadWindow, CM_EXECPROC, 0, Longint(Self)); } - if Assigned(FSynchronizeException) then - raise FSynchronizeException; -end; - - -procedure TThread.SetSuspended(Value: Boolean); -begin - if Value <> FSuspended then - if Value then - Suspend - else - Resume; -end; - - -procedure TThread.Suspend; -begin - FSuspended := true; - fpKill(FHandle, SIGSTOP); -end; - - -procedure TThread.Resume; -begin - fpKill(FHandle, SIGCONT); - FSuspended := False; -end; - - -procedure TThread.Terminate; -begin - FTerminated := True; -end; - -function TThread.WaitFor: Integer; -var - status : longint; -begin - if FThreadID = MainThreadID then - fpwaitpid(0,@status,0) - else - fpwaitpid(FHandle,@status,0); - Result:=status; -end; -{$ELSE} - -{ - What follows, is a short description on my implementation of TThread. - Most information can also be found by reading the source and accompanying - comments. - - A thread is created using BeginThread, which in turn calls - pthread_create. So the threads here are always posix threads. - Posix doesn't define anything for suspending threads as this is - inherintly unsafe. Just don't suspend threads at points they cannot - control. Therefore, I didn't implement .Suspend() if its called from - outside the threads execution flow (except on Linux _without_ NPTL). - - The implementation for .suspend uses a semaphore, which is initialized - at thread creation. If the thread tries to suspend itself, we simply - let it wait on the semaphore until it is unblocked by someone else - who calls .Resume. - - If a thread is supposed to be suspended (from outside its own path of - execution) on a system where the symbol LINUX is defined, two things - are possible. - 1) the system has the LinuxThreads pthread implementation - 2) the system has NPTL as the pthread implementation. - - In the first case, each thread is a process on its own, which as far as - know actually violates posix with respect to signal handling. - But we can detect this case, because getpid(2) will - return a different PID for each thread. In that case, sending SIGSTOP - to the PID associated with a thread will actually stop that thread - only. - In the second case, this is not possible. But getpid(2) returns the same - PID across all threads, which is detected, and TThread.Suspend() does - nothing in that case. This should probably be changed, but I know of - no way to suspend a thread when using NPTL. - - If the symbol LINUX is not defined, then the unimplemented - function SuspendThread is called. - - Johannes Berg , Sunday, November 16 2003 -} - -// ========== semaphore stuff ========== -{ - I don't like this. It eats up 2 filedescriptors for each thread, - and those are a limited resource. If you have a server programm - handling client connections (one per thread) it will not be able - to handle many if we use 2 fds already for internal structures. - However, right now I don't see a better option unless some sem_* - functions are added to systhrds. - I encapsulated all used functions here to make it easier to - change them completely. -} - -{BeOS implementation} - -function SemaphoreInit: Pointer; -begin - SemaphoreInit := GetMem(SizeOf(TFilDes)); - fppipe(PFilDes(SemaphoreInit)^); -end; - -procedure SemaphoreWait(const FSem: Pointer); -var - b: byte; -begin - fpread(PFilDes(FSem)^[0], b, 1); -end; - -procedure SemaphorePost(const FSem: Pointer); -var - b : byte; -begin - b := 0; - fpwrite(PFilDes(FSem)^[1], b, 1); -end; - -procedure SemaphoreDestroy(const FSem: Pointer); -begin - fpclose(PFilDes(FSem)^[0]); - fpclose(PFilDes(FSem)^[1]); - FreeMemory(FSem); -end; - -// =========== semaphore end =========== - -var - ThreadsInited: boolean = false; -{$IFDEF LINUX} - GMainPID: LongInt = 0; -{$ENDIF} -const - // stupid, considering its not even implemented... - Priorities: array [TThreadPriority] of Integer = - (-20,-19,-10,0,9,18,19); - -procedure InitThreads; -begin - if not ThreadsInited then begin - ThreadsInited := true; - {$IFDEF LINUX} - GMainPid := fpgetpid(); - {$ENDIF} - end; -end; - -procedure DoneThreads; -begin - ThreadsInited := false; -end; - -{ ok, so this is a hack, but it works nicely. Just never use - a multiline argument with WRITE_DEBUG! } -{$MACRO ON} -{$IFDEF DEBUG_MT} -{$define WRITE_DEBUG := writeln} // actually write something -{$ELSE} -{$define WRITE_DEBUG := //} // just comment out those lines -{$ENDIF} - -function ThreadFunc(parameter: Pointer): LongInt; // cdecl; -var - LThread: TThread; - c: char; -begin - WRITE_DEBUG('ThreadFunc is here...'); - LThread := TThread(parameter); - {$IFDEF LINUX} - // save the PID of the "thread" - // this is different from the PID of the main thread if - // the LinuxThreads implementation is used - LThread.FPid := fpgetpid(); - {$ENDIF} - WRITE_DEBUG('thread initing, parameter = ', LongInt(LThread)); - try - if LThread.FInitialSuspended then begin - SemaphoreWait(LThread.FSem); - if not LThread.FInitialSuspended then begin - WRITE_DEBUG('going into LThread.Execute'); - LThread.Execute; - end; - end else begin - WRITE_DEBUG('going into LThread.Execute'); - LThread.Execute; - end; - except - on e: exception do begin - WRITE_DEBUG('got exception: ',e.message); - LThread.FFatalException := TObject(AcquireExceptionObject); - // not sure if we should really do this... - // but .Destroy was called, so why not try FreeOnTerminate? - if e is EThreadDestroyCalled then LThread.FFreeOnTerminate := true; - end; - end; - WRITE_DEBUG('thread done running'); - Result := LThread.FReturnValue; - WRITE_DEBUG('Result is ',Result); - LThread.FFinished := True; - LThread.DoTerminate; - if LThread.FreeOnTerminate then begin - WRITE_DEBUG('Thread should be freed'); - LThread.Free; - WRITE_DEBUG('Thread freed'); - end; - WRITE_DEBUG('thread func exiting'); -end; - -{ TThread } -constructor TThread.Create(CreateSuspended: Boolean; const StackSize: SizeUInt = DefaultStackSize); -var - data : pointer; -begin - // lets just hope that the user doesn't create a thread - // via BeginThread and creates the first TThread Object in there! - InitThreads; - inherited Create; - FSem := SemaphoreInit; - FSuspended := CreateSuspended; - FSuspendedExternal := false; - FInitialSuspended := CreateSuspended; - FFatalException := nil; - WRITE_DEBUG('creating thread, self = ',longint(self)); - FHandle:= BeginThread(@ThreadFunc, Pointer(Self), FThreadID); - WRITE_DEBUG('TThread.Create done'); -end; - - -destructor TThread.Destroy; -begin - if FThreadID = GetCurrentThreadID then begin - raise EThreadDestroyCalled.Create('A thread cannot destroy itself except by setting FreeOnTerminate and leaving!'); - end; - // if someone calls .Free on a thread with - // FreeOnTerminate, then don't crash! - FFreeOnTerminate := false; - if not FFinished and not FSuspended then begin - Terminate; - WaitFor; - end; - if (FInitialSuspended) then begin - // thread was created suspended but never woken up. - SemaphorePost(FSem); - WaitFor; - end; - FFatalException.Free; - FFatalException := nil; - SemaphoreDestroy(FSem); - inherited Destroy; -end; - -procedure TThread.SetSuspended(Value: Boolean); -begin - if Value <> FSuspended then - if Value then - Suspend - else - Resume; -end; - -procedure TThread.Suspend; -begin - if not FSuspended then begin - if FThreadID = GetCurrentThreadID then begin - FSuspended := true; - SemaphoreWait(FSem); - end else begin - FSuspendedExternal := true; -{$IFDEF LINUX} - // naughty hack if the user doesn't have Linux with NPTL... - // in that case, the PID of threads will not be identical - // to the other threads, which means that our thread is a normal - // process that we can suspend via SIGSTOP... - // this violates POSIX, but is the way it works on the - // LinuxThreads pthread implementation. Not with NPTL, but in that case - // getpid(2) also behaves properly and returns the same PID for - // all threads. Thats actually (FINALLY!) native thread support :-) - if FPid <> GMainPID then begin - FSuspended := true; - fpkill(FPid, SIGSTOP); - end; -{$ELSE} - SuspendThread(FHandle); -{$ENDIF} - end; - end; -end; - - -procedure TThread.Resume; -begin - if (not FSuspendedExternal) then begin - if FSuspended then begin - SemaphorePost(FSem); - FInitialSuspended := false; - FSuspended := False; - end; - end else begin -{$IFDEF LINUX} - // see .Suspend - if FPid <> GMainPID then begin - fpkill(FPid, SIGCONT); - FSuspended := False; - end; -{$ELSE} - ResumeThread(FHandle); -{$ENDIF} - FSuspendedExternal := false; - end; -end; - - -procedure TThread.Terminate; -begin - FTerminated := True; -end; - -function TThread.WaitFor: Integer; -begin - WRITE_DEBUG('waiting for thread ',FHandle); - WaitFor := WaitForThreadTerminate(FHandle, 0); - WRITE_DEBUG('thread terminated'); -end; - -procedure TThread.CallOnTerminate; -begin - // no need to check if FOnTerminate <> nil, because - // thats already done in DoTerminate - FOnTerminate(self); -end; - -procedure TThread.DoTerminate; -begin - if Assigned(FOnTerminate) then - Synchronize(@CallOnTerminate); -end; - -function TThread.GetPriority: TThreadPriority; -var - P: Integer; - I: TThreadPriority; -begin - P := ThreadGetPriority(FHandle); - Result := tpNormal; - for I := Low(TThreadPriority) to High(TThreadPriority) do - if Priorities[I] = P then - Result := I; -end; - -(* -procedure TThread.Synchronize(Method: TThreadMethod); -begin -{$TODO someone with more clue of the GUI stuff will have to do this} -end; -*) -procedure TThread.SetPriority(Value: TThreadPriority); -begin - ThreadSetPriority(FHandle, Priorities[Value]); -end; -{$ENDIF} - Index: rtl/inc/stdsock.inc =================================================================== --- rtl/inc/stdsock.inc (revision 12632) +++ rtl/inc/stdsock.inc (working copy) @@ -14,7 +14,16 @@ {$define uselibc:=cdecl; external;} -const libname='c'; +const + {$ifdef BEOS} + {$ifdef HAIKU} + libname = 'network'; + {$else} + libname = 'net'; + {$endif} + {$else} + libname='c'; + {$endif} function cfpaccept (s:cint; addrx : psockaddr; addrlen : psocklen):cint; cdecl; external libname name 'accept'; function cfpbind (s:cint; addrx : psockaddr; addrlen : tsocklen):cint; cdecl; external libname name 'bind'; @@ -32,7 +41,12 @@ function cfpsetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen :tsocklen):cint; cdecl; external libname name 'setsockopt'; function cfpshutdown (s:cint; how:cint):cint; cdecl; external libname name 'shutdown'; function cfpsocket (domain:cint; xtype:cint; protocol: cint):cint; cdecl; external libname name 'socket'; + +{$if defined(BEOS) and not defined(HAIKU)} +// function unavailable under BeOS +{$else} function cfpsocketpair (d:cint; xtype:cint; protocol:cint; sv:pcint):cint; cdecl; external libname name 'socketpair'; +{$endif} function fpaccept (s:cint; addrx : psockaddr; addrlen : psocklen):cint; @@ -120,9 +134,16 @@ internal_socketerror:=fpgeterrno; end; +{$if defined(BEOS) and not defined(HAIKU)} +// function unavailable under BeOS function fpsocketpair (d:cint; xtype:cint; protocol:cint; sv:pcint):cint; begin + internal_socketerror:= -1; // TODO : check if it is an error +end; +{$else} +function fpsocketpair (d:cint; xtype:cint; protocol:cint; sv:pcint):cint; +begin fpsocketpair:=cfpsocketpair(d,xtype,protocol,sv); internal_socketerror:=fpgeterrno; end; - +{$endif} Index: packages/fcl-xml/Makefile.fpc =================================================================== --- packages/fcl-xml/Makefile.fpc (revision 12632) +++ packages/fcl-xml/Makefile.fpc (working copy) @@ -17,6 +17,8 @@ [require] packages=fcl-base +packages_beos=iconvenc +packages_haiku=iconvenc packages_linux=iconvenc packages_darwin=iconvenc packages_freebsd=iconvenc Index: packages/iconvenc/src/iconvenc.pas =================================================================== --- packages/iconvenc/src/iconvenc.pas (revision 12632) +++ packages/iconvenc/src/iconvenc.pas (working copy) @@ -31,6 +31,10 @@ const n = 1; +{$ifdef beos} + ESysEILSEQ = EILSEQ; +{$endif} + type piconv_t = ^iconv_t; iconv_t = pointer; Index: packages/Makefile.fpc =================================================================== --- packages/Makefile.fpc (revision 12632) +++ packages/Makefile.fpc (working copy) @@ -15,10 +15,12 @@ dirs_m68k_linux=graph dirs_beos=fv fcl-web fcl-async ibase mysql ncurses zlib oracle odbc postgres sqlite pthreads imagemagick \ gdbint libpng x11 gdbm tcl syslog libcurl opengl bfd aspell svgalib \ - imlib utmp fpgtk xforms fftw pcap ggi sdl openssl graph gnome1 gtk1 gtk2 librsvg httpd13 httpd20 httpd22 pxlib numlib + imlib utmp fpgtk xforms fftw pcap ggi sdl openssl graph gnome1 gtk1 gtk2 librsvg httpd13 httpd20 httpd22 pxlib numlib \ + iconvenc dirs_haiku=fv fcl-web fcl-async ibase mysql ncurses zlib oracle odbc postgres sqlite pthreads imagemagick \ gdbint libpng x11 gdbm tcl syslog libcurl opengl bfd aspell svgalib \ - imlib utmp fpgtk xforms fftw pcap ggi sdl openssl graph gnome1 gtk1 gtk2 librsvg httpd13 httpd20 httpd22 pxlib numlib + imlib utmp fpgtk xforms fftw pcap ggi sdl openssl graph gnome1 gtk1 gtk2 librsvg httpd13 httpd20 httpd22 pxlib numlib \ + iconvenc dirs_freebsd=fv fcl-web fcl-async ibase mysql ncurses zlib oracle odbc postgres sqlite pthreads imagemagick \ gdbint libpng x11 gdbm tcl syslog libcurl opengl cairo bfd aspell svgalib \ imlib utmp fpgtk xforms fftw pcap ggi sdl openssl graph gnome1 gtk1 gtk2 librsvg httpd13 httpd20 httpd22 pxlib numlib \ Index: packages/pthreads/src/pthreads.pp =================================================================== --- packages/pthreads/src/pthreads.pp (revision 12632) +++ packages/pthreads/src/pthreads.pp (working copy) @@ -35,7 +35,11 @@ {$else} {$ifdef beos} uses initc, ctypes, baseunix, unixtype; - {$i pthrbeos.inc} + {$ifdef haiku} + {$i pthrhaiku.inc} + {$else} + {$i pthrbeos.inc} + {$endif} {$else} {$error operating system not detected} {$endif}