mirror of
https://github.com/cahirwpz/libnix.git
synced 2026-09-12 03:30:43 +00:00
Move sources root to main directory.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
CC = @CC@
|
||||
CPP = @CPP@
|
||||
AS = @AS@
|
||||
|
||||
AR = @AR@
|
||||
RANLIB = @RANLIB@
|
||||
AWK = @AWK@
|
||||
|
||||
#### End system configuration section ####
|
||||
|
||||
OBJECTS=detach.o swapstack.o
|
||||
|
||||
OPTIONS=-I$(srcdir)/../headers $(CFLAGS)
|
||||
|
||||
vpath %.c $(SOURCEDIR)
|
||||
|
||||
REDEF=-D_DOSBase=___DOSBase \
|
||||
-D_UtilityBase=___UtilityBase \
|
||||
-D_MathIeeeSingBasBase=___MathIeeeSingBasBase \
|
||||
-D_MathIeeeSingTransBase=___MathIeeeSingTransBase \
|
||||
-D_MathIeeeDoubBasBase=___MathIeeeDoubBasBase \
|
||||
-D_MathIeeeDoubTransBase=___MathIeeeDoubTransBase \
|
||||
-D_LocaleBase=___LocaleBase
|
||||
|
||||
#Use private library bases to avoid naming collisions
|
||||
%.o: %.c
|
||||
$(CC) $(OPTIONS) -S $^ -o $*.S 2>&1|tee $*.err
|
||||
$(CPP) -traditional $(REDEF) $*.S -o $*2.S
|
||||
$(CC) $(OPTIONS) $*2.S -c -o $*.o
|
||||
-rm $*.S $*2.S
|
||||
-if test ! -s $*.err; then rm $*.err; fi
|
||||
echo "\$$$(V)" >>$*.o
|
||||
|
||||
.PHONY: all filelist subdirs clean veryclean
|
||||
|
||||
all: $(OBJECTS)
|
||||
|
||||
filelist:
|
||||
|
||||
subdirs:
|
||||
|
||||
clean:
|
||||
-rm -f *.o *.err
|
||||
|
||||
veryclean: clean
|
||||
@@ -0,0 +1,87 @@
|
||||
#include <exec/memory.h>
|
||||
#include <dos/dostags.h>
|
||||
#include <dos/dosextens.h>
|
||||
#include <proto/exec.h>
|
||||
#include <proto/dos.h>
|
||||
#include <stdlib.h>
|
||||
#include "stabs.h"
|
||||
|
||||
/* Sorry, but the assembler code produced by gcc for this function is too bad.
|
||||
* This one is much better!
|
||||
*/
|
||||
#ifdef CreateNewProcTags
|
||||
#undef CreateNewProcTags
|
||||
static APTR createnewproctags(APTR DOSBase,ULONG Tag,...)
|
||||
{ return CreateNewProc((struct TagItem *)&Tag); }
|
||||
#define CreateNewProcTags(tag...) createnewproctags(DOSBase,tag)
|
||||
#endif
|
||||
|
||||
extern struct WBStart *_WBenchMsg;
|
||||
extern char *__commandline;
|
||||
extern void *__SaveSP;
|
||||
extern char __dosname[];
|
||||
|
||||
extern char *__procname;
|
||||
extern long __priority;
|
||||
extern unsigned long __stack;
|
||||
|
||||
/* I must close a library after my child is running -
|
||||
* and closing a library requires a working dispatcher (IMHO).
|
||||
* Also semaphores are much smarter ;). Therefore:
|
||||
*/
|
||||
static struct SignalSemaphore *sem = NULL;
|
||||
|
||||
void __initdetach(void)
|
||||
{ struct Library *DOSBase,*SysBase = *(struct Library **)4;
|
||||
struct SignalSemaphore *sema;
|
||||
|
||||
if (_WBenchMsg)
|
||||
return;
|
||||
|
||||
if ((sema=sem)) { /* I must be the child process */
|
||||
ObtainSemaphore(sema); /* Assert that my parent is already dead */
|
||||
ReleaseSemaphore(sema);
|
||||
FreeMem(sema,sizeof(*sema));
|
||||
return;
|
||||
}
|
||||
/* I must be the parent */
|
||||
if ((sem=sema=(struct SignalSemaphore *)AllocMem(sizeof(*sema),MEMF_PUBLIC|MEMF_CLEAR))) {
|
||||
|
||||
InitSemaphore(sema);
|
||||
|
||||
if ((DOSBase=OpenLibrary(__dosname,37))) {
|
||||
|
||||
struct CommandLineInterface *cli = Cli();
|
||||
APTR pr,stack = __SaveSP;
|
||||
|
||||
ObtainSemaphore(sema); /* Assert that my child is suspended until I'm finished */
|
||||
|
||||
pr = CreateNewProcTags(NP_Seglist,cli->cli_Module, /* child process gets my seglist */
|
||||
NP_FreeSeglist,1, /* and must free it */
|
||||
NP_Cli,1, /* it must be a CLI process */
|
||||
NP_StackSize,__stack, /* it gets a stack */
|
||||
NP_Name,(ULONG)__procname, /* a name */
|
||||
NP_Priority,__priority, /* a priority */
|
||||
NP_Arguments,(ULONG)__commandline,/* and my commandline Arguments */
|
||||
TAG_END);
|
||||
CloseLibrary(DOSBase);
|
||||
|
||||
if (pr) {
|
||||
|
||||
cli->cli_Module = 0; /* I'm no longer owner of this */
|
||||
|
||||
/* Adjust stack, release semaphore and return 0 in one.
|
||||
* Maybe the 3 movel are a bit too cautious, but they ARE working
|
||||
*/
|
||||
asm("movel %0,sp;movel %1,a6;movel %2,a0;moveql #0,d0;jmp a6@(-570)"::
|
||||
"r"(stack),"r"(SysBase),"r"(sema):"sp","a6","a0");
|
||||
}
|
||||
|
||||
ReleaseSemaphore(sema); /* Again only caution - you never know */
|
||||
}
|
||||
FreeMem(sema,sizeof(*sema)); /* Couldn't start child :( */
|
||||
}
|
||||
exit(20);
|
||||
}
|
||||
|
||||
ADD2INIT(__initdetach,-70); /* A very high priority */
|
||||
@@ -0,0 +1,104 @@
|
||||
#include <exec/memory.h>
|
||||
#include <dos/dosextens.h>
|
||||
#include <proto/exec.h>
|
||||
#include <proto/dos.h>
|
||||
#include <stdlib.h>
|
||||
#include "stabs.h"
|
||||
|
||||
/*
|
||||
* swapstack.c
|
||||
*
|
||||
* A libnix startup module to swap to a new stack if the old one is not
|
||||
* big enough (minimum value set by the value of the __stack variable).
|
||||
*
|
||||
* WARNING!
|
||||
* Compile with -O3, or your Amiga will explode!
|
||||
*
|
||||
* Code derived from a stackswap module by Kriton Kyrimis (kyrimis@theseas.ntua.gr)
|
||||
* with some changes to work with the libnix startups (MF).
|
||||
* You use it at your own risk.
|
||||
*
|
||||
* Usage: Define some variable 'unsigned long __stack={desired size};'
|
||||
* somewhere in your code and link with this module.
|
||||
* The file stabs.h is in the headers directory of the libnix sources.
|
||||
*/
|
||||
|
||||
extern unsigned long __stack;
|
||||
void __request(const char *text);
|
||||
|
||||
static struct StackSwapStruct stack;
|
||||
static char *newstack;
|
||||
|
||||
void __stkinit(long a)
|
||||
{ APTR SysBase = *(APTR *)4;
|
||||
register char *sp asm("sp");
|
||||
ULONG size,needed=__stack;
|
||||
struct Process *pr;
|
||||
char *new;
|
||||
|
||||
asm("":"=r"(sp)); /* touch sp to get compiler happy */
|
||||
|
||||
/* Determine original stack size */
|
||||
|
||||
pr=(struct Process *)FindTask(NULL);
|
||||
|
||||
size = (char *)pr->pr_Task.tc_SPUpper - (char *)pr->pr_Task.tc_SPLower;
|
||||
|
||||
if (pr->pr_CLI) {
|
||||
size = *(ULONG *)pr->pr_ReturnAddr;
|
||||
}
|
||||
|
||||
if (needed <= size)
|
||||
return;
|
||||
|
||||
/* Round size to next long word */
|
||||
needed = (needed+(sizeof(LONG)-1))&~(sizeof(LONG)-1);
|
||||
|
||||
/* Allocate new stack */
|
||||
newstack = new = AllocVec(needed,MEMF_PUBLIC);
|
||||
if (!new) {
|
||||
__request("Couldn't allocate new stack!");
|
||||
exit(RETURN_FAIL);
|
||||
}
|
||||
|
||||
/* Build new stack structure */
|
||||
size=(char *)&a-sp+2*sizeof(ULONG);
|
||||
stack.stk_Lower =new;
|
||||
stack.stk_Upper =(ULONG)(new+=needed);
|
||||
stack.stk_Pointer=(APTR)(new-=size);
|
||||
|
||||
/* Copy required parts of old stack */
|
||||
CopyMem(sp,new,size);
|
||||
|
||||
/* Switch to new stack */
|
||||
StackSwap(&stack);
|
||||
}
|
||||
|
||||
void __stkexit(ULONG a)
|
||||
{ APTR SysBase = *(APTR *)4;
|
||||
register char *sp asm("sp");
|
||||
ULONG size;
|
||||
char *new;
|
||||
|
||||
asm("":"=r"(sp)); /* touch sp to get compiler happy */
|
||||
|
||||
if(!(new=newstack))
|
||||
return;
|
||||
|
||||
/* Prepare old stack */
|
||||
size=(char *)&a-sp+3*sizeof(ULONG);
|
||||
stack.stk_Pointer=(APTR)((char *)stack.stk_Pointer-size);
|
||||
|
||||
/* Copy required parts of current stack */
|
||||
CopyMem(sp,stack.stk_Pointer,size);
|
||||
|
||||
/* Switch back to old stack */
|
||||
StackSwap(&stack);
|
||||
|
||||
/* And clean up */
|
||||
FreeVec(new);
|
||||
}
|
||||
|
||||
/* The same priority as the detach module - you cannot use them both */
|
||||
ADD2INIT(__stkinit,-70);
|
||||
ADD2EXIT(__stkexit,-70);
|
||||
Reference in New Issue
Block a user