2 Copyright (C) 1995-2011, The AROS Development Team. All rights reserved.
13 #include <aros/debug.h>
15 // TODO: remove these comments when fixed and validated
16 // TODO: C++ style comments should be avoided
17 // FIXME: why use a $ in a filename ? just to try the resistance of bad FS
18 // TODO: use pipes instead of plain file ?
20 #define SHELL_EMBED "T:Shell$embed"
22 /* BackTicks handling... like V45, we allow several embedded
23 * commands, while V40 only allows one per line.
25 LONG
convertBackTicks(ShellState
*ss
, Buffer
*in
, Buffer
*out
, BOOL
*quoted
)
27 Buffer embedIn
= {0}, embedOut
= {0}; /* TODO pre-alloc */
28 LONG c
= 0, error
= 0, n
= in
->len
, p
= 0;
29 TEXT buf
[512] = SHELL_EMBED
;
32 ess
.ss_DOSBase
= DOSBase
;
33 ess
.ss_SysBase
= SysBase
;
35 for (++in
->cur
; in
->cur
< n
; p
= c
)
42 bufferCopy(in
, &embedIn
, 1, SysBase
);
47 bufferCopy(in
, &embedIn
, 1, SysBase
);
52 bufferCopy(&embedIn
, out
, embedIn
.len
, SysBase
);
56 ++in
->cur
; /* last backtick */
58 if (embedIn
.len
<= 0) /* `` empty command, no output */
61 initDefaultInterpreterState(&ess
);
63 /* The Amiga shell has severe problems when using
64 * redirections in embedded commands so here, the
65 * semantics differ somewhat. Unix shells seems to be
66 * a little bit sloppy with this, too.
67 * If you really wanted to, you could track down
68 * uses of > and >> and make them work inside ` `, too,
69 * but this seems to be rather much work for little gain.
71 if ((error
= Redirection_init(&ess
)))
74 /* Construct temporary output filename */
75 l2a(ss
->cliNumber
, buf
+ sizeof(SHELL_EMBED
) - 1);
77 if (!(ess
.newOut
= Open(buf
, MODE_NEWFILE
)))
83 ess
.oldOut
= SelectOutput(ess
.newOut
);
85 /* Embedded command isn't echo'ed, but its result will be integrated
86 in final command line, which will be echo'ed if the var is set. */
87 D(bug("[Shell] embedded command: %s\n", embedIn
.buf
));
88 if ((error
= checkLine(&ess
, &embedIn
, &embedOut
, FALSE
)) == 0)
90 LONG i
, len
= -1, size
;
92 /* copy result to output */
93 if ((size
= Seek(ess
.newOut
, 0, OFFSET_BEGINNING
)) >= 0)
95 while ((len
= Read(ess
.newOut
, buf
, 512)) > 0)
97 for (i
= 0; i
< len
- 1; ++i
) /* replace all \n but last */
103 if (size
<= 0 && buf
[i
] == '\n')
106 bufferAppend(buf
, len
, out
, SysBase
);
115 Redirection_release(&ess
);
116 /* TODO: delete generated file */
118 bufferFree(&embedIn
, SysBase
);
119 bufferFree(&embedOut
, SysBase
);
121 D(bug("[Shell] embedded command done, error = %d\n", error
));