/* source: xio-shell.c */ /* Copyright Gerhard Rieger and contributors (see file CHANGES) */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for opening addresses of shell type */ #include "xiosysincludes.h" #include "xioopen.h" #include "xio-progcall.h" #include "xio-shell.h" #if WITH_SHELL static int xioopen_shell(int arg, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); 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(":") }; const struct optdesc opt_shell = { "shell", NULL, OPT_SHELL, GROUP_SHELL, PH_PREEXEC, TYPE_STRING, OFUNC_SPEC, 0, 0 }; static int xioopen_shell( int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc) { struct single *sfd = &xfd->stream; int status; char *path = NULL; int duptostderr; int result; char *shellpath = NULL; const char *shellname; const char *string = argv[1]; if (argc != 2) { xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; } shellpath = getenv("SHELL"); retropt_string(opts, OPT_SHELL, &shellpath); if (shellpath == NULL) { Error("SHELL variable undefined"); errno = EINVAL; return -1; } shellname = strrchr(shellpath, '/'); if (shellname == NULL) { Error1("SHELL \"%s\" variable does not specify a path (has no '/')", shellpath); errno = EINVAL; return -1; } ++shellname; status = _xioopen_foxec(xioflags, sfd, addrdesc->groups, &opts, &duptostderr); if (status < 0) return status; if (status == 0) { /* child */ int numleft; if (setopt_path(opts, &path) < 0) { /* this could be dangerous, so let us abort this child... */ Exit(1); } if ((numleft = leftopts(opts)) > 0) { Error1("%d option(s) could not be used", numleft); showleft(opts); return STAT_NORETRY; } /* only now redirect stderr */ if (duptostderr >= 0) { diag_dup(); Dup2(duptostderr, 2); } Setenv("SHELL", shellpath, 1); Info1("executing shell command \"%s\"", string); Debug3("execl(\"%s\", \"%s\", \"-c\", \"%s\", NULL", shellpath, shellname, string); result = execl(shellpath, shellname, "-c", string, (char *)NULL); if (result != 0) { Warn2("execl(\"%s\") returned with status %d", string, result); Warn1("execl(): %s", strerror(errno)); } Exit(0); /* this child process */ } /* parent */ return 0; } #endif /* WITH_SHELL */