Fixed out-by-one error in previous commit.
[AROS.git] / workbench / c / shellcommands / Run.c
blob7a82c18967ee2df790e196d9bd7ab85af5e54adc
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 /******************************************************************************
11 NAME
13 Run
15 SYNOPSIS
17 QUIET/S,COMMAND/F
19 LOCATION
23 FUNCTION
25 Run a program, that is start a program as a background process.
26 That means it doesn't take over the parent shell.
28 INPUTS
30 QUIET -- avoids printing of the background CLI's number
32 COMMAND -- the program to run together with its arguments
34 RESULT
36 NOTES
38 To make it possible to close the current shell, redirect the output
39 using
41 Run >NIL: program arguments
43 EXAMPLE
45 BUGS
47 SEE ALSO
49 INTERNALS
51 HISTORY
53 ******************************************************************************/
55 #include <exec/memory.h>
56 #include <proto/exec.h>
57 #include <dos/dosextens.h>
58 #include <dos/dostags.h>
59 #include <dos/cliinit.h>
60 #include <dos/stdio.h>
61 #include <proto/dos.h>
62 #include <utility/tagitem.h>
63 #include <proto/alib.h>
65 #define DEBUG 0
66 #include <aros/debug.h>
68 #include <aros/shcommands.h>
70 AROS_SH2H(Run, 41.3, "Start a program as a background process\n",
71 AROS_SHAH(BOOL , ,QUIET ,/S,FALSE,"\tDon't print the background CLI's number"),
72 AROS_SHAH(STRPTR, ,COMMAND,/F,NULL , "The program (resp. script) to run (arguments allowed)\n") )
74 AROS_SHCOMMAND_INIT
76 struct CommandLineInterface *cli = Cli();
77 struct Process *me = (struct Process *)FindTask(NULL);
78 BPTR cis = BNULL, cos = BNULL, ces = BNULL;
79 struct FileHandle *fh;
80 LONG argsize;
81 CONST_STRPTR argbuff;
82 STRPTR command = (STRPTR)SHArg(COMMAND);
83 LONG cmdsize = 0;
85 if (!command)
86 command = "";
88 cis = Open("NIL:", MODE_OLDFILE);
90 /* To support '+' style continuation, we're
91 * going to need to be a little tricky. We
92 * want to append *only* the buffered input
93 * left in Input() after the implicit ReadArgs
94 * to our command.
96 * First, let's see how much we have.
98 fh = BADDR(Input());
99 argsize = (fh->fh_End > 0 && fh->fh_Pos > 0) ? (fh->fh_End - fh->fh_Pos) : 0;
101 /* Good, there's some buffered input for us.
102 * Append it to the command.
104 if (argsize > 0) {
105 STRPTR tmp;
106 cmdsize = strlen(command);
108 argbuff = BADDR(fh->fh_Buf) + fh->fh_Pos;
110 tmp = AllocMem(cmdsize+1+argsize+1, MEMF_ANY);
111 if (tmp) {
112 command = tmp;
113 CopyMem(SHArg(COMMAND), command, cmdsize);
114 command[cmdsize++]='\n';
115 CopyMem(argbuff, &command[cmdsize], argsize);
116 cmdsize += argsize;
117 command[cmdsize++] = 0;
118 } else {
119 cmdsize = 0;
123 cos = OpenFromLock(DupLockFromFH(Output()));
125 /* All the 'noise' goes to cli_StandardError
127 if (!SHArg(QUIET)) {
128 if (cli)
130 ces = cli->cli_StandardError;
131 } else {
132 ces = me->pr_CES;
136 /* Use a duplicate of the CES lock
138 if (ces)
139 ces = OpenFromLock(DupLockFromFH(ces));
140 else
141 ces = Open("NIL:", MODE_OLDFILE);
143 if ( command[0] != 0)
145 struct TagItem tags[] =
147 { SYS_ScriptInput, (IPTR)cis },
148 { SYS_Input, (IPTR)cis },
149 { SYS_Output, (IPTR)cos },
150 { SYS_Error, (IPTR)ces },
151 { SYS_CliType, (IPTR)CLI_RUN },
152 { TAG_DONE, 0 }
155 if ( SystemTagList((CONST_STRPTR)command,
156 tags ) == -1 )
158 PrintFault(IoErr(), "Run");
159 Close(cis);
160 Close(cos);
161 Close(ces);
162 if (cmdsize > 0)
163 FreeMem(command, cmdsize);
165 return RETURN_FAIL;
169 if (cmdsize > 0)
170 FreeMem(command, cmdsize);
172 return RETURN_OK;
174 AROS_SHCOMMAND_EXIT