2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
5 Desc: Execute a loaded command synchronously
9 #include <aros/debug.h>
10 #include <exec/memory.h>
11 #include <dos/dosextens.h>
12 #include <dos/filehandler.h>
13 #include <proto/arossupport.h>
14 #include <proto/exec.h>
15 #include <proto/dos.h>
19 #include "dos_intern.h"
21 /* Under AOS, BCPL handlers expect to receive a pointer to their
22 * startup packet in D1.
24 * This wrapper is here to support that.
26 void BCPL_RunHandler(void);
28 struct MsgPort
*RunHandler(struct DeviceNode
*deviceNode
, const char *path
, struct DosLibrary
*DOSBase
)
30 D(struct FileSysStartupMsg
*fssm
= NULL
;)
32 struct MsgPort
*reply_port
;
33 struct Process
*process
= NULL
;
39 handler
= AROS_BSTR_ADDR(deviceNode
->dn_Handler
);
41 /* No possible way to continue? */
42 if (deviceNode
->dn_SegList
== BNULL
&& handler
== NULL
)
45 if (deviceNode
->dn_SegList
== BNULL
) {
46 struct Segment
*seg
= NULL
;
48 /* Try to find in the Resident Segment list */
50 D(bug("[RunHandler] Looking for handler '%s' in resident list\n",
52 seg
= FindSegment(handler
, NULL
, TRUE
);
55 deviceNode
->dn_SegList
= seg
? seg
->seg_Seg
: BNULL
;
58 if (deviceNode
->dn_SegList
== BNULL
) {
59 D(bug("[RunHandler] LoadSeg(\"%s\")\n", handler
));
61 deviceNode
->dn_SegList
= LoadSeg(handler
);
64 if (deviceNode
->dn_SegList
== BNULL
) {
65 CONST_STRPTR cp
= FilePart(handler
);
69 dir
= Lock("L:", SHARED_LOCK
);
72 olddir
= CurrentDir(dir
);
73 D(bug("[RunHandler] LoadSeg(\"L:%s\")\n", cp
));
74 deviceNode
->dn_SegList
= LoadSeg(cp
);
80 if (deviceNode
->dn_SegList
== BNULL
) {
81 D(bug("[RunHandler] name '%b' seglist=NULL?\n", deviceNode
->dn_Name
));
87 bpath
= CreateBSTR(path
);
93 path
= AROS_BSTR_ADDR(deviceNode
->dn_Name
);
94 len
= AROS_BSTR_strlen(deviceNode
->dn_Name
);
95 bpath
= MKBADDR(AllocVec(AROS_BSTR_MEMSIZE4LEN(len
+ 1), MEMF_PUBLIC
));
99 CopyMem(path
, AROS_BSTR_ADDR(bpath
), len
);
100 AROS_BSTR_ADDR(bpath
)[len
++] = ':';
101 AROS_BSTR_setstrlen(bpath
, len
);
104 D(bug("[RunHandler] in open by Task '%s'\n", FindTask(NULL
)->tc_Node
.ln_Name
));
106 D(if ((IPTR
)deviceNode
->dn_Startup
>= 64)) /* really an FSSM? */
107 D(fssm
= (struct FileSysStartupMsg
*)BADDR(deviceNode
->dn_Startup
);)
109 D(bug("[RunHandler] devicenode=%08lx path='%b' devicename '%b' unit %d dosname '%b' handler=%x seg=%08lx startup=%08lx\n",
112 fssm
? fssm
->fssm_Device
: BNULL
,
113 fssm
? fssm
->fssm_Unit
: 0,
115 deviceNode
->dn_Handler
,
116 deviceNode
->dn_SegList
,
117 deviceNode
->dn_Startup
));
119 D(bug("RunHandler: %b has GlobalVec = %d\n", deviceNode
->dn_Name
, (SIPTR
)deviceNode
->dn_GlobalVec
));
122 /* BCPL file-handler support */
123 if (deviceNode
->dn_GlobalVec
!= (BPTR
)-1 && deviceNode
->dn_GlobalVec
!= (BPTR
)-2)
124 entry
= BCPL_RunHandler
;
127 entry
= BADDR(deviceNode
->dn_SegList
)+sizeof(IPTR
);
129 D(bug("[RunHandler] stacksize %d priority %d\n",
130 deviceNode
->dn_StackSize
,
131 deviceNode
->dn_Priority
));
134 process
= CreateNewProcTags(
135 NP_Entry
, (IPTR
)entry
,
136 NP_Seglist
, (IPTR
)deviceNode
->dn_SegList
,
137 NP_FreeSeglist
, (IPTR
)FALSE
,
138 NP_Name
, AROS_BSTR_ADDR(deviceNode
->dn_Name
), /* GB: always NUL terminated */
139 NP_StackSize
, deviceNode
->dn_StackSize
,
140 NP_Priority
, deviceNode
->dn_Priority
,
143 D(bug("[RunHandler] started, process structure is 0x%08x\n", process
));
144 reply_port
= CreateMsgPort();
146 FreeVec(BADDR(bpath
));
150 /* build the startup packet */
151 dp
= (struct DosPacket
*) AllocDosObject(DOS_STDPKT
, NULL
);
153 DeleteMsgPort(reply_port
);
154 FreeVec(BADDR(bpath
));
157 dp
->dp_Arg1
= (SIPTR
)bpath
;
158 dp
->dp_Arg2
= (SIPTR
)deviceNode
->dn_Startup
;
159 dp
->dp_Arg3
= (SIPTR
)MKBADDR(deviceNode
);
160 dp
->dp_Port
= reply_port
;
162 /* A handler can add volumes during startup, so we have to be fully functional before it
163 replies the startup packet */
165 D(bug("[RunHandler] sending startup packet port=%x\n", &(process
->pr_MsgPort
)));
166 PutMsg(&(process
->pr_MsgPort
), dp
->dp_Link
);
167 WaitPort(reply_port
);
170 DeleteMsgPort(reply_port
);
171 FreeVec(BADDR(bpath
));
173 if (dp
->dp_Res1
== DOSFALSE
)
175 D(bug("[RunHandler] handler failed startup [%d]\n", dp
->dp_Res2
));
177 deviceNode
->dn_Task
= NULL
; /* Some handlers (e.g. SFS) don't clear dn_Task upon failure. */
179 D(else bug("[RunHandler] '%b' now online, dn_Task 0x%p, pr_MsgPort 0x%p\n", deviceNode
->dn_Name
, deviceNode
->dn_Task
, &process
->pr_MsgPort
);)
181 FreeDosObject(DOS_STDPKT
, dp
);
183 return process
? &process
->pr_MsgPort
: NULL
;