1 /* source: xio-gopen.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 generic open type */
7 #include "xiosysincludes.h"
10 #include "xio-named.h"
12 #include "xio-gopen.h"
17 static int xioopen_gopen(int argc
, const char *argv
[], struct opt
*opts
, int xioflags
, xiofile_t
*fd
, unsigned groups
, int dummy1
, int dummy2
, int dummy3
);
20 const struct addrdesc addr_gopen
= { "gopen", 3, xioopen_gopen
, GROUP_FD
|GROUP_FIFO
|GROUP_CHR
|GROUP_BLK
|GROUP_REG
|GROUP_NAMED
|GROUP_OPEN
|GROUP_FILE
|GROUP_TERMIOS
|GROUP_SOCKET
|GROUP_SOCK_UNIX
, 0, 0, 0 HELP(":<filename>") };
22 static int xioopen_gopen(int argc
, const char *argv
[], struct opt
*opts
, int xioflags
, xiofile_t
*fd
, unsigned groups
, int dummy1
, int dummy2
, int dummy3
) {
23 const char *filename
= argv
[1];
24 flags_t openflags
= (xioflags
& XIO_ACCMODE
);
27 bool opt_unlink_close
= false;
31 _xioopen_named_early(argc
, argv
, fd
, GROUP_NAMED
|groups
, &exists
, opts
)) < 0) {
37 /* file (or at least named entry) exists */
38 if ((xioflags
&XIO_ACCMODE
) != XIO_RDONLY
) {
39 openflags
|= O_APPEND
;
45 /* note: when S_ISSOCK was undefined, it always gives 0 */
46 if (exists
&& S_ISSOCK(st_mode
)) {
48 union sockaddr_union us
;
49 socklen_t uslen
= sizeof(us
);
52 Info1("\"%s\" is a socket, connecting to it", filename
);
55 _xioopen_unix_client(&fd
->stream
, xioflags
, groups
, 0, opts
, filename
);
59 applyopts_named(filename
, opts
, PH_PASTOPEN
); /* unlink-late */
61 if (Getsockname(fd
->stream
.fd
, (struct sockaddr
*)&us
, &uslen
) < 0) {
62 Warn4("getsockname(%d, %p, {%d}): %s",
63 fd
->stream
.fd
, &us
, uslen
, strerror(errno
));
65 Notice1("successfully connected via %s",
66 sockaddr_unix_info(&us
.un
, uslen
,
67 infobuff
, sizeof(infobuff
)));
70 Error("\"%s\" is a socket, but UNIX socket support is not compiled in");
72 #endif /* WITH_UNIX */
77 Info1("\"%s\" is not a socket, open()'ing it", filename
);
79 retropt_bool(opts
, OPT_UNLINK_CLOSE
, &opt_unlink_close
);
80 if (opt_unlink_close
) {
81 if ((fd
->stream
.unlink_close
= strdup(filename
)) == NULL
) {
82 Error1("strdup(\"%s\"): out of memory", filename
);
84 fd
->stream
.opt_unlink_close
= true;
87 Notice3("opening %s \"%s\" for %s",
88 filetypenames
[(st_mode
&S_IFMT
)>>12], filename
, ddirection
[(xioflags
&XIO_ACCMODE
)]);
89 if ((result
= _xioopen_open(filename
, openflags
, opts
)) < 0)
92 if (S_ISCHR(st_mode
)) {
93 Ioctl(result
, I_PUSH
, "ptem\0\0\0"); /* pad string length ... */
94 Ioctl(result
, I_PUSH
, "ldterm\0"); /* ... to requirements of ... */
95 Ioctl(result
, I_PUSH
, "ttcompat"); /* ... AdressSanitizer */
98 fd
->stream
.fd
= result
;
101 if (Isatty(fd
->stream
.fd
)) {
102 if (Tcgetattr(fd
->stream
.fd
, &fd
->stream
.savetty
) < 0) {
103 Warn2("cannot query current terminal settings on fd %d: %s",
104 fd
->stream
.fd
, strerror(errno
));
106 fd
->stream
.ttyvalid
= true;
109 #endif /* WITH_TERMIOS */
110 applyopts_named(filename
, opts
, PH_FD
);
111 applyopts(fd
->stream
.fd
, opts
, PH_FD
);
112 applyopts_cloexec(fd
->stream
.fd
, opts
);
115 if ((result
= applyopts2(fd
->stream
.fd
, opts
, PH_PASTSOCKET
, PH_CONNECTED
)) < 0)
118 if ((result
= _xio_openlate(&fd
->stream
, opts
)) < 0)
123 #endif /* WITH_GOPEN */