Treat all unknown auxv tags on FreeBSD as unknown.
[external/binutils.git] / gdb / ser-uds.c
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>
26 #include <netdb.h>
27 #include "netstuff.h"
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 {
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
50   struct sockaddr_un addr;
51
52   if (strlen (socket_name) > UNIX_PATH_MAX - 1)
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;
62   strncpy (addr.sun_path, socket_name, UNIX_PATH_MAX - 1);
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 }