nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* source: xio-pipe.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 pipe type */ |
||
6 | |||
7 | #include "xiosysincludes.h" |
||
8 | #include "xioopen.h" |
||
9 | |||
10 | #include "xio-named.h" |
||
11 | |||
12 | |||
13 | #if WITH_PIPE |
||
14 | |||
15 | static int xioopen_fifo0(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); |
||
16 | static int xioopen_fifo1(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3); |
||
17 | |||
18 | static const struct xioaddr_endpoint_desc xioaddr_pipe0 = { XIOADDR_SYS, "pipe", 0, XIOBIT_RDWR, GROUP_FD|GROUP_NAMED|GROUP_OPEN|GROUP_FIFO, XIOSHUT_CLOSE, XIOCLOSE_CLOSE, xioopen_fifo0, 0, 0, 0 HELP("") }; |
||
19 | static const struct xioaddr_endpoint_desc xioaddr_pipe1 = { XIOADDR_SYS, "pipe", 1, XIOBIT_ALL, GROUP_FD|GROUP_NAMED|GROUP_OPEN|GROUP_FIFO, XIOSHUT_CLOSE, XIOCLOSE_CLOSE, xioopen_fifo1, 0, 0, 0 HELP(":<filename>") }; |
||
20 | |||
21 | const union xioaddr_desc *xioaddrs_pipe[] = { |
||
22 | (union xioaddr_desc *)&xioaddr_pipe0, |
||
23 | (union xioaddr_desc *)&xioaddr_pipe1, |
||
24 | NULL }; |
||
25 | |||
26 | /* process an unnamed bidirectional "pipe" or "fifo" or "echo" argument with |
||
27 | options */ |
||
28 | static int xioopen_fifo0(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *sock, unsigned groups, int dummy1, int dummy2, int dummy3) { |
||
29 | struct opt *opts2; |
||
30 | int filedes[2]; |
||
31 | int numleft; |
||
32 | int result; |
||
33 | |||
34 | if (applyopts_single(&sock->stream, opts, PH_INIT) < 0) return -1; |
||
35 | applyopts(-1, opts, PH_INIT); |
||
36 | |||
37 | if (Pipe(filedes) != 0) { |
||
38 | Error2("pipe(%p): %s", filedes, strerror(errno)); |
||
39 | return -1; |
||
40 | } |
||
41 | /*0 Info2("pipe({%d,%d})", filedes[0], filedes[1]);*/ |
||
42 | |||
43 | sock->common.tag = XIO_TAG_RDWR; |
||
44 | sock->stream.dtype = XIODATA_2PIPE; |
||
45 | sock->stream.rfd = filedes[0]; |
||
46 | sock->stream.wfd = filedes[1]; |
||
47 | applyopts_cloexec(sock->stream.rfd, opts); |
||
48 | applyopts_cloexec(sock->stream.wfd, opts); |
||
49 | |||
50 | /* one-time and input-direction options, no second application */ |
||
51 | retropt_bool(opts, OPT_IGNOREEOF, &sock->stream.ignoreeof); |
||
52 | |||
53 | /* here we copy opts! */ |
||
54 | if ((opts2 = copyopts(opts, GROUP_FIFO)) == NULL) { |
||
55 | return STAT_NORETRY; |
||
56 | } |
||
57 | |||
58 | /* apply options to first FD */ |
||
59 | if ((result = applyopts(sock->stream.rfd, opts, PH_ALL)) < 0) { |
||
60 | return result; |
||
61 | } |
||
62 | if ((result = applyopts_single(&sock->stream, opts, PH_ALL)) < 0) { |
||
63 | return result; |
||
64 | } |
||
65 | |||
66 | /* apply options to second FD */ |
||
67 | if ((result = applyopts(sock->stream.wfd, opts2, PH_ALL)) < 0) |
||
68 | { |
||
69 | return result; |
||
70 | } |
||
71 | |||
72 | if ((numleft = leftopts(opts)) > 0) { |
||
73 | Error1("%d option(s) could not be used", numleft); |
||
74 | showleft(opts); |
||
75 | } |
||
76 | Notice("writing to and reading from unnamed pipe"); |
||
77 | return 0; |
||
78 | } |
||
79 | |||
80 | |||
81 | /* open a named or unnamed pipe/fifo */ |
||
82 | static int xioopen_fifo1(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3) { |
||
83 | const char *pipename = argv[1]; |
||
84 | int rw = (xioflags & XIO_ACCMODE); |
||
85 | #if HAVE_STAT64 |
||
86 | struct stat64 pipstat; |
||
87 | #else |
||
88 | struct stat pipstat; |
||
89 | #endif /* !HAVE_STAT64 */ |
||
90 | bool opt_unlink_early = false; |
||
91 | bool opt_unlink_close = true; |
||
92 | mode_t mode = 0666; |
||
93 | int result; |
||
94 | |||
95 | if (applyopts_single(&fd->stream, opts, PH_INIT) < 0) return -1; |
||
96 | applyopts(-1, opts, PH_INIT); |
||
97 | |||
98 | retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); |
||
99 | applyopts_named(pipename, opts, PH_EARLY); /* umask! */ |
||
100 | applyopts(-1, opts, PH_EARLY); |
||
101 | |||
102 | if (opt_unlink_early) { |
||
103 | if (Unlink(pipename) < 0) { |
||
104 | if (errno == ENOENT) { |
||
105 | Warn2("unlink(%s): %s", pipename, strerror(errno)); |
||
106 | } else { |
||
107 | Error2("unlink(%s): %s", pipename, strerror(errno)); |
||
108 | return STAT_RETRYLATER; |
||
109 | } |
||
110 | } |
||
111 | } |
||
112 | |||
113 | retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); |
||
114 | retropt_modet(opts, OPT_PERM, &mode); |
||
115 | if (applyopts_named(pipename, opts, PH_EARLY) < 0) { |
||
116 | return STAT_RETRYLATER; |
||
117 | } |
||
118 | if (applyopts_named(pipename, opts, PH_PREOPEN) < 0) { |
||
119 | return STAT_RETRYLATER; |
||
120 | } |
||
121 | if ( |
||
122 | #if HAVE_STAT64 |
||
123 | Stat64(pipename, &pipstat) < 0 |
||
124 | #else |
||
125 | Stat(pipename, &pipstat) < 0 |
||
126 | #endif /* !HAVE_STAT64 */ |
||
127 | ) { |
||
128 | if (errno != ENOENT) { |
||
129 | Error3("stat(\"%s\", %p): %s", pipename, &pipstat, strerror(errno)); |
||
130 | } else { |
||
131 | Debug1("xioopen_fifo(\"%s\"): does not exist, creating fifo", pipename); |
||
132 | #if 0 |
||
133 | result = Mknod(pipename, S_IFIFO|mode, 0); |
||
134 | if (result < 0) { |
||
135 | Error3("mknod(%s, %d, 0): %s", pipename, mode, strerror(errno)); |
||
136 | return STAT_RETRYLATER; |
||
137 | } |
||
138 | #else |
||
139 | result = Mkfifo(pipename, mode); |
||
140 | if (result < 0) { |
||
141 | Error3("mkfifo(%s, %d): %s", pipename, mode, strerror(errno)); |
||
142 | return STAT_RETRYLATER; |
||
143 | } |
||
144 | #endif |
||
145 | Notice2("created named pipe \"%s\" for %s", pipename, ddirection[rw]); |
||
146 | applyopts_named(pipename, opts, PH_ALL); |
||
147 | |||
148 | } |
||
149 | if (opt_unlink_close) { |
||
150 | if ((fd->stream.unlink_close = strdup(pipename)) == NULL) { |
||
151 | Error1("strdup(\"%s\"): out of memory", pipename); |
||
152 | } |
||
153 | fd->stream.opt_unlink_close = true; |
||
154 | } |
||
155 | } else { |
||
156 | /* exists */ |
||
157 | Debug1("xioopen_fifo(\"%s\"): already exist, opening it", pipename); |
||
158 | Notice3("opening %s \"%s\" for %s", |
||
159 | filetypenames[(pipstat.st_mode&S_IFMT)>>12], |
||
160 | pipename, ddirection[rw]); |
||
161 | /*applyopts_early(pipename, opts);*/ |
||
162 | applyopts_named(pipename, opts, PH_EARLY); |
||
163 | } |
||
164 | |||
165 | if ((result = _xioopen_open(pipename, rw, opts)) < 0) { |
||
166 | return result; |
||
167 | } |
||
168 | fd->stream.rfd = result; |
||
169 | fd->stream.wfd = result; |
||
170 | fd->stream.howtoshut = XIOSHUTWR_NONE|XIOSHUTRD_CLOSE; |
||
171 | fd->stream.howtoclose = XIOCLOSE_CLOSE; |
||
172 | |||
173 | applyopts_named(pipename, opts, PH_FD); |
||
174 | applyopts(fd->stream.rfd, opts, PH_FD); |
||
175 | applyopts_cloexec(fd->stream.rfd, opts); |
||
176 | return _xio_openlate(&fd->stream, opts); |
||
177 | } |
||
178 | |||
179 | #endif /* WITH_PIPE */ |