nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
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 */