nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* source: xio-system.c */ |
2 | /* Copyright Gerhard Rieger */ |
||
3 | /* Published under the GNU General Public License V.2, see file COPYING */ |
||
4 | |||
5 | /* this file contains the source for opening addresses of system type */ |
||
6 | |||
7 | #include "xiosysincludes.h" |
||
8 | #include "xioopen.h" |
||
9 | |||
10 | #include "xio-progcall.h" |
||
11 | #include "xio-system.h" |
||
12 | |||
13 | |||
14 | #if WITH_SYSTEM |
||
15 | |||
16 | static int xioopen_system(int arg, const char *argv[], struct opt *opts, |
||
17 | int xioflags, /* XIO_RDONLY etc. */ |
||
18 | xiofile_t *fd, |
||
19 | unsigned groups, |
||
20 | int inter, int form, int dummy3 |
||
21 | ); |
||
22 | |||
23 | /* the endpoint variant: get stdin and/or stdout on "left" side. socat does not |
||
24 | provide a "right" side for script */ |
||
25 | static const struct xioaddr_endpoint_desc xioendpoint_system1 = { XIOADDR_SYS, "system", 1, XIOBIT_ALL, GROUP_FD|GROUP_FORK|GROUP_EXEC|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_TERMIOS|GROUP_FIFO|GROUP_PTY|GROUP_PARENT, XIOSHUT_UNSPEC, XIOCLOSE_UNSPEC, xioopen_system, false, 0, 0 HELP(":<shell-command>") }; |
||
26 | /* the inter address variant: the bidirectional form has stdin and stdout on |
||
27 | its "left" side, and FDs 3 (for reading) and FD 4 (for writing) on its right |
||
28 | side. */ |
||
29 | static const struct xioaddr_inter_desc xiointer_system1_2rw = { XIOADDR_INTER, "system", 1, XIOBIT_RDWR, GROUP_FD|GROUP_FORK|GROUP_EXEC|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_TERMIOS|GROUP_FIFO|GROUP_PTY|GROUP_PARENT, XIOSHUT_UNSPEC, XIOCLOSE_UNSPEC, xioopen_system, true, 2, 0, XIOBIT_RDWR HELP(":<shell-command>") }; |
||
30 | static const struct xioaddr_inter_desc xiointer_system1_2ro = { XIOADDR_INTER, "system", 1, XIOBIT_RDONLY, GROUP_FD|GROUP_FORK|GROUP_EXEC|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_TERMIOS|GROUP_FIFO|GROUP_PTY|GROUP_PARENT, XIOSHUT_UNSPEC, XIOCLOSE_UNSPEC, xioopen_system, true, 2, 0, XIOBIT_WRONLY HELP(":<shell-command>") }; |
||
31 | static const struct xioaddr_inter_desc xiointer_system1_2wo = { XIOADDR_INTER, "system", 1, XIOBIT_WRONLY, GROUP_FD|GROUP_FORK|GROUP_EXEC|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_TERMIOS|GROUP_FIFO|GROUP_PTY|GROUP_PARENT, XIOSHUT_UNSPEC, XIOCLOSE_UNSPEC, xioopen_system, true, 2, 0, XIOBIT_RDONLY HELP(":<shell-command>") }; |
||
32 | /* the unidirectional inter address variant: the "left" side reads from stdin, |
||
33 | and the right side reads from stdout. */ |
||
34 | static const struct xioaddr_inter_desc xiointer_system1_1wo = { XIOADDR_INTER, "system1", 1, XIOBIT_WRONLY, GROUP_FD|GROUP_FORK|GROUP_EXEC|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_TERMIOS|GROUP_FIFO|GROUP_PTY|GROUP_PARENT, XIOSHUT_UNSPEC, XIOCLOSE_UNSPEC, xioopen_system, true, 1, 0, XIOBIT_RDONLY HELP(":<shell-command>") }; |
||
35 | |||
36 | /* the general forms, designed for bidirectional transfer (stdio -- 3,4) */ |
||
37 | const union xioaddr_desc *xioaddrs_system[] = { |
||
38 | (union xioaddr_desc *)&xioendpoint_system1, |
||
39 | (union xioaddr_desc *)&xiointer_system1_2rw, |
||
40 | (union xioaddr_desc *)&xiointer_system1_2ro, |
||
41 | (union xioaddr_desc *)&xiointer_system1_2wo, |
||
42 | NULL |
||
43 | }; |
||
44 | |||
45 | /* unidirectional inter address (stdin -- stdout) */ |
||
46 | const union xioaddr_desc *xioaddrs_system1[] = { |
||
47 | (union xioaddr_desc *)&xiointer_system1_1wo, |
||
48 | NULL }; |
||
49 | |||
50 | static int xioopen_system(int argc, const char *argv[], struct opt *opts, |
||
51 | int xioflags, /* XIO_RDONLY etc. */ |
||
52 | xiofile_t *fd, |
||
53 | unsigned groups, |
||
54 | int inter, int form, int dummy3 |
||
55 | ) { |
||
56 | int status; |
||
57 | char *path = NULL; |
||
58 | int duptostderr; |
||
59 | int result; |
||
60 | const char *string = argv[1]; |
||
61 | |||
62 | status = _xioopen_progcall(xioflags, &fd->stream, groups, &opts, &duptostderr, inter, form); |
||
63 | if (status < 0) return status; |
||
64 | if (status == 0) { /* child */ |
||
65 | int numleft; |
||
66 | |||
67 | /* do not shutdown connections that belong our parent */ |
||
68 | sock[0] = NULL; |
||
69 | sock[1] = NULL; |
||
70 | |||
71 | if (setopt_path(opts, &path) < 0) { |
||
72 | /* this could be dangerous, so let us abort this child... */ |
||
73 | Exit(1); |
||
74 | } |
||
75 | |||
76 | if ((numleft = leftopts(opts)) > 0) { |
||
77 | Error1("%d option(s) could not be used", numleft); |
||
78 | showleft(opts); |
||
79 | return STAT_NORETRY; |
||
80 | } |
||
81 | |||
82 | /* only now redirect stderr */ |
||
83 | if (duptostderr >= 0) { |
||
84 | diag_dup(); |
||
85 | Dup2(duptostderr, 2); |
||
86 | } |
||
87 | Info1("executing shell command \"%s\"", string); |
||
88 | result = System(string); |
||
89 | if (result != 0) { |
||
90 | Warn2("system(\"%s\") returned with status %d", string, result); |
||
91 | Warn1("system(): %s", strerror(errno)); |
||
92 | } |
||
93 | Exit(0); /* this child process */ |
||
94 | } |
||
95 | |||
96 | /* parent */ |
||
97 | return 0; |
||
98 | } |
||
99 | |||
100 | #endif /* WITH_SYSTEM */ |