1 /* source: xio-exec.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 exec type */
7 #include "xiosysincludes.h"
11 #include "xio-progcall.h"
16 static int xioopen_exec(int argc
, const char *argv
[], struct opt
*opts
, int xioflags
, xiofile_t
*xfd
, const struct addrdesc
*addrdesc
);
18 const struct addrdesc xioaddr_exec
= { "EXEC", 3, xioopen_exec
, GROUP_FD
|GROUP_FORK
|GROUP_EXEC
|GROUP_SOCKET
|GROUP_SOCK_UNIX
|GROUP_TERMIOS
|GROUP_FIFO
|GROUP_PTY
|GROUP_PARENT
, 0, 0, 0 HELP(":<command-line>") };
20 const struct optdesc opt_dash
= { "dash", "login", OPT_DASH
, GROUP_EXEC
, PH_PREEXEC
, TYPE_BOOL
, OFUNC_SPEC
};
22 static int xioopen_exec(
26 int xioflags
, /* XIO_RDONLY, XIO_MAYCHILD etc. */
28 const struct addrdesc
*addrdesc
)
30 struct single
*sfd
= &xfd
->stream
;
37 xio_syntax(argv
[0], 1, argc
-1, addrdesc
->syntax
);
41 retropt_bool(opts
, OPT_DASH
, &dash
);
44 _xioopen_foxec(xioflags
, sfd
, addrdesc
->groups
, &opts
, &duptostderr
);
47 if (status
== 0) { /* child */
48 const char *ends
[] = { " ", NULL
};
49 const char *hquotes
[] = { "'", NULL
};
50 const char *squotes
[] = { "\"", NULL
};
51 const char *nests
[] = {
67 /*! Close(something) */
68 /* parse command line */
69 Debug1("child: args = \"%s\"", argv
[1]);
70 pargv
= Malloc(8*sizeof(char *));
71 if (pargv
== NULL
) return STAT_RETRYLATER
;
72 len
= strlen(argv
[1])+1;
74 token
= Malloc(len
); /*! */
76 if (nestlex(&strp
, &tokp
, &len
, ends
, hquotes
, squotes
, nests
,
77 true, true, false) < 0) {
78 Error("internal: miscalculated string lengths");
81 pargv
[0] = strrchr(tokp
-1, '/');
82 if (pargv
[0] == NULL
) pargv
[0] = token
; else ++pargv
[0];
84 while (*strp
== ' ') {
85 while (*++strp
== ' ') ;
86 if ((pargc
& 0x07) == 0) {
87 pargv
= Realloc(pargv
, (pargc
+8)*sizeof(char *));
88 if (pargv
== NULL
) return STAT_RETRYLATER
;
90 pargv
[pargc
++] = tokp
;
91 if (nestlex(&strp
, &tokp
, &len
, ends
, hquotes
, squotes
, nests
,
92 true, true, false) < 0) {
93 Error("internal: miscalculated string lengths");
99 if ((tmp
= Malloc(strlen(pargv
[0])+2)) == NULL
) {
100 return STAT_RETRYLATER
;
104 strcpy(tmp
+1, pargv
[0]);
106 strcpy(tmp
, pargv
[0]);
110 if (setopt_path(opts
, &path
) < 0) {
111 /* this could be dangerous, so let us abort this child... */
115 dropopts(opts
, PH_PASTEXEC
);
116 if ((numleft
= leftopts(opts
)) > 0) {
118 Error1("INTERNAL: %d option(s) remained unused", numleft
);
122 /* only now redirect stderr */
123 if (duptostderr
>= 0) {
125 Dup2(duptostderr
, 2);
127 Notice1("execvp'ing \"%s\"", token
);
128 Execvp(token
, pargv
);
129 /* here we come only if execvp() failed */
132 Error3("execvp(\"%s\", \"%s\"): %s",
133 token
, pargv
[0], strerror(errno
)); break;
135 Error4("execvp(\"%s\", \"%s\", \"%s\"): %s",
136 token
, pargv
[0], pargv
[1], strerror(errno
)); break;
139 Error5("execvp(\"%s\", \"%s\", \"%s\", \"%s\", ...): %s", token
,
140 pargv
[0], pargv
[1], pargv
[2], strerror(errno
));
143 Exit(1); /* this child process */
147 _xio_openlate(sfd
, opts
);
150 #endif /* WITH_EXEC */