2 * Copyright 2009, Michael Lotz, mmlr@mlotz.ch
3 * Distributed under the terms of the MIT License.
11 static sem_id sRequestSem
= -1;
12 static char sCommandBuffer
[1024];
13 static uint32 sCommandOffset
= 0;
14 static uint32 sCommandCount
= 0;
18 run_on_exit_loop(void *data
)
21 if (acquire_sem(sRequestSem
) != B_OK
)
24 char *pointer
= sCommandBuffer
;
25 while (sCommandCount
> 0) {
26 uint8 argCount
= (uint8
)pointer
[0];
29 const char *args
[argCount
];
30 for (uint8 i
= 0; i
< argCount
; i
++) {
32 uint32 length
= strlen(pointer
);
33 pointer
+= length
+ 1;
36 thread_id thread
= load_image(argCount
, args
, NULL
);
38 resume_thread(thread
);
50 add_run_on_exit_command(int argc
, char **argv
)
52 if (argc
< 2 || strcmp(argv
[1], "--help") == 0) {
53 print_debugger_command_usage(argv
[0]);
58 kprintf("too many arguments\n");
62 size_t totalLength
= 1;
63 for (int32 i
= 1; i
< argc
; i
++)
64 totalLength
+= strlen(argv
[i
]) + 1;
66 if (sCommandOffset
+ totalLength
> sizeof(sCommandBuffer
)) {
67 kprintf("no space left in command buffer\n");
71 char *pointer
= sCommandBuffer
+ sCommandOffset
;
72 *pointer
++ = (char)(argc
- 1);
74 for (int32 i
= 1; i
< argc
; i
++) {
75 strcpy(pointer
, argv
[i
]);
76 pointer
+= strlen(argv
[i
]) + 1;
79 sCommandOffset
+= totalLength
;
88 if (sCommandCount
> 0)
89 release_sem_etc(sRequestSem
, 1, B_DO_NOT_RESCHEDULE
);
94 std_ops(int32 op
, ...)
96 if (op
== B_MODULE_INIT
) {
97 sRequestSem
= create_sem(0, "run_on_exit_request");
98 if (sRequestSem
< B_OK
)
101 thread_id thread
= spawn_kernel_thread(&run_on_exit_loop
,
102 "run_on_exit_loop", B_NORMAL_PRIORITY
, NULL
);
106 resume_thread(thread
);
108 add_debugger_command_etc("on_exit", &add_run_on_exit_command
,
109 "Adds a command to be run when leaving the kernel debugger",
110 "<command> [<arguments>]\n"
111 "Adds a command to be run when leaving the kernel debugger.\n", 0);
114 } else if (op
== B_MODULE_UNINIT
) {
115 remove_debugger_command("on_exit", &add_run_on_exit_command
);
116 // deleting the sem will also cause the thread to exit
117 delete_sem(sRequestSem
);
126 static struct debugger_module_info sModuleInfo
= {
128 "debugger/run_on_exit/v1",
139 module_info
*modules
[] = {
140 (module_info
*)&sModuleInfo
,