1 /* source: xio-fdnum.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 fdnum type */
7 #include "xiosysincludes.h"
10 #include "xio-listen.h"
12 #include "xio-fdnum.h"
17 static int xioopen_fdnum(int argc
, const char *argv
[], struct opt
*opts
, int xioflags
, xiofile_t
*xfd
, const struct addrdesc
*addrdesc
);
18 static int xioopen_accept_fd(int argc
, const char *argv
[], struct opt
*opts
, int xioflags
, xiofile_t
*xfd
, const struct addrdesc
*addrdesc
);
21 const struct addrdesc xioaddr_fd
= { "FD", 1+XIO_RDWR
, xioopen_fdnum
, GROUP_FD
|GROUP_FIFO
|GROUP_CHR
|GROUP_BLK
|GROUP_FILE
|GROUP_SOCKET
|GROUP_TERMIOS
|GROUP_SOCK_UNIX
|GROUP_SOCK_IP
|GROUP_IPAPP
, 0, 0, 0 HELP(":<fdnum>") };
23 const struct addrdesc xioaddr_accept_fd
= { "ACCEPT-FD", 1+XIO_RDWR
, xioopen_accept_fd
, GROUP_FD
|GROUP_SOCKET
|GROUP_SOCK_UNIX
|GROUP_SOCK_IP
|GROUP_IPAPP
|GROUP_CHILD
|GROUP_RANGE
|GROUP_RETRY
, 0, 0, 0 HELP(":<fdnum>") };
24 #endif /* WITH_LISTEN */
27 /* use some file descriptor and apply the options. Set the FD_CLOEXEC flag. */
28 static int xioopen_fdnum(
34 const struct addrdesc
*addrdesc
)
37 int rw
= (xioflags
&XIO_ACCMODE
);
42 Error2("%s: wrong number of parameters (%d instead of 1)", argv
[0], argc
-1);
45 numfd
= strtoul(argv
[1], &a1
, 0);
47 Error1("error in FD number \"%s\"", argv
[1]);
49 /* we dont want to see these fds in child processes */
50 if (Fcntl_l(numfd
, F_SETFD
, FD_CLOEXEC
) < 0) {
51 Warn2("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", numfd
, strerror(errno
));
53 Notice2("using file descriptor %d for %s", numfd
, ddirection
[rw
]);
54 if ((result
= xioopen_fd(opts
, rw
, &xfd
->stream
, numfd
)) < 0) {
62 /* Use some file descriptor and apply the options. Set the FD_CLOEXEC flag. */
63 static int xioopen_accept_fd(
69 const struct addrdesc
*addrdesc
)
72 int rw
= (xioflags
&XIO_ACCMODE
);
74 union sockaddr_union us
;
75 socklen_t uslen
= sizeof(union sockaddr_union
);
79 xio_syntax(argv
[0], 1, argc
-1, addrdesc
->syntax
);
83 numfd
= strtoul(argv
[1], &a1
, 0);
85 Error1("error in FD number \"%s\"", argv
[1]);
87 /* we dont want to see these fds in child processes */
88 if (Fcntl_l(numfd
, F_SETFD
, FD_CLOEXEC
) < 0) {
89 Warn2("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", numfd
, strerror(errno
));
92 if (Getsockname(numfd
, (struct sockaddr
*)&us
, &uslen
) < 0) {
93 Warn2("getsockname(fd=%d, ...): %s", numfd
, strerror(errno
));
95 Notice2("using file descriptor %d accepting a connection for %s", numfd
, ddirection
[rw
]);
96 xfd
->stream
.fd
= numfd
;
97 if ((result
= _xioopen_accept_fd(&xfd
->stream
, xioflags
, (struct sockaddr
*)&us
, uslen
, opts
, us
.soa
.sa_family
, 0, 0)) < 0) {
103 #endif /* WITH_LISTEN */
104 #endif /* WITH_FDNUM */
109 /* Retrieves and apply options to a standard file descriptor.
110 Does not set FD_CLOEXEC flag. */
111 int xioopen_fd(struct opt
*opts
, int rw
, struct single
*sfd
, int numfd
) {
114 if (sfd
->howtoend
== END_UNSPEC
)
115 sfd
->howtoend
= END_NONE
;
118 if (Isatty(sfd
->fd
)) {
119 if (Tcgetattr(sfd
->fd
, &sfd
->savetty
) < 0) {
120 Warn2("cannot query current terminal settings on fd %d: %s",
121 sfd
->fd
, strerror(errno
));
123 sfd
->ttyvalid
= true;
126 #endif /* WITH_TERMIOS */
127 if (applyopts_single(sfd
, opts
, PH_INIT
) < 0)
130 applyopts2(sfd
, -1, opts
, PH_INIT
, PH_FD
);
132 return _xio_openlate(sfd
, opts
);