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
, const struct addrdesc
*addrdesc
);
20 const struct addrdesc xioaddr_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(
28 const struct addrdesc
*addrdesc
)
30 struct single
*sfd
= &xxfd
->stream
;
31 const char *filename
= argv
[1];
32 flags_t openflags
= (xioflags
& XIO_ACCMODE
);
35 bool opt_unlink_close
= false;
39 _xioopen_named_early(argc
, argv
, xxfd
, GROUP_NAMED
|addrdesc
->groups
, &exists
,
40 opts
, addrdesc
->syntax
))
47 /* file (or at least named entry) exists */
48 if ((xioflags
&XIO_ACCMODE
) != XIO_RDONLY
) {
49 openflags
|= O_APPEND
;
55 /* note: when S_ISSOCK was undefined, it always gives 0 */
56 if (exists
&& S_ISSOCK(st_mode
)) {
58 union sockaddr_union us
;
59 socklen_t uslen
= sizeof(us
);
62 Info1("\"%s\" is a socket, connecting to it", filename
);
65 _xioopen_unix_client(sfd
, xioflags
, addrdesc
->groups
, 0, opts
,
70 applyopts_named(filename
, opts
, PH_PASTOPEN
); /* unlink-late */
72 if (Getsockname(sfd
->fd
, (struct sockaddr
*)&us
, &uslen
) < 0) {
73 Warn4("getsockname(%d, %p, {%d}): %s",
74 sfd
->fd
, &us
, uslen
, strerror(errno
));
76 Notice1("successfully connected via %s",
77 sockaddr_unix_info(&us
.un
, uslen
,
78 infobuff
, sizeof(infobuff
)));
81 Error("\"%s\" is a socket, but UNIX socket support is not compiled in");
83 #endif /* WITH_UNIX */
88 Info1("\"%s\" is not a socket, open()'ing it", filename
);
90 retropt_bool(opts
, OPT_UNLINK_CLOSE
, &opt_unlink_close
);
91 if (opt_unlink_close
) {
92 if ((sfd
->unlink_close
= strdup(filename
)) == NULL
) {
93 Error1("strdup(\"%s\"): out of memory", filename
);
95 sfd
->opt_unlink_close
= true;
98 Notice3("opening %s \"%s\" for %s",
99 filetypenames
[(st_mode
&S_IFMT
)>>12], filename
, ddirection
[(xioflags
&XIO_ACCMODE
)]);
100 if ((result
= _xioopen_open(filename
, openflags
, opts
)) < 0)
103 if (S_ISCHR(st_mode
) && Ioctl(result
, I_FIND
, "ldterm\0") == 0) {
104 Ioctl(result
, I_PUSH
, "ptem\0\0\0"); /* pad string length ... */
105 Ioctl(result
, I_PUSH
, "ldterm\0"); /* ... to requirements of ... */
106 Ioctl(result
, I_PUSH
, "ttcompat"); /* ... AdressSanitizer */
112 if (Isatty(sfd
->fd
)) {
113 if (Tcgetattr(sfd
->fd
, &sfd
->savetty
) < 0) {
114 Warn2("cannot query current terminal settings on fd %d: %s",
115 sfd
->fd
, strerror(errno
));
117 sfd
->ttyvalid
= true;
120 #endif /* WITH_TERMIOS */
121 applyopts_named(filename
, opts
, PH_FD
);
122 applyopts(sfd
, -1, opts
, PH_FD
);
123 applyopts_cloexec(sfd
->fd
, opts
);
126 if ((result
= applyopts2(sfd
, -1, opts
, PH_PASTSOCKET
, PH_CONNECTED
)) < 0)
129 if ((result
= _xio_openlate(sfd
, opts
)) < 0)
134 #endif /* WITH_GOPEN */