use m4_normalize on the output strings to remove trailing spaces/tabs and consolidate...
[AROS.git] / workbench / c / Break.c
blobe12f00d925e653c62d129892893659aa01adeb3e
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Break - send a signal to a process.
6 Lang: english
7 */
9 /*****************************************************************************
11 NAME
12 Break
14 FORMAT
15 Break <process> [ALL|C|D|E|F]
17 SYNOPSIS
18 PROCESS/N,PORT,NAME/K,ALL/S,C/S,D/S,E/S,F/S
20 LOCATION
23 FUNCTION
24 BREAK sends one or more signals to a CLI process.
25 The argument PROCESS specifies the numeric ID of the CLI process that
26 you wish to send the signal to. The STATUS command will list all currently
27 running CLI processes along with ther ID.
28 You can also specify a public port name and send signal's to the
29 port's task.
31 You can send all signals at once via option ALL or any combination of the
32 flags CTRL-C, CTRL-D, CTRL-E and CTRL-F by their respective options.
33 When only the CLI process ID is specified the CTRL-C signal will be sent.
35 The effect of using the BREAK command is the same as selecting
36 the console window of a process and pressing the relevant key
37 combination.
39 The normal meaning of the keys is:
40 CTRL-C - Halt a process
41 CTRL-D - Halt a shell script
42 CTRL-E - Close a process' window
43 CTRL-F - Make active the process' window
45 Not all programs respond to these signals, however most should
46 respond to CTRL-C.
48 EXAMPLE
50 1.SYS:> BREAK 1
52 Send the CTRL-C signal to the process numbered 1.
54 1.SYS:> BREAK 4 E
56 Send the CTRL-E signal to the process numbered 4.
58 1.SYS:> BREAK NAME c:dhcpclient
60 Send the CTRL-C signal to the process named "c:dhcpclient".
62 ******************************************************************************/
64 #include <exec/types.h>
65 #include <exec/tasks.h>
66 #include <dos/dos.h>
67 #include <dos/dosextens.h>
68 #include <dos/rdargs.h>
69 #include <utility/tagitem.h>
70 #include <proto/exec.h>
71 #include <proto/dos.h>
73 #define ARG_TEMPLATE "PROCESS/N,PORT,NAME/K,C/S,D/S,E/S,F/S,ALL/S"
74 #define ARG_PROCESS 0
75 #define ARG_PORT 1
76 #define ARG_NAME 2
77 #define ARG_C 3
78 #define ARG_D 4
79 #define ARG_E 5
80 #define ARG_F 6
81 #define ARG_ALL 7
82 #define TOTAL_ARGS 8
84 const TEXT version[] = "$VER: Break 42.1 (8.12.2007)";
86 static const char exthelp[] =
87 "Break: Send break signal(s) to a CLI process\n"
88 "\tPROCESS/N signal receiver's CLI process number\n"
89 "\tPORT Portname for the Process to set flags for\n"
90 "\tNAME/K Name of the process (as shown by tasklist)\n"
91 "\tC/S send CTRL-C signal\n"
92 "\tD/S send CTRL-D signal\n"
93 "\tE/S send CTRL-E signal\n"
94 "\tF/S send CTRL-F signal\n"
95 "\tALL/S send all signals\n";
97 int __nocommandline = 1;
101 main(void)
103 struct RDArgs *rd, *rda = NULL;
105 IPTR args[TOTAL_ARGS] = { };
107 int error = 0;
109 if ((rda = AllocDosObject(DOS_RDARGS, NULL)))
111 rda->RDA_ExtHelp = (STRPTR) exthelp;
113 if ((rd = ReadArgs(ARG_TEMPLATE, (IPTR *) args, rda)))
115 struct Process *pr = NULL;
116 Forbid();
117 if (args[ARG_PROCESS])
118 pr = FindCliProc(*(IPTR *) args[ARG_PROCESS]);
119 else if (args[ARG_PORT])
121 struct MsgPort *MyPort;
122 if ((MyPort = (struct MsgPort*) FindPort((STRPTR) args[ARG_PORT])) != NULL)
124 pr = (struct Process*) MyPort->mp_SigTask;
127 else if (args[ARG_NAME])
129 pr = (struct Process *) FindTask((UBYTE *)args[ARG_NAME]);
131 if (pr != NULL)
133 ULONG
134 mask = 0;
136 /* Figure out the mask of flags to send. */
137 if (args[ARG_ALL])
139 mask = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D
140 | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F;
142 else
144 mask = (args[ARG_C] != 0 ? SIGBREAKF_CTRL_C : 0)
145 | (args[ARG_D] != 0 ? SIGBREAKF_CTRL_D : 0)
146 | (args[ARG_E] != 0 ? SIGBREAKF_CTRL_E : 0)
147 | (args[ARG_F]!= 0 ? SIGBREAKF_CTRL_F : 0);
149 if (0 == mask)
151 mask = SIGBREAKF_CTRL_C; /* default */
155 Signal((struct Task *) pr, mask);
156 Permit();
158 else
160 /* There is no relevant error code, OBJECT_NOT_FOUND
161 * is a filesystem error, so we can't use that... */
162 Permit();
163 pr = (struct Process *) FindTask(NULL);
165 BPTR errStream = (pr->pr_CES != BNULL)
166 ? pr->pr_CES
167 : Output();
169 if (args[ARG_PROCESS])
171 VFPrintf(errStream, "Break: Process %ld does not exist.\n", (APTR) args[ARG_PROCESS]);
173 else if (args[ARG_PORT])
175 FPrintf(errStream, "Break: Port \"%s\" does not exist.\n", (LONG) args[ARG_PORT]);
177 else if (args[ARG_NAME])
179 FPrintf(errStream, "Break: Task \"%s\" does not exist.\n", (LONG) args[ARG_NAME]);
181 else
183 FPuts(errStream, "Break: Either PROCESS, PORT or NAME is required.\n");
185 error = -1;
188 FreeArgs(rd);
189 } /* ReadArgs() ok */
190 else
192 error = IoErr();
195 FreeDosObject(DOS_RDARGS, rda);
196 } /* Got rda */
197 else
199 error = IoErr();
202 if (error != 0 && error != -1)
204 PrintFault(error, "Break");
205 return RETURN_FAIL;
208 SetIoErr(0);
210 return 0;