Commit | Line | Data |
---|---|---|
c1168a2f JD |
1 | /* Serial interface for local domain connections on Un*x like systems. |
2 | ||
3 | Copyright (C) 1992-2018 Free Software Foundation, Inc. | |
4 | ||
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include "defs.h" | |
21 | #include "serial.h" | |
22 | #include "ser-base.h" | |
23 | ||
24 | #include <sys/socket.h> | |
25 | #include <sys/un.h> | |
88f5cc8c JD |
26 | #include <netdb.h> |
27 | #include "netstuff.h" | |
c1168a2f JD |
28 | |
29 | #ifndef UNIX_PATH_MAX | |
30 | #define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path) | |
31 | #endif | |
32 | ||
33 | /* Open an AF_UNIX socket. */ | |
34 | ||
35 | static int | |
36 | uds_open (struct serial *scb, const char *name) | |
37 | { | |
88f5cc8c JD |
38 | struct addrinfo hint; |
39 | ||
40 | memset (&hint, 0, sizeof (hint)); | |
41 | /* Assume no prefix will be passed, therefore we should use | |
42 | AF_UNSPEC. */ | |
43 | hint.ai_family = AF_UNSPEC; | |
44 | hint.ai_socktype = SOCK_STREAM; | |
45 | ||
46 | parsed_connection_spec parsed = parse_connection_spec (name, &hint); | |
47 | ||
48 | const char *socket_name = parsed.port_str.empty() ? name : parsed.port_str.c_str (); | |
49 | ||
c1168a2f JD |
50 | struct sockaddr_un addr; |
51 | ||
88f5cc8c | 52 | if (strlen (socket_name) > UNIX_PATH_MAX - 1) |
c1168a2f JD |
53 | { |
54 | warning | |
55 | (_("The socket name is too long. It may be no longer than %s bytes."), | |
56 | pulongest (UNIX_PATH_MAX - 1L)); | |
57 | return -1; | |
58 | } | |
59 | ||
60 | memset (&addr, 0, sizeof addr); | |
61 | addr.sun_family = AF_UNIX; | |
88f5cc8c | 62 | strncpy (addr.sun_path, socket_name, UNIX_PATH_MAX - 1); |
c1168a2f JD |
63 | |
64 | int sock = socket (AF_UNIX, SOCK_STREAM, 0); | |
65 | ||
66 | if (connect (sock, (struct sockaddr *) &addr, | |
67 | sizeof (struct sockaddr_un)) < 0) | |
68 | { | |
69 | close (sock); | |
70 | scb->fd = -1; | |
71 | return -1; | |
72 | } | |
73 | ||
74 | scb->fd = sock; | |
75 | ||
76 | return 0; | |
77 | } | |
78 | ||
79 | static void | |
80 | uds_close (struct serial *scb) | |
81 | { | |
82 | if (scb->fd == -1) | |
83 | return; | |
84 | ||
85 | close (scb->fd); | |
86 | scb->fd = -1; | |
87 | } | |
88 | ||
89 | static int | |
90 | uds_read_prim (struct serial *scb, size_t count) | |
91 | { | |
92 | return recv (scb->fd, scb->buf, count, 0); | |
93 | } | |
94 | ||
95 | static int | |
96 | uds_write_prim (struct serial *scb, const void *buf, size_t count) | |
97 | { | |
98 | return send (scb->fd, buf, count, 0); | |
99 | } | |
100 | ||
101 | /* The local socket ops. */ | |
102 | ||
103 | static const struct serial_ops uds_ops = | |
104 | { | |
105 | "local", | |
106 | uds_open, | |
107 | uds_close, | |
108 | NULL, | |
109 | ser_base_readchar, | |
110 | ser_base_write, | |
111 | ser_base_flush_output, | |
112 | ser_base_flush_input, | |
113 | ser_base_send_break, | |
114 | ser_base_raw, | |
115 | ser_base_get_tty_state, | |
116 | ser_base_copy_tty_state, | |
117 | ser_base_set_tty_state, | |
118 | ser_base_print_tty_state, | |
119 | ser_base_setbaudrate, | |
120 | ser_base_setstopbits, | |
121 | ser_base_setparity, | |
122 | ser_base_drain_output, | |
123 | ser_base_async, | |
124 | uds_read_prim, | |
125 | uds_write_prim | |
126 | }; | |
127 | ||
128 | void | |
129 | _initialize_ser_socket (void) | |
130 | { | |
131 | serial_add_interface (&uds_ops); | |
132 | } |