2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Common startup code
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
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
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
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()
32 #include <aros/config.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__)
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_entry
,
58 AROS_UFHA(char *,argstr
,A0
),
59 AROS_UFHA(ULONG
,argsize
,D0
),
60 AROS_UFHA(struct ExecBase
*,SysBase
,A6
)) __attribute__((section(".aros.startup")));
62 AROS_UFP3(static LONG
, __detach_trampoline
,
63 AROS_UFHA(char *,argstr
,A0
),
64 AROS_UFHA(ULONG
,argsize
,D0
),
65 AROS_UFHA(struct ExecBase
*,SysBase
,A6
));
67 AROS_UFH3(static LONG
, __detach_entry
,
68 AROS_UFHA(char *,argstr
,A0
),
69 AROS_UFHA(ULONG
,argsize
,D0
),
70 AROS_UFHA(struct ExecBase
*,SysBase
,A6
))
74 struct DosLibrary
*DOSBase
;
75 struct CommandLineInterface
*cli
;
76 struct Process
*newproc
;
77 BPTR mysegment
= NULL
;
80 DOSBase
= (struct DosLibrary
*)OpenLibrary(DOSNAME
, 39);
81 if (!DOSBase
) return RETURN_FAIL
;
84 /* Without a CLI detaching makes no sense, just jump to
88 #if 0 /* gcc 4.0 trouble. static follows non-static bla bla bla */
89 AROS_UFC3(LONG
, SETELEM(__detach_entry
, program_entries
)[1],
90 AROS_UFHA(char *,argstr
,A0
),
91 AROS_UFHA(ULONG
,argsize
,D0
),
92 AROS_UFHA(struct ExecBase
*,SysBase
,A6
));
94 AROS_UFC3(LONG
, SETNAME(PROGRAM_ENTRIES
)[1 + 1],
95 AROS_UFHA(char *,argstr
,A0
),
96 AROS_UFHA(ULONG
,argsize
,D0
),
97 AROS_UFHA(struct ExecBase
*,SysBase
,A6
));
102 mysegment
= cli
->cli_Module
;
103 cli
->cli_Module
= NULL
;
105 detached_name
= __detached_name
? __detached_name
: (STRPTR
)FindTask(NULL
)->tc_Node
.ln_Name
;
108 struct TagItem tags
[] =
110 { NP_Seglist
, (IPTR
)mysegment
},
111 { NP_Entry
, (IPTR
)&__detach_trampoline
},
112 { NP_Name
, (IPTR
)detached_name
},
113 { NP_Arguments
, (IPTR
)argstr
},
118 __detacher_process
= (struct Process
*)FindTask(NULL
);
120 /* CreateNewProc() will take care of freeing the seglist */
121 newproc
= CreateNewProc(tags
);
124 CloseLibrary((struct Library
*)DOSBase
);
128 cli
->cli_Module
= mysegment
;
129 __detached_return_value
= RETURN_ERROR
;
132 while (!__detacher_go_away
) Wait(SIGF_SINGLE
);
134 if (__detached_return_value
!= RETURN_OK
)
136 PutStr(FindTask(NULL
)->tc_Node
.ln_Name
); PutStr(": Failed to detach.\n");
142 Signal(&newproc
->pr_Task
, SIGF_SINGLE
);
145 return __detached_return_value
;
150 DEFINESET(PROGRAM_ENTRIES
);
151 ADD2SET(__detach_entry
, program_entries
, 0);
153 void __Detach(LONG retval
);
155 AROS_UFH3(static LONG
, __detach_trampoline
,
156 AROS_UFHA(char *,argstr
,A0
),
157 AROS_UFHA(ULONG
,argsize
,D0
),
158 AROS_UFHA(struct ExecBase
*,SysBase
,A6
))
164 /* The program has two options: either take care of telling the detacher
165 process when exactly to go away, via the Detach() function, or let this
166 startup code take care of it. If __detached_manages_detach is TRUE, then
167 the detached process handles it, otherwise we handle it. */
169 if (!__detached_manages_detach
)
172 #if 0 /* gcc 4.0 trouble. static follows non-static bla bla bla */
174 retval
= AROS_UFC3(LONG
, SETELEM(__detach_entry
, program_entries
)[1],
175 AROS_UFHA(char *,argstr
,A0
),
176 AROS_UFHA(ULONG
,argsize
,D0
),
177 AROS_UFHA(struct ExecBase
*,SysBase
,A6
));
179 retval
= AROS_UFC3(LONG
, SETNAME(PROGRAM_ENTRIES
)[1 + 1],
180 AROS_UFHA(char *,argstr
,A0
),
181 AROS_UFHA(ULONG
,argsize
,D0
),
182 AROS_UFHA(struct ExecBase
*,SysBase
,A6
));
185 /* At this point the detacher process might still be around,
186 If the program forgot to detach, or if it couldn't, but in any
187 case we need to tell the detacher to go away. */
195 void __Detach(LONG retval
)
197 if (__detacher_process
!= NULL
)
199 __detached_return_value
= retval
;
200 __detacher_go_away
= TRUE
;
202 SetSignal(0, SIGF_SINGLE
);
203 /* Tell the detacher process it can now go away */
204 Signal(&__detacher_process
->pr_Task
, SIGF_SINGLE
);
206 /* Wait for it to say "goodbye" */
208 __detacher_process
= NULL
;