1 /* source: xio-pipe.c */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
3 /* Published under the GNU General Public License V.2, see file COPYING */
5 /* this file contains the source for opening addresses of pipe type */
7 #include "xiosysincludes.h"
10 #include "xio-named.h"
15 static int xioopen_fifo(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_fifo_unnamed(xiofile_t
*sock
, struct opt
*opts
);
19 const struct addrdesc addr_pipe
= { "pipe", 3, xioopen_fifo
, GROUP_FD
|GROUP_NAMED
|GROUP_OPEN
|GROUP_FIFO
, 0, 0, 0 HELP(":<filename>") };
22 /* process an unnamed bidirectional "pipe" or "fifo" or "echo" argument with
24 static int xioopen_fifo_unnamed(xiofile_t
*sock
, struct opt
*opts
) {
30 if (applyopts_single(&sock
->stream
, opts
, PH_INIT
) < 0) return -1;
31 applyopts(-1, opts
, PH_INIT
);
33 if (Pipe(filedes
) != 0) {
34 Error2("pipe(%p): %s", filedes
, strerror(errno
));
37 /*0 Info2("pipe({%d,%d})", filedes[0], filedes[1]);*/
39 sock
->common
.tag
= XIO_TAG_RDWR
;
40 sock
->stream
.dtype
= XIODATA_PIPE
;
41 sock
->stream
.fd
= filedes
[0];
42 sock
->stream
.para
.bipipe
.fdout
= filedes
[1];
43 applyopts_cloexec(sock
->stream
.fd
, opts
);
44 applyopts_cloexec(sock
->stream
.para
.bipipe
.fdout
, opts
);
46 /* one-time and input-direction options, no second application */
47 retropt_bool(opts
, OPT_IGNOREEOF
, &sock
->stream
.ignoreeof
);
49 /* here we copy opts! */
50 if ((opts2
= copyopts(opts
, GROUP_FIFO
)) == NULL
) {
54 /* apply options to first FD */
55 if ((result
= applyopts(sock
->stream
.fd
, opts
, PH_ALL
)) < 0) {
58 if ((result
= applyopts_single(&sock
->stream
, opts
, PH_ALL
)) < 0) {
62 /* apply options to second FD */
63 if ((result
= applyopts(sock
->stream
.para
.bipipe
.fdout
, opts2
, PH_ALL
)) < 0)
68 if ((numleft
= leftopts(opts
)) > 0) {
69 Error1("%d option(s) could not be used", numleft
);
72 Notice("writing to and reading from unnamed pipe");
77 /* open a named or unnamed pipe/fifo */
78 static int xioopen_fifo(int argc
, const char *argv
[], struct opt
*opts
, int xioflags
, xiofile_t
*fd
, unsigned groups
, int dummy1
, int dummy2
, int dummy3
) {
79 const char *pipename
= argv
[1];
80 int rw
= (xioflags
& XIO_ACCMODE
);
82 struct stat64 pipstat
;
85 #endif /* !HAVE_STAT64 */
86 bool opt_unlink_early
= false;
87 bool opt_unlink_close
= true;
92 return xioopen_fifo_unnamed(fd
, fd
->stream
.opts
);
96 Error2("%s: wrong number of parameters (%d instead of 1)", argv
[0], argc
-1);
99 if (applyopts_single(&fd
->stream
, opts
, PH_INIT
) < 0) return -1;
100 applyopts(-1, opts
, PH_INIT
);
102 retropt_bool(opts
, OPT_UNLINK_EARLY
, &opt_unlink_early
);
103 applyopts_named(pipename
, opts
, PH_EARLY
); /* umask! */
104 applyopts(-1, opts
, PH_EARLY
);
106 if (opt_unlink_early
) {
107 if (Unlink(pipename
) < 0) {
108 if (errno
== ENOENT
) {
109 Warn2("unlink(%s): %s", pipename
, strerror(errno
));
111 Error2("unlink(%s): %s", pipename
, strerror(errno
));
112 return STAT_RETRYLATER
;
117 retropt_bool(opts
, OPT_UNLINK_CLOSE
, &opt_unlink_close
);
118 retropt_modet(opts
, OPT_PERM
, &mode
);
119 if (applyopts_named(pipename
, opts
, PH_EARLY
) < 0) {
120 return STAT_RETRYLATER
;
122 if (applyopts_named(pipename
, opts
, PH_PREOPEN
) < 0) {
123 return STAT_RETRYLATER
;
127 Stat64(pipename
, &pipstat
) < 0
129 Stat(pipename
, &pipstat
) < 0
130 #endif /* !HAVE_STAT64 */
132 if (errno
!= ENOENT
) {
133 Error3("stat(\"%s\", %p): %s", pipename
, &pipstat
, strerror(errno
));
135 Debug1("xioopen_fifo(\"%s\"): does not exist, creating fifo", pipename
);
137 result
= Mknod(pipename
, S_IFIFO
|mode
, 0);
139 Error3("mknod(%s, %d, 0): %s", pipename
, mode
, strerror(errno
));
140 return STAT_RETRYLATER
;
143 result
= Mkfifo(pipename
, mode
);
145 Error3("mkfifo(%s, %d): %s", pipename
, mode
, strerror(errno
));
146 return STAT_RETRYLATER
;
149 Notice2("created named pipe \"%s\" for %s", pipename
, ddirection
[rw
]);
150 applyopts_named(pipename
, opts
, PH_ALL
);
153 if (opt_unlink_close
) {
154 if ((fd
->stream
.unlink_close
= strdup(pipename
)) == NULL
) {
155 Error1("strdup(\"%s\"): out of memory", pipename
);
157 fd
->stream
.opt_unlink_close
= true;
161 Debug1("xioopen_fifo(\"%s\"): already exist, opening it", pipename
);
162 Notice3("opening %s \"%s\" for %s",
163 filetypenames
[(pipstat
.st_mode
&S_IFMT
)>>12],
164 pipename
, ddirection
[rw
]);
165 /*applyopts_early(pipename, opts);*/
166 applyopts_named(pipename
, opts
, PH_EARLY
);
169 if ((result
= _xioopen_open(pipename
, rw
, opts
)) < 0) {
172 fd
->stream
.fd
= result
;
174 applyopts_named(pipename
, opts
, PH_FD
);
175 applyopts(fd
->stream
.fd
, opts
, PH_FD
);
176 applyopts_cloexec(fd
->stream
.fd
, opts
);
177 return _xio_openlate(&fd
->stream
, opts
);
180 #endif /* WITH_PIPE */