New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / compiler / startup / detach.c
blob0109b3aded384bbdef439fdff611073a3cd8145b
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Common startup code
6 Lang: english
8 Use: To make a program detach itself from the launching CLI, use
9 detach.o as your program's start file, before any other usual start
10 file.
12 If you want the detached process to have a name different than the
13 detacher's one, define the following variable in your program's
14 source code:
16 STRPTR __detached_name = "My Preferred Program Name";
18 You can also decide to control exactly when to detach your program
19 from the shell. To do so, simply use the function
21 Detach();
23 declared in
25 <aros/detach.h>
27 when you want to detach the program. Not using this function will
28 result in your program being detached from the shell before the main()
29 function is reached.
32 #include <aros/config.h>
33 #include <dos/dos.h>
34 #include <proto/exec.h>
35 #include <proto/dos.h>
36 #include <aros/asmcall.h>
37 #include <aros/symbolsets.h>
39 #if (AROS_FLAVOUR & AROS_FLAVOUR_NATIVE & defined __mc68000__)
40 asm
42 ".text\n"
43 "\n"
44 "move.l 4.w,a6\n"
45 "bra _detach_entry\n"
47 #endif
49 int __detached_manages_detach;
50 int __detacher_go_away;
51 STRPTR __detached_name;
52 LONG __detached_return_value;
53 struct Process *__detacher_process;
55 DECLARESET(PROGRAM_ENTRIES);
57 AROS_UFP3(static LONG, __detach_trampoline,
58 AROS_UFHA(char *,argstr,A0),
59 AROS_UFHA(ULONG,argsize,D0),
60 AROS_UFHA(struct ExecBase *,SysBase,A6));
62 AROS_UFH3(static LONG, __detach_entry,
63 AROS_UFHA(char *,argstr,A0),
64 AROS_UFHA(ULONG,argsize,D0),
65 AROS_UFHA(struct ExecBase *,SysBase,A6))
67 AROS_USERFUNC_INIT
69 struct DosLibrary *DOSBase;
70 struct CommandLineInterface *cli;
71 struct Process *newproc;
72 BPTR mysegment = NULL;
73 STRPTR detached_name;
75 DOSBase = (struct DosLibrary *)OpenLibrary(DOSNAME, 39);
76 if (!DOSBase) return RETURN_FAIL;
78 cli = Cli();
79 /* Without a CLI detaching makes no sense, just jump to
80 the real program. */
81 if (!cli)
83 #if 0 /* gcc 4.0 trouble. static follows non-static bla bla bla */
84 AROS_UFC3(LONG, SETELEM(__detach_entry, program_entries)[1],
85 AROS_UFHA(char *,argstr,A0),
86 AROS_UFHA(ULONG,argsize,D0),
87 AROS_UFHA(struct ExecBase *,SysBase,A6));
88 #else
89 AROS_UFC3(LONG, SETNAME(PROGRAM_ENTRIES)[1 + 1],
90 AROS_UFHA(char *,argstr,A0),
91 AROS_UFHA(ULONG,argsize,D0),
92 AROS_UFHA(struct ExecBase *,SysBase,A6));
93 #endif
97 mysegment = cli->cli_Module;
98 cli->cli_Module = NULL;
100 detached_name = __detached_name ? __detached_name : (STRPTR)FindTask(NULL)->tc_Node.ln_Name;
103 struct TagItem tags[] =
105 { NP_Seglist, (IPTR)mysegment },
106 { NP_Entry, (IPTR)&__detach_trampoline },
107 { NP_Name, (IPTR)detached_name },
108 { NP_Arguments, (IPTR)argstr },
109 { NP_Cli, TRUE },
110 { TAG_DONE, 0 }
113 __detacher_process = (struct Process *)FindTask(NULL);
115 /* CreateNewProc() will take care of freeing the seglist */
116 newproc = CreateNewProc(tags);
119 CloseLibrary((struct Library *)DOSBase);
121 if (!newproc)
123 cli->cli_Module = mysegment;
124 __detached_return_value = RETURN_ERROR;
126 else
127 while (!__detacher_go_away) Wait(SIGF_SINGLE);
129 if (__detached_return_value != RETURN_OK)
131 PutStr(FindTask(NULL)->tc_Node.ln_Name); PutStr(": Failed to detach.\n");
134 if (newproc)
136 Forbid();
137 Signal(&newproc->pr_Task, SIGF_SINGLE);
140 return __detached_return_value;
142 AROS_USERFUNC_EXIT
145 DEFINESET(PROGRAM_ENTRIES);
146 ADD2SET(__detach_entry, program_entries, 0);
148 void __Detach(LONG retval);
150 AROS_UFH3(static LONG, __detach_trampoline,
151 AROS_UFHA(char *,argstr,A0),
152 AROS_UFHA(ULONG,argsize,D0),
153 AROS_UFHA(struct ExecBase *,SysBase,A6))
155 AROS_USERFUNC_INIT
157 LONG retval;
159 /* The program has two options: either take care of telling the detacher
160 process when exactly to go away, via the Detach() function, or let this
161 startup code take care of it. If __detached_manages_detach is TRUE, then
162 the detached process handles it, otherwise we handle it. */
164 if (!__detached_manages_detach)
165 __Detach(RETURN_OK);
167 #if 0 /* gcc 4.0 trouble. static follows non-static bla bla bla */
169 retval = AROS_UFC3(LONG, SETELEM(__detach_entry, program_entries)[1],
170 AROS_UFHA(char *,argstr,A0),
171 AROS_UFHA(ULONG,argsize,D0),
172 AROS_UFHA(struct ExecBase *,SysBase,A6));
173 #else
174 retval = AROS_UFC3(LONG, SETNAME(PROGRAM_ENTRIES)[1 + 1],
175 AROS_UFHA(char *,argstr,A0),
176 AROS_UFHA(ULONG,argsize,D0),
177 AROS_UFHA(struct ExecBase *,SysBase,A6));
178 #endif
180 /* At this point the detacher process might still be around,
181 If the program forgot to detach, or if it couldn't, but in any
182 case we need to tell the detacher to go away. */
183 __Detach(retval);
185 return 0;
187 AROS_USERFUNC_EXIT
190 void __Detach(LONG retval)
192 if (__detacher_process != NULL)
194 __detached_return_value = retval;
195 __detacher_go_away = TRUE;
197 SetSignal(0, SIGF_SINGLE);
198 /* Tell the detacher process it can now go away */
199 Signal(&__detacher_process->pr_Task, SIGF_SINGLE);
201 /* Wait for it to say "goodbye" */
202 Wait(SIGF_SINGLE);
203 __detacher_process = NULL;