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"
17 static int xioopen_fifo(int argc
, const char *argv
[], struct opt
*opts
, int xioflags
, xiofile_t
*fd
, const struct addrdesc
*addrdesc
);
18 static int xioopen_fifo_unnamed(xiofile_t
*sock
, struct opt
*opts
);
21 const struct addrdesc xioaddr_pipe
= { "PIPE", 3, xioopen_fifo
, GROUP_FD
|GROUP_NAMED
|GROUP_OPEN
|GROUP_FIFO
, 0, 0, 0 HELP("[:<filename>]") };
23 #if defined(F_SETPIPE_SZ)
24 const struct optdesc opt_f_setpipe_sz
= { "f-setpipe-sz", "pipesz", OPT_F_SETPIPE_SZ
, GROUP_FD
, PH_FD
, TYPE_INT
, OFUNC_FCNTL
, F_SETPIPE_SZ
, 0 };
27 /* process an unnamed bidirectional "pipe" or "fifo" or "echo" argument with
29 static int xioopen_fifo_unnamed(xiofile_t
*sock
, struct opt
*opts
) {
30 struct single
*sfd
= &sock
->stream
;
36 if (applyopts_single(sfd
, opts
, PH_INIT
) < 0) return -1;
37 applyopts(sfd
, -1, opts
, PH_INIT
);
39 if (Pipe(filedes
) != 0) {
40 Error2("pipe(%p): %s", filedes
, strerror(errno
));
43 /*0 Info2("pipe({%d,%d})", filedes[0], filedes[1]);*/
45 sock
->common
.tag
= XIO_TAG_RDWR
;
46 sfd
->dtype
= XIODATA_PIPE
;
48 sfd
->para
.bipipe
.fdout
= filedes
[1];
49 sfd
->para
.bipipe
.socktype
= SOCK_STREAM
; /* due to socketpair reuse */
50 applyopts_cloexec(sfd
->fd
, opts
);
51 applyopts_cloexec(sfd
->para
.bipipe
.fdout
, opts
);
53 /* one-time and input-direction options, no second application */
54 retropt_bool(opts
, OPT_IGNOREEOF
, &sfd
->ignoreeof
);
56 /* here we copy opts! */
57 if ((opts2
= copyopts(opts
, GROUP_FIFO
)) == NULL
) {
61 /* apply options to first FD */
62 if ((result
= applyopts(sfd
, -1, opts
, PH_ALL
)) < 0) {
65 if ((result
= applyopts_single(sfd
, opts
, PH_ALL
)) < 0) {
69 /* apply options to second FD */
70 if (applyopts(&sock
->stream
, sfd
->para
.bipipe
.fdout
, opts2
, PH_ALL
) < 0)
73 if ((numleft
= leftopts(opts
)) > 0) {
75 Error1("INTERNAL: %d option(s) remained unused", numleft
);
78 xio_chk_pipesz(sfd
->fd
);
80 Notice("writing to and reading from unnamed pipe");
85 /* open a named or unnamed pipe/fifo */
86 static int xioopen_fifo(
92 const struct addrdesc
*addrdesc
)
94 struct single
*sfd
= &xfd
->stream
;
95 const char *pipename
= argv
[1];
96 int rw
= (xioflags
& XIO_ACCMODE
);
98 struct stat64 pipstat
;
101 #endif /* !HAVE_STAT64 */
102 bool opt_unlink_early
= false;
103 bool opt_unlink_close
= true;
108 return xioopen_fifo_unnamed(xfd
, sfd
->opts
);
112 xio_syntax(argv
[0], 1, argc
-1,addrdesc
->syntax
);
116 if (applyopts_single(sfd
, opts
, PH_INIT
) < 0)
118 applyopts(sfd
, -1, opts
, PH_INIT
);
120 retropt_bool(opts
, OPT_UNLINK_EARLY
, &opt_unlink_early
);
121 applyopts_named(pipename
, opts
, PH_EARLY
); /* umask! */
122 applyopts(sfd
, -1, opts
, PH_EARLY
);
124 if (opt_unlink_early
) {
125 if (Unlink(pipename
) < 0) {
126 return STAT_RETRYLATER
;
130 retropt_bool(opts
, OPT_UNLINK_CLOSE
, &opt_unlink_close
);
131 retropt_modet(opts
, OPT_PERM
, &mode
);
132 if (applyopts_named(pipename
, opts
, PH_EARLY
) < 0) {
133 return STAT_RETRYLATER
;
135 if (applyopts_named(pipename
, opts
, PH_PREOPEN
) < 0) {
136 return STAT_RETRYLATER
;
140 Stat64(pipename
, &pipstat
) < 0
142 Stat(pipename
, &pipstat
) < 0
143 #endif /* !HAVE_STAT64 */
145 if (errno
!= ENOENT
) {
146 Error3("stat(\"%s\", %p): %s", pipename
, &pipstat
, strerror(errno
));
148 Debug1("xioopen_fifo(\"%s\"): does not exist, creating fifo", pipename
);
150 result
= Mknod(pipename
, S_IFIFO
|mode
, 0);
152 Error3("mknod(%s, %d, 0): %s", pipename
, mode
, strerror(errno
));
153 return STAT_RETRYLATER
;
156 result
= Mkfifo(pipename
, mode
);
158 Error3("mkfifo(%s, %d): %s", pipename
, mode
, strerror(errno
));
159 return STAT_RETRYLATER
;
162 Notice2("created named pipe \"%s\" for %s", pipename
, ddirection
[rw
]);
163 applyopts_named(pipename
, opts
, PH_ALL
);
166 if (opt_unlink_close
) {
167 if ((sfd
->unlink_close
= strdup(pipename
)) == NULL
) {
168 Error1("strdup(\"%s\"): out of memory", pipename
);
170 sfd
->opt_unlink_close
= true;
174 Info1("xioopen_fifo(\"%s\"): already exist, opening it", pipename
);
175 Notice3("opening %s \"%s\" for %s",
176 filetypenames
[(pipstat
.st_mode
&S_IFMT
)>>12],
177 pipename
, ddirection
[rw
]);
178 applyopts_named(pipename
, opts
, PH_EARLY
);
181 if ((result
= _xioopen_open(pipename
, rw
, opts
)) < 0) {
186 applyopts_named(pipename
, opts
, PH_FD
);
187 applyopts(sfd
, -1, opts
, PH_FD
);
188 applyopts_cloexec(sfd
->fd
, opts
);
189 xio_chk_pipesz(sfd
->fd
);
191 return _xio_openlate(sfd
, opts
);
195 /* Checks if fd is a pipe and if its buffer is at least the blksiz.
197 returns 1 if unknown;
205 if (fstat(fd
, &st
) < 0) {
206 Warn2("fstat(%d, ...): %s", fd
, strerror(errno
));
209 if ((st
.st_mode
&S_IFMT
) != S_IFIFO
) {
213 #if defined(F_GETPIPE_SZ)
214 if ((pipesz
= Fcntl(fd
, F_GETPIPE_SZ
)) < 0) {
215 Warn2("fcntl(%d, F_GETPIPE_SZ): %s", fd
, strerror(errno
));
219 if (pipesz
>= xioparms
.bufsiz
)
222 Warn3("xio_chk_pipesz(%d, ...): Socat block size "F_Zu
" is larger than pipe size %d, might block; use option f-setpipe-sz!",
223 fd
, xioparms
.bufsiz
, pipesz
);
225 #else /* !defined(F_GETPIPE_SZ) */
227 #endif /* !defined(F_GETPIPE_SZ) */
230 #endif /* WITH_PIPE */