OpenOCD
server.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2005 by Dominic Rath *
5  * Dominic.Rath@gmx.de *
6  * *
7  * Copyright (C) 2007-2010 Øyvind Harboe *
8  * oyvind.harboe@zylin.com *
9  * *
10  * Copyright (C) 2008 by Spencer Oliver *
11  * spen@spen-soft.co.uk *
12  ***************************************************************************/
13 
14 #ifdef HAVE_CONFIG_H
15 #include "config.h"
16 #endif
17 
18 #include "server.h"
19 #include <helper/tcl-common.h>
20 #include <helper/time_support.h>
21 #include <target/target.h>
22 #include <target/target_request.h>
24 #include "openocd.h"
25 #include "tcl_server.h"
26 #include "telnet_server.h"
27 #include "ipdbg.h"
28 
29 #include <signal.h>
30 
31 #ifdef HAVE_NETDB_H
32 #include <netdb.h>
33 #endif
34 
35 #ifndef _WIN32
36 #include <netinet/tcp.h>
37 #endif
38 
40  CONTINUE_MAIN_LOOP, /* stay in main event loop */
41  SHUTDOWN_REQUESTED, /* set by shutdown command; exit the event loop and quit the debugger */
42  SHUTDOWN_WITH_ERROR_CODE, /* set by shutdown command; quit with non-zero return code */
43  SHUTDOWN_WITH_SIGNAL_CODE /* set by sig_handler; exec shutdown then exit with signal as return code */
44 };
45 
46 static struct service *services;
47 
48 static volatile sig_atomic_t shutdown_openocd = CONTINUE_MAIN_LOOP;
49 /* Received signal number, later used to kill ourselves.
50  * Only relevant for SHUTDOWN_WITH_SIGNAL_CODE. */
51 static volatile sig_atomic_t last_signal;
52 /* Exit status to use. Only relevant for SHUTDOWN_REQUESTED
53  * or SHUTDOWN_WITH_ERROR_CODE. */
54 static uint8_t openocd_exit_status_code;
55 
56 /* set the polling period to 100ms */
57 static int polling_period = 100;
58 
59 /* address by name on which to listen for incoming TCP/IP connections */
60 static char *bindto_name;
61 
62 static int add_connection(struct service *service, struct command_context *cmd_ctx)
63 {
64  socklen_t address_size;
65  struct connection *c, **p;
66  int retval;
67  int flag = 1;
68 
69  c = malloc(sizeof(struct connection));
70  c->fd = -1;
71  c->fd_out = -1;
72  memset(&c->sin, 0, sizeof(c->sin));
74  c->service = service;
75  c->input_pending = false;
76  c->priv = NULL;
77  c->next = NULL;
78 
79  if (service->type == CONNECTION_TCP) {
80  address_size = sizeof(c->sin);
81 
82  c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
83  c->fd_out = c->fd;
84 
85  /* This increases performance dramatically for e.g. GDB load which
86  * does not have a sliding window protocol.
87  *
88  * Ignore errors from this fn as it probably just means less performance
89  */
90  setsockopt(c->fd, /* socket affected */
91  IPPROTO_TCP, /* set option at TCP level */
92  TCP_NODELAY, /* name of option */
93  (char *)&flag, /* the cast is historical cruft */
94  sizeof(int)); /* length of option value */
95 
96  LOG_INFO("accepting '%s' connection on tcp/%s", service->name, service->port);
97  retval = service->new_connection(c);
98  if (retval != ERROR_OK) {
99  close_socket(c->fd);
100  LOG_ERROR("attempted '%s' connection rejected", service->name);
101  command_done(c->cmd_ctx);
102  free(c);
103  return retval;
104  }
105  } else if (service->type == CONNECTION_STDINOUT) {
106  c->fd = service->fd;
107  c->fd_out = fileno(stdout);
108 
109 #ifdef _WIN32
110  /* we are using stdin/out so ignore ctrl-c under windoze */
111  SetConsoleCtrlHandler(NULL, TRUE);
112 #endif
113 
114  /* do not check for new connections again on stdin */
115  service->fd = -1;
116 
117  LOG_INFO("accepting '%s' connection from pipe", service->name);
118  retval = service->new_connection(c);
119  if (retval != ERROR_OK) {
120  LOG_ERROR("attempted '%s' connection rejected", service->name);
121  command_done(c->cmd_ctx);
122  free(c);
123  return retval;
124  }
125  } else if (service->type == CONNECTION_PIPE) {
126  c->fd = service->fd;
127  /* do not check for new connections again on stdin */
128  service->fd = -1;
129 
130  char *out_file = alloc_printf("%so", service->port);
131  c->fd_out = open(out_file, O_WRONLY);
132  free(out_file);
133  if (c->fd_out == -1) {
134  LOG_ERROR("could not open %s", service->port);
135  command_done(c->cmd_ctx);
136  free(c);
137  return ERROR_FAIL;
138  }
139 
140  LOG_INFO("accepting '%s' connection from pipe %s", service->name, service->port);
141  retval = service->new_connection(c);
142  if (retval != ERROR_OK) {
143  LOG_ERROR("attempted '%s' connection rejected", service->name);
144  command_done(c->cmd_ctx);
145  free(c);
146  return retval;
147  }
148  }
149 
150  /* add to the end of linked list */
151  for (p = &service->connections; *p; p = &(*p)->next)
152  ;
153  *p = c;
154 
157 
158  return ERROR_OK;
159 }
160 
162 {
163  struct connection **p = &service->connections;
164  struct connection *c;
165 
166  /* find connection */
167  while ((c = *p)) {
168  if (c->fd == connection->fd) {
171  if (service->type == CONNECTION_TCP)
172  close_socket(c->fd);
173  else if (service->type == CONNECTION_PIPE) {
174  /* The service will listen to the pipe again */
175  c->service->fd = c->fd;
176  }
177 
178  command_done(c->cmd_ctx);
179 
180  /* delete connection */
181  *p = c->next;
182  free(c);
183 
186 
187  break;
188  }
189 
190  /* redirect p to next list pointer */
191  p = &(*p)->next;
192  }
193 
194  return ERROR_OK;
195 }
196 
197 static void free_service(struct service *c)
198 {
199  if (c->type == CONNECTION_PIPE && c->fd != -1)
200  close(c->fd);
201  if (c->type == CONNECTION_TCP && c->fd != -1)
202  close_socket(c->fd);
203  if (c->service_dtor)
204  c->service_dtor(c);
205  free(c->name);
206  free(c->port);
207  free(c->priv);
208  free(c);
209 }
210 
211 int add_service(const struct service_driver *driver, const char *port,
212  int max_connections, void *priv)
213 {
214  struct service *c, **p;
215  struct hostent *hp;
216  int so_reuseaddr_option = 1;
217 
218  c = calloc(1, sizeof(*c));
219  if (!c) {
220  LOG_ERROR("Out of memory");
221  return ERROR_FAIL;
222  }
223 
224  c->name = strdup(driver->name);
225  c->port = strdup(port);
226  c->max_connections = 1; /* Only TCP/IP ports can support more than one connection */
227  c->fd = -1;
228  c->connections = NULL;
231  c->input = driver->input_handler;
234  c->service_dtor = driver->service_dtor_handler;
235  c->service_info = driver->service_info_handler;
236  c->priv = priv;
237  c->next = NULL;
238 
239  if (!c->name || !c->port) {
240  LOG_ERROR("Out of memory");
241  goto error;
242  }
243 
244  long portnumber;
245  if (strcmp(c->port, "pipe") == 0)
247  else {
248  char *end;
249  portnumber = strtol(c->port, &end, 0);
250  if (!*end && (parse_long(c->port, &portnumber) == ERROR_OK)) {
251  c->portnumber = portnumber;
252  c->type = CONNECTION_TCP;
253  } else
254  c->type = CONNECTION_PIPE;
255  }
256 
257  if (c->type == CONNECTION_TCP) {
258  c->max_connections = max_connections;
259 
260  c->fd = socket(AF_INET, SOCK_STREAM, 0);
261  if (c->fd == -1) {
262  LOG_ERROR("error creating socket: %s", strerror(errno));
263  goto error;
264  }
265 
266  setsockopt(c->fd,
267  SOL_SOCKET,
268  SO_REUSEADDR,
269  (void *)&so_reuseaddr_option,
270  sizeof(int));
271 
272  socket_nonblock(c->fd);
273 
274  memset(&c->sin, 0, sizeof(c->sin));
275  c->sin.sin_family = AF_INET;
276 
277  if (!bindto_name)
278  c->sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
279  else {
280  hp = gethostbyname(bindto_name);
281  if (!hp) {
282  LOG_ERROR("couldn't resolve bindto address: %s", bindto_name);
283  close_socket(c->fd);
284  goto error;
285  }
286  memcpy(&c->sin.sin_addr, hp->h_addr_list[0], hp->h_length);
287  }
288  c->sin.sin_port = htons(c->portnumber);
289 
290  if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
291  LOG_ERROR("couldn't bind %s to socket on port %d: %s", c->name, c->portnumber, strerror(errno));
292  close_socket(c->fd);
293  goto error;
294  }
295 
296 #ifndef _WIN32
297  int segsize = 65536;
298  setsockopt(c->fd, IPPROTO_TCP, TCP_MAXSEG, &segsize, sizeof(int));
299 #endif
300  int window_size = 128 * 1024;
301 
302  /* These setsockopt()s must happen before the listen() */
303 
304  setsockopt(c->fd, SOL_SOCKET, SO_SNDBUF,
305  (char *)&window_size, sizeof(window_size));
306  setsockopt(c->fd, SOL_SOCKET, SO_RCVBUF,
307  (char *)&window_size, sizeof(window_size));
308 
309  if (listen(c->fd, 1) == -1) {
310  LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
311  close_socket(c->fd);
312  goto error;
313  }
314 
315  struct sockaddr_in addr_in;
316  addr_in.sin_port = 0;
317  socklen_t addr_in_size = sizeof(addr_in);
318  if (getsockname(c->fd, (struct sockaddr *)&addr_in, &addr_in_size) == 0)
319  LOG_INFO("Listening on port %hu for %s connections",
320  ntohs(addr_in.sin_port), c->name);
321  } else if (c->type == CONNECTION_STDINOUT) {
322  c->fd = fileno(stdin);
323 
324 #ifdef _WIN32
325  /* for win32 set stdin/stdout to binary mode */
326  if (_setmode(_fileno(stdout), _O_BINARY) < 0)
327  LOG_WARNING("cannot change stdout mode to binary");
328  if (_setmode(_fileno(stdin), _O_BINARY) < 0)
329  LOG_WARNING("cannot change stdin mode to binary");
330  if (_setmode(_fileno(stderr), _O_BINARY) < 0)
331  LOG_WARNING("cannot change stderr mode to binary");
332 #else
333  socket_nonblock(c->fd);
334 #endif
335  } else if (c->type == CONNECTION_PIPE) {
336 #ifdef _WIN32
337  /* we currently do not support named pipes under win32
338  * so exit openocd for now */
339  LOG_ERROR("Named pipes currently not supported under this os");
340  goto error;
341 #else
342  /* Pipe we're reading from */
343  c->fd = open(c->port, O_RDONLY | O_NONBLOCK);
344  if (c->fd == -1) {
345  LOG_ERROR("could not open %s", c->port);
346  goto error;
347  }
348 #endif
349  }
350 
351  /* add to the end of linked list */
352  for (p = &services; *p; p = &(*p)->next)
353  ;
354  *p = c;
355 
356  return ERROR_OK;
357 
358 error:
359  // Only free() what has been locally allocated
360  free(c->port);
361  free(c->name);
362  free(c);
363 
364  return ERROR_FAIL;
365 }
366 
367 static void remove_connections(struct service *service)
368 {
369  struct connection *connection;
370 
372 
373  while (connection) {
374  struct connection *tmp;
375 
376  tmp = connection->next;
378  connection = tmp;
379  }
380 }
381 
382 int remove_service(const char *name, const char *port)
383 {
384  struct service *tmp;
385  struct service *prev;
386 
387  prev = services;
388 
389  for (tmp = services; tmp; prev = tmp, tmp = tmp->next) {
390  if (!strcmp(tmp->name, name) && !strcmp(tmp->port, port)) {
391  remove_connections(tmp);
392 
393  if (tmp == services)
394  services = tmp->next;
395  else
396  prev->next = tmp->next;
397 
398  if (tmp->type != CONNECTION_STDINOUT)
399  close_socket(tmp->fd);
400 
401  free_service(tmp);
402 
403  return ERROR_OK;
404  }
405  }
406 
407  return ERROR_OK;
408 }
409 
410 static int remove_services(void)
411 {
412  struct service *c = services;
413 
414  /* loop service */
415  while (c) {
416  struct service *next = c->next;
417 
419  free_service(c);
420  /* remember the last service for unlinking */
421  c = next;
422  }
423 
424  services = NULL;
425 
426  return ERROR_OK;
427 }
428 
430 {
431  for (struct service *s = services; s; s = s->next)
432  if (s->keep_client_alive)
433  for (struct connection *c = s->connections; c; c = c->next)
434  s->keep_client_alive(c);
435 }
436 
438 {
439  struct service *service;
440 
441  bool poll_ok = true;
442 
443  /* used in select() */
444  fd_set read_fds;
445  int fd_max;
446 
447  /* used in accept() */
448  int retval;
449 
450  int64_t next_event = timeval_ms() + polling_period;
451 
452 #ifndef _WIN32
453  if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
454  LOG_ERROR("couldn't set SIGPIPE to SIG_IGN");
455 #endif
456 
458  /* monitor sockets for activity */
459  fd_max = 0;
460  FD_ZERO(&read_fds);
461 
462  /* add service and connection fds to read_fds */
463  for (service = services; service; service = service->next) {
464  if (service->fd != -1) {
465  /* listen for new connections */
466  OCD_FD_SET(service->fd, &read_fds);
467 
468  if (service->fd > fd_max)
469  fd_max = service->fd;
470  }
471 
472  if (service->connections) {
473  struct connection *c;
474 
475  for (c = service->connections; c; c = c->next) {
476  /* check for activity on the connection */
477  OCD_FD_SET(c->fd, &read_fds);
478  if (c->fd > fd_max)
479  fd_max = c->fd;
480  }
481  }
482  }
483 
484  struct timeval tv;
485  tv.tv_sec = 0;
486  if (poll_ok) {
487  /* we're just polling this iteration, this is faster on embedded
488  * hosts */
489  tv.tv_usec = 0;
490  retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
491  } else {
492  /* Timeout socket_select() when a target timer expires or every polling_period */
493  int timeout_ms = next_event - timeval_ms();
494  if (timeout_ms < 0)
495  timeout_ms = 0;
496  else if (timeout_ms > polling_period)
497  timeout_ms = polling_period;
498  tv.tv_usec = timeout_ms * 1000;
499  /* Only while we're sleeping we'll let others run */
500  retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
501  }
502 
503  if (retval == -1) {
504 #ifdef _WIN32
505 
506  errno = WSAGetLastError();
507 
508  if (errno == WSAEINTR)
509  FD_ZERO(&read_fds);
510  else {
511  LOG_ERROR("error during select: %s", strerror(errno));
513  openocd_exit_status_code = EXIT_FAILURE;
514  return;
515  }
516 #else
517 
518  if (errno == EINTR)
519  FD_ZERO(&read_fds);
520  else {
521  LOG_ERROR("error during select: %s", strerror(errno));
523  openocd_exit_status_code = EXIT_FAILURE;
524  return;
525  }
526 #endif
527  }
528 
529  if (retval == 0) {
530  /* Execute callbacks of expired timers when
531  * - there was nothing to do if poll_ok was true
532  * - socket_select() timed out if poll_ok was false, now one or more
533  * timers expired or the polling period elapsed
534  */
536  next_event = target_timer_next_event();
538 
539  FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case! */
540 
541  /* We timed out/there was nothing to do, timeout rather than poll next time
542  **/
543  poll_ok = false;
544  } else {
545  /* There was something to do, next time we'll just poll */
546  poll_ok = true;
547  }
548 
549  /* This is a simple back-off algorithm where we immediately
550  * re-poll if we did something this time around.
551  *
552  * This greatly improves performance of DCC.
553  */
554  poll_ok = poll_ok || target_got_message();
555 
556  for (service = services; service; service = service->next) {
557  /* handle new connections on listeners */
558  if ((service->fd != -1)
559  && (OCD_FD_ISSET(service->fd, &read_fds))) {
560  if (service->max_connections != 0)
562  else {
563  if (service->type == CONNECTION_TCP) {
564  struct sockaddr_in sin;
565  socklen_t address_size = sizeof(sin);
566  int tmp_fd;
567  tmp_fd = accept(service->fd,
568  (struct sockaddr *)&service->sin,
569  &address_size);
570  close_socket(tmp_fd);
571  }
572  LOG_INFO(
573  "rejected '%s' connection, no more connections allowed",
574  service->name);
575  }
576  }
577 
578  /* handle activity on connections */
579  if (service->connections) {
580  struct connection *c;
581 
582  for (c = service->connections; c; ) {
583  if ((c->fd >= 0 && OCD_FD_ISSET(c->fd, &read_fds)) || c->input_pending) {
584  retval = service->input(c);
585  if (retval != ERROR_OK) {
586  struct connection *next = c->next;
587  if (service->type == CONNECTION_PIPE ||
589  /* if connection uses a pipe then
590  * shutdown openocd on error */
592  }
594  LOG_INFO("dropped '%s' connection",
595  service->name);
596  c = next;
597  continue;
598  }
599  }
600  c = c->next;
601  }
602  }
603  }
604 
605 #ifdef _WIN32
606  MSG msg;
607  while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
608  if (msg.message == WM_QUIT)
610  }
611 #endif
612  }
613 
617 
618  /* when quit for signal or CTRL-C, run (eventually user implemented) "shutdown" */
620  command_run_line(command_context, "shutdown");
621 }
622 
624 {
626 }
627 
629 {
630  /* This value is only meaningful if the shutdown reason is signal.
631  * The caller should check the shutdown reason first. */
632  assert(server_terminated_by_signal());
633 
634  return last_signal;
635 }
636 
638 {
639  assert(!server_terminated_by_signal());
641 }
642 
643 static void sig_handler(int sig)
644 {
645  /* store only first signal that hits us */
648  last_signal = sig;
649  LOG_DEBUG("Terminating on Signal %d", sig);
650  } else
651  LOG_DEBUG("Ignored extra Signal %d", sig);
652 }
653 
654 
655 #ifdef _WIN32
656 BOOL WINAPI control_handler(DWORD ctrl_type)
657 {
659  return TRUE;
660 }
661 #else
662 static void sigkey_handler(int sig)
663 {
664  /* ignore keystroke generated signals if not in foreground process group */
665 
666  if (tcgetpgrp(STDIN_FILENO) > 0)
667  sig_handler(sig);
668  else
669  LOG_DEBUG("Ignored Signal %d", sig);
670 }
671 #endif
672 
673 
675 {
676  /* this currently only calls WSAStartup on native win32 systems
677  * before any socket operations are performed.
678  * This is an issue if you call init in your config script */
679 
680 #ifdef _WIN32
681  WORD version_requested;
682  WSADATA wsadata;
683 
684  version_requested = MAKEWORD(2, 2);
685 
686  if (WSAStartup(version_requested, &wsadata) != 0) {
687  LOG_ERROR("Failed to Open Winsock");
688  return ERROR_FAIL;
689  }
690 #endif
691  return ERROR_OK;
692 }
693 
695 {
696 #ifdef _WIN32
697  WSACleanup();
698 #endif
699  return ERROR_OK;
700 }
701 
702 int server_preinit(void)
703 {
704 #ifdef _WIN32
705  /* register ctrl-c handler */
706  SetConsoleCtrlHandler(control_handler, TRUE);
707 
708  signal(SIGBREAK, sig_handler);
709  signal(SIGINT, sig_handler);
710 #else
711  signal(SIGHUP, sig_handler);
712  signal(SIGPIPE, sig_handler);
713  signal(SIGQUIT, sigkey_handler);
714  signal(SIGINT, sigkey_handler);
715 #endif
716  signal(SIGTERM, sig_handler);
717  signal(SIGABRT, sig_handler);
718 
719  return ERROR_OK;
720 }
721 
723 {
724  int ret = tcl_init();
725 
726  if (ret != ERROR_OK)
727  return ret;
728 
729  ret = telnet_init("Open On-Chip Debugger");
730 
731  if (ret != ERROR_OK) {
732  remove_services();
733  return ret;
734  }
735 
736  return ERROR_OK;
737 }
738 
739 void server_quit(void)
740 {
741  remove_services();
742  target_quit();
743 
744 #ifdef _WIN32
745  SetConsoleCtrlHandler(control_handler, FALSE);
746 #endif
747 }
748 
749 void server_free(void)
750 {
755 
756  free(bindto_name);
757 }
758 
759 int exit_on_signal(int sig)
760 {
761 #ifndef _WIN32
762  // *nix: Bring back the default system handler and kill self
763  signal(sig, SIG_DFL);
764  kill(getpid(), sig); /* does not return */
765  __builtin_unreachable();
766 #else
767  // On Windows, simply use the signal number as the exit code
768  return sig;
769 #endif
770 }
771 
772 int connection_write(struct connection *connection, const void *data, int len)
773 {
774  if (len == 0) {
775  /* successful no-op. Sockets and pipes behave differently here... */
776  return 0;
777  }
779  return write_socket(connection->fd_out, data, len);
780  else
781  return write(connection->fd_out, data, len);
782 }
783 
784 int connection_read(struct connection *connection, void *data, int len)
785 {
787  return read_socket(connection->fd, data, len);
788  else
789  return read(connection->fd, data, len);
790 }
791 
793 {
795 }
796 
797 /* tell the server we want to shut down */
798 COMMAND_HANDLER(handle_shutdown_command)
799 {
800  if (CMD_ARGC > 1)
802 
803  LOG_USER("shutdown command invoked");
804 
805  if (CMD_ARGC == 0) {
806  /* When "shutdown" (without parameters) is auto-executed
807  * as a result of a signal, keep the alredy-set shutdown reason
808  * unchanged. */
810  // Default exit code is zero (success)
813  }
814  } else {
815  uint8_t code;
816  if (strcmp(CMD_ARGV[0], "error") == 0) {
817  /* "shutdown error" is a synonym of "shutdown 1"
818  * for backward compatibility. */
819  code = 1;
820  } else {
821  COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], code);
822  }
823 
826  }
827 
828  command_run_line(CMD_CTX, "_run_pre_shutdown_commands");
829 
831 }
832 
833 COMMAND_HANDLER(handle_exit_command)
834 {
837  LOG_WARNING("DEPRECATED: 'exit' should only be used in telnet or Tcl "
838  "sessions to close the session");
839  LOG_WARNING("Did you mean 'shutdown'?");
840  return command_run_line(CMD_CTX, "shutdown");
841  }
842 
843  if (CMD_ARGC != 0)
845 
846  /* Disconnect telnet / Tcl session */
848 }
849 
850 COMMAND_HANDLER(handle_poll_period_command)
851 {
852  if (CMD_ARGC == 0)
853  LOG_WARNING("You need to set a period value");
854  else
856 
857  LOG_INFO("set servers polling period to %ums", polling_period);
858 
859  return ERROR_OK;
860 }
861 
862 COMMAND_HANDLER(handle_bindto_command)
863 {
864  switch (CMD_ARGC) {
865  case 0:
866  command_print(CMD, "bindto name: %s", bindto_name);
867  break;
868  case 1:
869  free(bindto_name);
870  bindto_name = strdup(CMD_ARGV[0]);
871  break;
872  default:
874  }
875  return ERROR_OK;
876 }
877 
878 COMMAND_HANDLER(handle_services_command)
879 {
880  if (CMD_ARGC != 0)
882 
883  for (const struct service *s = services; s; s = s->next) {
884  command_print(CMD, "{");
885 
886  /* Escape the name in case it contains special characters. */
887  char *escaped_name = tcl_escape_alloc(CMD_CTX->interp, s->name);
888  if (!escaped_name) {
889  command_print(CMD, "Unable to escape Tcl string");
890  return ERROR_FAIL;
891  }
892  command_print(CMD, " name %s", escaped_name);
893  free(escaped_name);
894 
895  struct sockaddr_in addr_in;
896  addr_in.sin_port = 0;
897  socklen_t addr_in_size = sizeof(addr_in);
898  /* If it's a TCP connection and they specified port 0 try to get the real port. */
899  if (s->type == CONNECTION_TCP &&
900  s->portnumber == 0 &&
901  getsockname(s->fd, (struct sockaddr *)&addr_in, &addr_in_size) == 0) {
902  command_print(CMD, " port %hu", ntohs(addr_in.sin_port));
903  } else {
904  /* Need to escape port because it could be a FIFO path which is
905  * allowed to contain basically any character. */
906  char *escaped_port = tcl_escape_alloc(CMD_CTX->interp, s->port);
907  if (!escaped_port) {
908  command_print(CMD, "Unable to escape Tcl string");
909  return ERROR_FAIL;
910  }
911  command_print(CMD, " port %s", escaped_port);
912  free(escaped_port);
913  }
914 
915  if (s->service_info)
916  CALL_COMMAND_HANDLER(s->service_info, s);
917 
918  command_print(CMD, "}");
919  }
920  return ERROR_OK;
921 }
922 
923 static const struct command_registration server_command_handlers[] = {
924  {
925  .name = "shutdown",
926  .handler = &handle_shutdown_command,
927  .mode = COMMAND_ANY,
928  .usage = "['error'|exit_code]",
929  .help = "shut down OpenOCD process",
930  },
931  {
932  .name = "exit",
933  .handler = &handle_exit_command,
934  .mode = COMMAND_ANY,
935  .usage = "",
936  .help = "exit (disconnect) telnet or Tcl session",
937  },
938  {
939  .name = "poll_period",
940  .handler = &handle_poll_period_command,
941  .mode = COMMAND_ANY,
942  .usage = "",
943  .help = "set the servers polling period",
944  },
945  {
946  .name = "bindto",
947  .handler = &handle_bindto_command,
948  .mode = COMMAND_CONFIG,
949  .usage = "[name]",
950  .help = "Specify address by name on which to listen for "
951  "incoming TCP/IP connections",
952  },
953  {
954  .name = "services",
955  .handler = &handle_services_command,
956  .mode = COMMAND_ANY,
957  .usage = "",
958  .help = "return information about running services"
959  },
961 };
962 
964 {
965  int retval = telnet_register_commands(cmd_ctx);
966  if (retval != ERROR_OK)
967  return retval;
968 
969  retval = tcl_register_commands(cmd_ctx);
970  if (retval != ERROR_OK)
971  return retval;
972 
973  retval = jsp_register_commands(cmd_ctx);
974  if (retval != ERROR_OK)
975  return retval;
976 
978 }
979 
980 COMMAND_HELPER(server_port_command, unsigned short *out)
981 {
982  switch (CMD_ARGC) {
983  case 0:
984  command_print(CMD, "%d", *out);
985  break;
986  case 1:
987  {
988  uint16_t port;
989  COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);
990  *out = port;
991  break;
992  }
993  default:
995  }
996  return ERROR_OK;
997 }
998 
999 COMMAND_HELPER(server_pipe_command, char **out)
1000 {
1001  switch (CMD_ARGC) {
1002  case 0:
1003  command_print(CMD, "%s", *out);
1004  break;
1005  case 1:
1006  {
1007  if (CMD_CTX->mode == COMMAND_EXEC) {
1008  LOG_WARNING("unable to change server port after init");
1010  }
1011  free(*out);
1012  *out = strdup(CMD_ARGV[0]);
1013  break;
1014  }
1015  default:
1017  }
1018  return ERROR_OK;
1019 }
#define MSG
Definition: arm_tpiu_swo.c:43
const char * name
Definition: armv4_5.c:75
void command_done(struct command_context *cmd_ctx)
Frees the resources associated with a command context.
Definition: command.c:584
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:389
void process_jim_events(struct command_context *cmd_ctx)
Definition: command.c:1221
struct command_context * copy_command_context(struct command_context *context)
Creates a copy of an existing command context.
Definition: command.c:575
int command_run_line(struct command_context *context, char *line)
Definition: command.c:497
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:146
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:123
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:161
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:405
#define ERROR_COMMAND_CLOSE_CONNECTION
Definition: command.h:404
int parse_long(const char *str, long *ul)
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:156
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
Definition: command.h:445
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:151
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
#define ERROR_COMMAND_ARGUMENT_INVALID
Definition: command.h:407
static int register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds)
Register one or more commands in the specified context, as children of parent (or top-level commends,...
Definition: command.h:277
@ COMMAND_CONFIG
Definition: command.h:41
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_EXEC
Definition: command.h:40
static struct esp_usb_jtag * priv
Definition: esp_usb_jtag.c:219
int ipdbg_server_free(void)
Definition: ipdbg.c:778
void jsp_service_free(void)
Definition: jsp_server.c:236
int jsp_register_commands(struct command_context *cmd_ctx)
Definition: jsp_server.c:230
char * alloc_printf(const char *format,...)
Definition: log.c:386
#define LOG_USER(expr ...)
Definition: log.h:150
#define LOG_WARNING(expr ...)
Definition: log.h:144
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_INFO(expr ...)
Definition: log.h:141
#define LOG_DEBUG(expr ...)
Definition: log.h:124
#define ERROR_OK
Definition: log.h:182
int flag
Definition: mips64.c:29
static int socket_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
Definition: replacements.h:214
static int read_socket(int handle, void *buffer, unsigned int count)
Definition: replacements.h:174
static int close_socket(int sock)
Definition: replacements.h:183
#define OCD_FD_SET(fd, set)
Definition: replacements.h:159
static int write_socket(int handle, const void *buffer, unsigned int count)
Definition: replacements.h:165
#define OCD_FD_ISSET(fd, set)
Definition: replacements.h:161
static void socket_nonblock(int fd)
Definition: replacements.h:203
int connection_write(struct connection *connection, const void *data, int len)
Definition: server.c:772
int server_get_last_signal_number(void)
Definition: server.c:628
int server_preinit(void)
Definition: server.c:702
static volatile sig_atomic_t shutdown_openocd
Definition: server.c:48
static void sig_handler(int sig)
Definition: server.c:643
int connection_read(struct connection *connection, void *data, int len)
Definition: server.c:784
uint8_t server_get_exit_status_code(void)
Definition: server.c:637
static void free_service(struct service *c)
Definition: server.c:197
int server_host_os_close(void)
Definition: server.c:694
static char * bindto_name
Definition: server.c:60
void server_free(void)
Definition: server.c:749
static const struct command_registration server_command_handlers[]
Definition: server.c:923
static uint8_t openocd_exit_status_code
Definition: server.c:54
bool server_terminated_by_signal(void)
Definition: server.c:623
int server_host_os_entry(void)
Definition: server.c:674
COMMAND_HANDLER(handle_shutdown_command)
Definition: server.c:798
static void remove_connections(struct service *service)
Definition: server.c:367
static int remove_services(void)
Definition: server.c:410
int exit_on_signal(int sig)
Definition: server.c:759
static int remove_connection(struct service *service, struct connection *connection)
Definition: server.c:161
void server_keep_clients_alive(void)
Definition: server.c:429
shutdown_reason
Definition: server.c:39
@ SHUTDOWN_REQUESTED
Definition: server.c:41
@ SHUTDOWN_WITH_ERROR_CODE
Definition: server.c:42
@ CONTINUE_MAIN_LOOP
Definition: server.c:40
@ SHUTDOWN_WITH_SIGNAL_CODE
Definition: server.c:43
bool openocd_is_shutdown_pending(void)
Definition: server.c:792
int remove_service(const char *name, const char *port)
Definition: server.c:382
void server_loop(struct command_context *command_context)
Definition: server.c:437
static int add_connection(struct service *service, struct command_context *cmd_ctx)
Definition: server.c:62
static volatile sig_atomic_t last_signal
Definition: server.c:51
int server_register_commands(struct command_context *cmd_ctx)
Definition: server.c:963
static struct service * services
Definition: server.c:46
COMMAND_HELPER(server_port_command, unsigned short *out)
Definition: server.c:980
int add_service(const struct service_driver *driver, const char *port, int max_connections, void *priv)
Definition: server.c:211
int server_init(struct command_context *cmd_ctx)
Definition: server.c:722
static void sigkey_handler(int sig)
Definition: server.c:662
void server_quit(void)
Definition: server.c:739
static int polling_period
Definition: server.c:57
#define CONNECTION_LIMIT_UNLIMITED
Definition: server.h:34
@ CONNECTION_PIPE
Definition: server.h:30
@ CONNECTION_STDINOUT
Definition: server.h:31
@ CONNECTION_TCP
Definition: server.h:29
const char * name
Definition: command.h:239
struct sockaddr_in sin
Definition: server.h:39
struct command_context * cmd_ctx
Definition: server.h:40
void * priv
Definition: server.h:43
int fd_out
Definition: server.h:38
int fd
Definition: server.h:37
struct service * service
Definition: server.h:41
struct connection * next
Definition: server.h:44
bool input_pending
Definition: server.h:42
void(* service_dtor_handler)(struct service *service)
Definition: server.h:61
const char * name
the name of the server
Definition: server.h:49
int(* connection_closed_handler)(struct connection *connection)
callback to tear down the connection
Definition: server.h:65
void(* keep_client_alive_handler)(struct connection *connection)
called periodically to send keep-alive messages on the connection
Definition: server.h:67
int(* new_connection_handler)(struct connection *connection)
complete code to accept a new connection.
Definition: server.h:58
int(* new_connection_during_keep_alive_handler)(struct connection *connection)
optional minimal setup to accept a connection during keep-alive
Definition: server.h:51
int(* input_handler)(struct connection *connection)
callback to handle incoming data
Definition: server.h:60
Definition: server.h:70
struct service * next
Definition: server.h:92
int fd
Definition: server.h:80
void(* service_dtor)(struct service *service)
Definition: server.h:87
void * priv
Definition: server.h:91
int max_connections
Definition: server.h:82
int(* new_connection_during_keep_alive)(struct connection *connection)
Definition: server.h:84
struct sockaddr_in sin
Definition: server.h:81
struct connection * connections
Definition: server.h:83
int(* input)(struct connection *connection)
Definition: server.h:86
char * name
Definition: server.h:71
char * port
The 'port', which can be an integer for TCP, or 'disabled', 'pipe' (stdin/out) or a FIFO path.
Definition: server.h:77
int(* connection_closed)(struct connection *connection)
Definition: server.h:89
unsigned short portnumber
If port is an integer it is parsed and saved here.
Definition: server.h:79
void(* keep_client_alive)(struct connection *connection)
Definition: server.h:90
enum connection_type type
Definition: server.h:72
int(* new_connection)(struct connection *connection)
Definition: server.h:85
Definition: ftdi.c:132
long tv_sec
Definition: replacements.h:46
long tv_usec
Definition: replacements.h:47
int target_call_timer_callbacks(void)
Definition: target.c:1930
int64_t target_timer_next_event(void)
Returns when the next registered event will take place.
Definition: target.c:1941
void target_quit(void)
Free all the resources allocated by targets and the target layer.
Definition: target.c:2285
bool target_got_message(void)
Read and clear the flag as to whether we got a message.
char * tcl_escape_alloc(Jim_Interp *interp, const char *s)
Convert a C string to a string that can be used for Tcl list.
Definition: tcl-libjim.c:25
int tcl_register_commands(struct command_context *cmd_ctx)
Definition: tcl_server.c:383
void tcl_service_free(void)
Definition: tcl_server.c:389
int tcl_init(void)
Definition: tcl_server.c:287
bool tcl_is_from_tcl_session(struct command_context *cmd_ctx)
Definition: tcl_server.c:297
void telnet_service_free(void)
int telnet_register_commands(struct command_context *cmd_ctx)
int telnet_init(char *banner)
bool telnet_is_from_telnet_session(struct command_context *cmd_ctx)
int64_t timeval_ms(void)
#define NULL
Definition: usb.h:16
#define WORD
Definition: x86_32_common.h:32
#define DWORD
Definition: x86_32_common.h:33