nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* source: xio-gopen.c */ |
2 | /* Copyright Gerhard Rieger 2001-2012 */ |
||
3 | /* Published under the GNU General Public License V.2, see file COPYING */ |
||
4 | |||
5 | /* this file contains the source for opening addresses of generic open type */ |
||
6 | |||
7 | #include "xiosysincludes.h" |
||
8 | #include "xioopen.h" |
||
9 | |||
10 | #include "xio-named.h" |
||
11 | #include "xio-unix.h" |
||
12 | #include "xio-gopen.h" |
||
13 | |||
14 | |||
15 | #if WITH_GOPEN |
||
16 | |||
17 | static int xioopen_gopen1(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3); |
||
18 | |||
19 | |||
20 | const struct xioaddr_endpoint_desc xioaddr_gopen1 = { XIOADDR_SYS, "gopen", 1, XIOBIT_ALL, GROUP_FD|GROUP_FIFO|GROUP_BLK|GROUP_REG|GROUP_NAMED|GROUP_OPEN|GROUP_FILE|GROUP_TERMIOS|GROUP_SOCKET|GROUP_SOCK_UNIX, XIOSHUT_UNSPEC, XIOCLOSE_UNSPEC, xioopen_gopen1, 0, 0, 0 HELP(":<filename>") }; |
||
21 | |||
22 | const union xioaddr_desc *xioaddrs_gopen[] = { |
||
23 | (union xioaddr_desc *)&xioaddr_gopen1, |
||
24 | NULL |
||
25 | }; |
||
26 | |||
27 | static int xioopen_gopen1(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3) { |
||
28 | const char *filename = argv[1]; |
||
29 | int fd; |
||
30 | int rw = (xioflags & XIO_ACCMODE); |
||
31 | flags_t openflags = (xioflags & XIO_ACCMODE); |
||
32 | mode_t st_mode; |
||
33 | bool exists; |
||
34 | bool opt_unlink_close = false; |
||
35 | int result; |
||
36 | |||
37 | if ((result = |
||
38 | _xioopen_named_early(argc, argv, xfd, GROUP_NAMED|groups, &exists, opts)) < 0) { |
||
39 | return result; |
||
40 | } |
||
41 | st_mode = result; |
||
42 | |||
43 | if (exists) { |
||
44 | /* file (or at least named entry) exists */ |
||
45 | if ((xioflags&XIO_ACCMODE) != XIO_RDONLY) { |
||
46 | openflags |= O_APPEND; |
||
47 | } |
||
48 | } else { |
||
49 | openflags |= O_CREAT; |
||
50 | } |
||
51 | |||
52 | /* note: when S_ISSOCK was undefined, it always gives 0 */ |
||
53 | if (exists && S_ISSOCK(st_mode)) { |
||
54 | #if WITH_UNIX |
||
55 | union sockaddr_union us; |
||
56 | socklen_t uslen = sizeof(us); |
||
57 | char infobuff[256]; |
||
58 | |||
59 | Info1("\"%s\" is a socket, connecting to it", filename); |
||
60 | |||
61 | xfd->stream.howtoshut = XIOSHUT_DOWN; |
||
62 | xfd->stream.howtoclose = XIOCLOSE_CLOSE; |
||
63 | result = |
||
64 | _xioopen_unix_client(&xfd->stream, xioflags, groups, 0, opts, filename); |
||
65 | if (result < 0) { |
||
66 | return result; |
||
67 | } |
||
68 | if (xfd->stream.rfd >= 0) { |
||
69 | fd = xfd->stream.rfd; |
||
70 | } else { |
||
71 | fd = xfd->stream.wfd; |
||
72 | } |
||
73 | |||
74 | applyopts_named(filename, opts, PH_PASTOPEN); /* unlink-late */ |
||
75 | |||
76 | if (Getsockname(fd, (struct sockaddr *)&us, &uslen) < 0) { |
||
77 | Warn4("getsockname(%d, %p, {%d}): %s", |
||
78 | fd, &us, uslen, strerror(errno)); |
||
79 | } else { |
||
80 | Notice1("successfully connected via %s", |
||
81 | sockaddr_unix_info(&us.un, uslen, |
||
82 | infobuff, sizeof(infobuff))); |
||
83 | } |
||
84 | #else |
||
85 | Error("\"%s\" is a socket, but UNIX socket support is not compiled in"); |
||
86 | return -1; |
||
87 | #endif /* WITH_UNIX */ |
||
88 | |||
89 | } else { |
||
90 | /* a file name */ |
||
91 | |||
92 | Info1("\"%s\" is not a socket, open()'ing it", filename); |
||
93 | |||
94 | retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); |
||
95 | if (opt_unlink_close) { |
||
96 | if ((xfd->stream.unlink_close = strdup(filename)) == NULL) { |
||
97 | Error1("strdup(\"%s\"): out of memory", filename); |
||
98 | } |
||
99 | xfd->stream.opt_unlink_close = true; |
||
100 | } |
||
101 | if (xfd->stream.howtoshut == XIOSHUT_UNSPEC) |
||
102 | xfd->stream.howtoshut = XIOSHUT_NONE; |
||
103 | if (xfd->stream.howtoclose == XIOCLOSE_UNSPEC) |
||
104 | xfd->stream.howtoclose = XIOCLOSE_CLOSE; |
||
105 | |||
106 | Notice3("opening %s \"%s\" for %s", |
||
107 | filetypenames[(st_mode&S_IFMT)>>12], filename, ddirection[(xioflags&XIO_ACCMODE)]); |
||
108 | if ((fd = _xioopen_open(filename, openflags, opts)) < 0) |
||
109 | return fd; |
||
110 | #ifdef I_PUSH |
||
111 | if (S_ISCHR(st_mode)) { |
||
112 | Ioctl(result, I_PUSH, "ptem"); |
||
113 | Ioctl(result, I_PUSH, "ldterm"); |
||
114 | Ioctl(result, I_PUSH, "ttcompat"); |
||
115 | } |
||
116 | #endif |
||
117 | |||
118 | #if WITH_TERMIOS |
||
119 | if (Isatty(fd)) { |
||
120 | if (Tcgetattr(fd, &xfd->stream.savetty) < 0) { |
||
121 | Warn2("cannot query current terminal settings on fd %d: %s", |
||
122 | fd, strerror(errno)); |
||
123 | } else { |
||
124 | xfd->stream.ttyvalid = true; |
||
125 | } |
||
126 | } |
||
127 | #endif /* WITH_TERMIOS */ |
||
128 | applyopts_named(filename, opts, PH_FD); |
||
129 | applyopts(fd, opts, PH_FD); |
||
130 | applyopts_cloexec(fd, opts); |
||
131 | if (XIOWITHRD(rw)) xfd->stream.rfd = fd; |
||
132 | if (XIOWITHWR(rw)) xfd->stream.wfd = fd; |
||
133 | } |
||
134 | |||
135 | if ((result = applyopts2(fd, opts, PH_PASTSOCKET, PH_CONNECTED)) < 0) |
||
136 | return result; |
||
137 | |||
138 | if ((result = _xio_openlate(&xfd->stream, opts)) < 0) |
||
139 | return result; |
||
140 | |||
141 | return 0; |
||
142 | } |
||
143 | |||
144 | #endif /* WITH_GOPEN */ |