nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /* source: xio-stdio.c */
2 /* Copyright Gerhard Rieger 2001-2009 */
3 /* Published under the GNU General Public License V.2, see file COPYING */
4  
5 /* this file contains the source for opening addresses stdio type */
6  
7 #include "xiosysincludes.h"
8 #include "xioopen.h"
9  
10 #include "xio-fdnum.h"
11 #include "xio-stdio.h"
12  
13  
14 #if WITH_STDIO
15  
16 static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3);
17 static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int fd, int dummy2, int dummy3);
18  
19  
20 /* we specify all option groups that we can imagine for a FD, becasue the
21 changed parsing mechanism does not allow us to check the type of FD before
22 applying the options */
23 static const struct xioaddr_endpoint_desc xioaddr_stdio0 = { XIOADDR_SYS, "stdio", 0, XIOBIT_ALL, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_FILE|GROUP_SOCKET|GROUP_TERMIOS|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP, XIOSHUT_UNSPEC, XIOCLOSE_NONE, xioopen_stdio, 0, 0, 0 HELP(NULL) };
24 static const struct xioaddr_endpoint_desc xioaddr_stdin0 = { XIOADDR_SYS, "stdin", 0, XIOBIT_RDONLY, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_FILE|GROUP_SOCKET|GROUP_TERMIOS|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP, XIOSHUT_UNSPEC, XIOCLOSE_NONE, xioopen_stdfd, 0, 0, 0 HELP(NULL) };
25 static const struct xioaddr_endpoint_desc xioaddr_stdout0 = { XIOADDR_SYS, "stdout", 0, XIOBIT_WRONLY, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_FILE|GROUP_SOCKET|GROUP_TERMIOS|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP, XIOSHUT_UNSPEC, XIOCLOSE_NONE, xioopen_stdfd, 1, 0, 0 HELP(NULL) };
26 static const struct xioaddr_endpoint_desc xioaddr_stderr0 = { XIOADDR_SYS, "stderr", 0, XIOBIT_WRONLY, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_FILE|GROUP_SOCKET|GROUP_TERMIOS|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP, XIOSHUT_UNSPEC, XIOCLOSE_NONE, xioopen_stdfd, 2, 0, 0 HELP(NULL) };
27  
28 const union xioaddr_desc *xioaddrs_stdio[] = {
29 (union xioaddr_desc *)&xioaddr_stdio0, NULL };
30 const union xioaddr_desc *xioaddrs_stdin[] = {
31 (union xioaddr_desc *)&xioaddr_stdin0, NULL };
32 const union xioaddr_desc *xioaddrs_stdout[] = {
33 (union xioaddr_desc *)&xioaddr_stdout0, NULL };
34 const union xioaddr_desc *xioaddrs_stderr[] = {
35 (union xioaddr_desc *)&xioaddr_stderr0, NULL };
36  
37 /* process a bidirectional "stdio" or "-" argument with options. */
38 int xioopen_stdio_bi(xiofile_t *sock) {
39 struct opt *opts1, *opts2, *optspr;
40 unsigned int groups1 = xioaddr_stdio0.groups, groups2 = xioaddr_stdio0.groups;
41 int result;
42  
43 sock->stream.rfd = 0 /*stdin*/;
44 sock->stream.wfd = 1 /*stdout*/;
45  
46 #if WITH_TERMIOS
47 if (Isatty(sock->stream.rfd)) {
48 if (Tcgetattr(sock->stream.rfd,
49 &sock->stream.savetty)
50 < 0) {
51 Warn2("cannot query current terminal settings on fd %d: %s",
52 sock->stream.rfd, strerror(errno));
53 } else {
54 sock->stream.ttyvalid = true;
55 }
56 }
57 if (Isatty(sock->stream.wfd) && (sock->stream.wfd != sock->stream.rfd)) {
58 if (Tcgetattr(sock->stream.wfd,
59 &sock->stream.savetty)
60 < 0) {
61 Warn2("cannot query current terminal settings on fd %d: %s",
62 sock->stream.wfd, strerror(errno));
63 } else {
64 sock->stream.ttyvalid = true;
65 }
66 }
67 #endif /* WITH_TERMIOS */
68 if (applyopts_single(&sock->stream, sock->stream.opts, PH_INIT) < 0)
69 return -1;
70 applyopts(-1, sock->stream.opts, PH_INIT);
71 if (sock->stream.howtoshut == XIOSHUT_UNSPEC)
72 sock->stream.howtoshut = XIOSHUT_NONE;
73  
74 /* options here are one-time and one-direction, no second use */
75 retropt_bool(sock->stream.opts, OPT_IGNOREEOF, &sock->stream.ignoreeof);
76  
77 /* extract opts that should be applied only once */
78 if ((optspr = copyopts(sock->stream.opts, GROUP_PROCESS)) == NULL) {
79 return -1;
80 }
81 if ((result = applyopts(-1, optspr, PH_EARLY)) < 0)
82 return result;
83 if ((result = applyopts(-1, optspr, PH_PREOPEN)) < 0)
84 return result;
85  
86 /* here we copy opts, because most have to be applied twice! */
87 if ((opts1 = copyopts(sock->stream.opts, GROUP_FD|GROUP_APPL|(groups1&~GROUP_PROCESS))) == NULL) {
88 return -1;
89 }
90  
91 /* apply options to first FD */
92 if ((result = applyopts(sock->stream.rfd, opts1, PH_ALL)) < 0) {
93 return result;
94 }
95 if ((result = _xio_openlate(&sock->stream, opts1)) < 0) {
96 return result;
97 }
98  
99 if ((opts2 = copyopts(sock->stream.opts, GROUP_FD|GROUP_APPL|(groups2&~GROUP_PROCESS))) == NULL) {
100 return -1;
101 }
102 /* apply options to second FD */
103 if ((result = applyopts(sock->stream.wfd, opts2, PH_ALL)) < 0) {
104 return result;
105 }
106 if ((result = _xio_openlate(&sock->stream, opts2)) < 0) {
107 return result;
108 }
109  
110 if ((result = _xio_openlate(&sock->stream, optspr)) < 0) {
111 return result;
112 }
113  
114 Notice("reading from and writing to stdio");
115 return 0;
116 }
117  
118  
119 /* wrap around unidirectional xioopensingle and xioopen_fd to automatically determine stdin or stdout fd depending on rw.
120 Do not set FD_CLOEXEC flag. */
121 static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3) {
122 int rw = (xioflags&XIO_ACCMODE);
123  
124 if (argc != 1) {
125 Error2("%s: wrong number of parameters (%d instead of 0)", argv[0], argc-1);
126 }
127  
128 if (rw == XIO_RDWR) {
129 return xioopen_stdio_bi(xfd);
130 }
131  
132 Notice2("using %s for %s",
133 &("stdin\0\0\0stdout"[rw<<3]),
134 ddirection[rw]);
135 return xioopen_fd(opts, rw, xfd,
136 XIOWITHRD(rw)?0:-1,
137 XIOWITHWR(rw)?1:-1,
138 dummy2, dummy3);
139 }
140  
141 /* wrap around unidirectional xioopensingle and xioopen_fd to automatically determine stdin or stdout fd depending on rw.
142 Do not set FD_CLOEXEC flag. */
143 static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int fd, int dummy2, int dummy3) {
144 int rw = (xioflags&XIO_ACCMODE);
145  
146 if (argc != 1) {
147 Error2("%s: wrong number of parameters (%d instead of 0)", argv[0], argc-1);
148 }
149 Notice2("using %s for %s",
150 &("stdin\0\0\0stdout\0\0stderr"[fd<<3]),
151 ddirection[rw]);
152 return xioopen_fd(opts, rw, xfd,
153 XIOWITHRD(rw)?fd:-1,
154 XIOWITHWR(rw)?fd:-1,
155 dummy2, dummy3);
156 }
157 #endif /* WITH_STDIO */