1 /* source: xio-shell.c */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
3 /* Published under the GNU General Public License V.2, see file COPYING */
5 /* this file contains the source for opening addresses of shell type */
7 #include "xiosysincludes.h"
10 #include "xio-progcall.h"
11 #include "xio-shell.h"
16 static int xioopen_shell(int arg
, const char *argv
[], struct opt
*opts
, int xioflags
, xiofile_t
*xfd
, const struct addrdesc
*addrdesc
);
18 const struct addrdesc xioaddr_shell
= { "SHELL", 3, xioopen_shell
, GROUP_FD
|GROUP_FORK
|GROUP_EXEC
|GROUP_SOCKET
|GROUP_SOCK_UNIX
|GROUP_TERMIOS
|GROUP_FIFO
|GROUP_PTY
|GROUP_PARENT
|GROUP_SHELL
, 1, 0, 0 HELP(":<shell-command>") };
20 const struct optdesc opt_shell
= { "shell", NULL
, OPT_SHELL
, GROUP_SHELL
, PH_PREEXEC
, TYPE_STRING
, OFUNC_SPEC
, 0, 0 };
22 static int xioopen_shell(
28 const struct addrdesc
*addrdesc
)
30 struct single
*sfd
= &xfd
->stream
;
35 char *shellpath
= NULL
;
36 const char *shellname
;
37 const char *string
= argv
[1];
40 xio_syntax(argv
[0], 1, argc
-1, addrdesc
->syntax
);
44 shellpath
= getenv("SHELL");
45 retropt_string(opts
, OPT_SHELL
, &shellpath
);
46 if (shellpath
== NULL
) {
47 Error("SHELL variable undefined");
51 shellname
= strrchr(shellpath
, '/');
52 if (shellname
== NULL
) {
53 Error1("SHELL \"%s\" variable does not specify a path (has no '/')", shellpath
);
59 status
= _xioopen_foxec(xioflags
, sfd
, addrdesc
->groups
, &opts
, &duptostderr
);
60 if (status
< 0) return status
;
61 if (status
== 0) { /* child */
64 if (setopt_path(opts
, &path
) < 0) {
65 /* this could be dangerous, so let us abort this child... */
69 if ((numleft
= leftopts(opts
)) > 0) {
70 Error1("%d option(s) could not be used", numleft
);
75 /* only now redirect stderr */
76 if (duptostderr
>= 0) {
81 Setenv("SHELL", shellpath
, 1);
83 Info1("executing shell command \"%s\"", string
);
84 Debug3("execl(\"%s\", \"%s\", \"-c\", \"%s\", NULL",
85 shellpath
, shellname
, string
);
86 result
= execl(shellpath
, shellname
, "-c", string
, (char *)NULL
);
88 Warn2("execl(\"%s\") returned with status %d", string
, result
);
89 Warn1("execl(): %s", strerror(errno
));
91 Exit(0); /* this child process */
98 #endif /* WITH_SHELL */