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
,
17 int xioflags
, /* XIO_RDONLY etc. */
20 int dummy1
, int dummy2
, int dummy3
23 const struct addrdesc addr_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>") };
25 const struct optdesc opt_dash
= { "dash", "login", OPT_DASH
, GROUP_EXEC
, PH_PREEXEC
, TYPE_BOOL
, OFUNC_SPEC
};
27 static int xioopen_exec(int argc
, const char *argv
[], struct opt
*opts
,
28 int xioflags
, /* XIO_RDONLY, XIO_MAYCHILD etc. */
31 int dummy1
, int dummy2
, int dummy3
38 Error3("\"%s:%s\": wrong number of parameters (%d instead of 1)", argv
[0], argv
[1], argc
-1);
41 retropt_bool(opts
, OPT_DASH
, &dash
);
43 status
= _xioopen_foxec(xioflags
, &fd
->stream
, groups
, &opts
, &duptostderr
);
44 if (status
< 0) return status
;
45 if (status
== 0) { /* child */
46 const char *ends
[] = { " ", NULL
};
47 const char *hquotes
[] = { "'", NULL
};
48 const char *squotes
[] = { "\"", NULL
};
49 const char *nests
[] = {
66 /*! Close(something) */
67 /* parse command line */
68 Debug1("child: args = \"%s\"", argv
[1]);
69 pargv
= Malloc(8*sizeof(char *));
70 if (pargv
== NULL
) return STAT_RETRYLATER
;
71 len
= strlen(argv
[1])+1;
73 token
= Malloc(len
); /*! */
75 if (nestlex(&strp
, &tokp
, &len
, ends
, hquotes
, squotes
, nests
,
76 true, true, false) < 0) {
77 Error("internal: miscalculated string lengths");
80 pargv
[0] = strrchr(tokp
-1, '/');
81 if (pargv
[0] == NULL
) pargv
[0] = token
; else ++pargv
[0];
83 while (*strp
== ' ') {
84 while (*++strp
== ' ') ;
85 if ((pargc
& 0x07) == 0) {
86 pargv
= Realloc(pargv
, (pargc
+8)*sizeof(char *));
87 if (pargv
== NULL
) return STAT_RETRYLATER
;
89 pargv
[pargc
++] = tokp
;
90 if (nestlex(&strp
, &tokp
, &len
, ends
, hquotes
, squotes
, nests
,
91 true, true, false) < 0) {
92 Error("internal: miscalculated string lengths");
98 if ((tmp
= Malloc(strlen(pargv
[0])+2)) == NULL
) {
99 return STAT_RETRYLATER
;
103 strcpy(tmp
+1, pargv
[0]);
105 strcpy(tmp
, pargv
[0]);
109 if (setopt_path(opts
, &path
) < 0) {
110 /* this could be dangerous, so let us abort this child... */
114 if ((numleft
= leftopts(opts
)) > 0) {
115 Error1("%d option(s) could not be used", numleft
);
120 /* only now redirect stderr */
121 if (duptostderr
>= 0) {
123 Dup2(duptostderr
, 2);
125 Notice1("execvp'ing \"%s\"", token
);
126 Execvp(token
, pargv
);
127 /* here we come only if execvp() failed */
129 case 1: Error3("execvp(\"%s\", \"%s\"): %s", token
, pargv
[0], strerror(errno
)); break;
130 case 2: Error4("execvp(\"%s\", \"%s\", \"%s\"): %s", token
, pargv
[0], pargv
[1], strerror(errno
)); break;
133 Error5("execvp(\"%s\", \"%s\", \"%s\", \"%s\", ...): %s", token
, pargv
[0], pargv
[1], pargv
[2], strerror(errno
)); break;
135 Exit(1); /* this child process */
141 #endif /* WITH_EXEC */