added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / workbench / c / Break.c
blobe186e0b84693d8fe5c57683fe32fc67c1ea670f6
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,ALL/S,C/S,D/S,E/S,F/S
20 LOCATION
21 Sys:c
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 **************************************************************************/
60 #include <exec/types.h>
61 #include <exec/tasks.h>
62 #include <dos/dos.h>
63 #include <dos/dosextens.h>
64 #include <dos/rdargs.h>
65 #include <utility/tagitem.h>
66 #include <proto/exec.h>
67 #include <proto/dos.h>
69 #define ARG_TEMPLATE "PROCESS/N,PORT,C/S,D/S,E/S,F/S,ALL/S"
70 #define ARG_PROCESS 0
71 #define ARG_PORT 1
72 #define ARG_C 2
73 #define ARG_D 3
74 #define ARG_E 4
75 #define ARG_F 5
76 #define ARG_ALL 6
77 #define TOTAL_ARGS 7
79 const TEXT version[] = "$VER: Break 42.1 (8.12.2007)";
81 static const char exthelp[] =
82 "Break: Send break signal(s) to a CLI process\n"
83 "\tPROCESS/N signal receiver's CLI process number\n"
84 "\tPORT Portname for the Process to set flags for\n"
85 "\tC/S send CTRL-C signal\n"
86 "\tD/S send CTRL-D signal\n"
87 "\tE/S send CTRL-E signal\n"
88 "\tF/S send CTRL-F signal\n"
89 "\tALL/S send all signals\n";
91 int __nocommandline = 1;
94 int
95 main(void)
97 struct RDArgs *rd, *rda = NULL;
99 IPTR args[TOTAL_ARGS] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
101 int error = 0;
103 if ((rda = AllocDosObject(DOS_RDARGS, NULL)))
105 rda->RDA_ExtHelp = (STRPTR) exthelp;
107 if ((rd = ReadArgs(ARG_TEMPLATE, (LONG *) args, rda)))
109 struct Process *pr = NULL;
110 Forbid();
111 if (args[ARG_PROCESS])
112 pr = FindCliProc(*(IPTR *) args[ARG_PROCESS]);
113 else if (args[ARG_PORT])
115 struct MsgPort *MyPort;
116 if ((MyPort = (struct MsgPort*) FindPort((STRPTR) args[ARG_PORT])) != NULL)
118 pr = (struct Process*) MyPort->mp_SigTask;
121 if (pr != NULL)
123 ULONG
124 mask = 0;
126 /* Figure out the mask of flags to send. */
127 if (args[ARG_ALL])
129 mask = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D
130 | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F;
132 else
134 mask = (args[ARG_C] != NULL ? SIGBREAKF_CTRL_C : 0)
135 | (args[ARG_D] != NULL ? SIGBREAKF_CTRL_D : 0)
136 | (args[ARG_E] != NULL ? SIGBREAKF_CTRL_E : 0)
137 | (args[ARG_F]!= NULL ? SIGBREAKF_CTRL_F : 0);
139 if (NULL == mask)
141 mask = SIGBREAKF_CTRL_C; /* default */
145 Signal((struct Task *) pr, mask);
146 Permit();
148 else
150 /* There is no relevant error code, OBJECT_NOT_FOUND
151 * is a filesystem error, so we can't use that... */
152 Permit();
153 pr = (struct Process *) FindTask(NULL);
155 BPTR errStream = (pr->pr_CES != NULL)
156 ? pr->pr_CES
157 : Output();
159 if (args[ARG_PROCESS])
161 VFPrintf(errStream, "Break: Process %ld does not exist.\n", (APTR) args[ARG_PROCESS]);
163 else if (args[ARG_PORT])
165 FPrintf(errStream, "Break: Port \"%s\" does not exist.\n", (LONG) args[ARG_PORT]);
167 else
169 FPuts(errStream, "Break: Either PROCESS or PORT is required.\n");
171 error = -1;
174 FreeArgs(rd);
175 } /* ReadArgs() ok */
176 else
178 error = IoErr();
181 FreeDosObject(DOS_RDARGS, rda);
182 } /* Got rda */
183 else
185 error = IoErr();
188 if (error != 0 && error != -1)
190 PrintFault(error, "Break");
191 return RETURN_FAIL;
194 SetIoErr(0);
196 return 0;