34 #include <netinet/tcp.h>
58 socklen_t address_size;
66 memset(&c->
sin, 0,
sizeof(c->
sin));
74 address_size =
sizeof(c->
sin);
101 c->
fd_out = fileno(stdout);
105 SetConsoleCtrlHandler(
NULL, TRUE);
125 c->
fd_out = open(out_file, O_WRONLY);
198 int max_connections,
void *
priv)
202 int so_reuseaddr_option = 1;
204 c = malloc(
sizeof(
struct service));
207 c->
port = strdup(port);
219 if (strcmp(c->
port,
"pipe") == 0)
223 portnumber = strtol(c->
port, &end, 0);
234 c->
fd = socket(AF_INET, SOCK_STREAM, 0);
236 LOG_ERROR(
"error creating socket: %s", strerror(errno));
244 (
void *)&so_reuseaddr_option,
249 memset(&c->
sin, 0,
sizeof(c->
sin));
250 c->
sin.sin_family = AF_INET;
253 c->
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
262 memcpy(&c->
sin.sin_addr, hp->h_addr_list[0], hp->h_length);
266 if (bind(c->
fd, (
struct sockaddr *)&c->
sin,
sizeof(c->
sin)) == -1) {
275 setsockopt(c->
fd, IPPROTO_TCP, TCP_MAXSEG, &segsize,
sizeof(
int));
277 int window_size = 128 * 1024;
281 setsockopt(c->
fd, SOL_SOCKET, SO_SNDBUF,
282 (
char *)&window_size,
sizeof(window_size));
283 setsockopt(c->
fd, SOL_SOCKET, SO_RCVBUF,
284 (
char *)&window_size,
sizeof(window_size));
286 if (listen(c->
fd, 1) == -1) {
287 LOG_ERROR(
"couldn't listen on socket: %s", strerror(errno));
293 struct sockaddr_in addr_in;
294 addr_in.sin_port = 0;
295 socklen_t addr_in_size =
sizeof(addr_in);
296 if (getsockname(c->
fd, (
struct sockaddr *)&addr_in, &addr_in_size) == 0)
297 LOG_INFO(
"Listening on port %hu for %s connections",
298 ntohs(addr_in.sin_port), c->
name);
300 c->
fd = fileno(stdin);
304 if (_setmode(_fileno(stdout), _O_BINARY) < 0)
305 LOG_WARNING(
"cannot change stdout mode to binary");
306 if (_setmode(_fileno(stdin), _O_BINARY) < 0)
308 if (_setmode(_fileno(stderr), _O_BINARY) < 0)
309 LOG_WARNING(
"cannot change stderr mode to binary");
317 LOG_ERROR(
"Named pipes currently not supported under this os");
322 c->
fd = open(c->
port, O_RDONLY | O_NONBLOCK);
361 for (tmp =
services; tmp; prev = tmp, tmp = tmp->
next) {
416 if (s->keep_client_alive)
418 s->keep_client_alive(c);
437 if (
signal(SIGPIPE, SIG_IGN) == SIG_ERR)
438 LOG_ERROR(
"couldn't set SIGPIPE to SIG_IGN");
461 FD_SET(c->
fd, &read_fds);
482 tv.
tv_usec = timeout_ms * 1000;
490 errno = WSAGetLastError();
492 if (errno == WSAEINTR)
495 LOG_ERROR(
"error during select: %s", strerror(errno));
503 LOG_ERROR(
"error during select: %s", strerror(errno));
544 struct sockaddr_in sin;
545 socklen_t address_size =
sizeof(sin);
553 "rejected '%s' connection, no more connections allowed",
587 while (PeekMessage(&msg,
NULL, 0, 0, PM_REMOVE)) {
588 if (msg.message == WM_QUIT)
607 LOG_DEBUG(
"Terminating on Signal %d", sig);
609 LOG_DEBUG(
"Ignored extra Signal %d", sig);
614 BOOL WINAPI control_handler(
DWORD ctrl_type)
624 if (tcgetpgrp(STDIN_FILENO) > 0)
639 WORD version_requested;
642 version_requested = MAKEWORD(2, 2);
644 if (WSAStartup(version_requested, &wsadata) != 0) {
664 SetConsoleCtrlHandler(control_handler, TRUE);
703 SetConsoleCtrlHandler(control_handler, FALSE);
758 LOG_USER(
"shutdown command invoked");
765 if (!strcmp(
CMD_ARGV[0],
"error")) {
805 .handler = &handle_shutdown_command,
808 .help =
"shut the server down",
811 .name =
"poll_period",
812 .handler = &handle_poll_period_command,
815 .help =
"set the servers polling period",
819 .handler = &handle_bindto_command,
822 .help =
"Specify address by name on which to listen for "
823 "incoming TCP/IP connections",
873 LOG_WARNING(
"unable to change server port after init");
void command_done(struct command_context *cmd_ctx)
Frees the resources associated with a command context.
void command_print(struct command_invocation *cmd, const char *format,...)
void process_jim_events(struct command_context *cmd_ctx)
struct command_context * copy_command_context(struct command_context *context)
Creates a copy of an existing command context.
int command_run_line(struct command_context *context, char *line)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define ERROR_COMMAND_CLOSE_CONNECTION
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...
#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...
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
#define ERROR_COMMAND_ARGUMENT_INVALID
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,...
static struct esp_usb_jtag * priv
void jsp_service_free(void)
int jsp_register_commands(struct command_context *cmd_ctx)
char * alloc_printf(const char *format,...)
#define LOG_USER(expr ...)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
static int socket_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
static int read_socket(int handle, void *buffer, unsigned int count)
static int close_socket(int sock)
static int write_socket(int handle, const void *buffer, unsigned int count)
static void socket_nonblock(int fd)
void exit_on_signal(int sig)
int connection_write(struct connection *connection, const void *data, int len)
static void sig_handler(int sig)
int connection_read(struct connection *connection, void *data, int len)
static void free_service(struct service *c)
int server_host_os_close(void)
static char * bindto_name
static const struct command_registration server_command_handlers[]
int server_host_os_entry(void)
COMMAND_HANDLER(handle_shutdown_command)
static void remove_connections(struct service *service)
static enum shutdown_reason shutdown_openocd
static int remove_services(void)
static int remove_connection(struct service *service, struct connection *connection)
void server_keep_clients_alive(void)
@ SHUTDOWN_WITH_ERROR_CODE
@ SHUTDOWN_WITH_SIGNAL_CODE
bool openocd_is_shutdown_pending(void)
int server_loop(struct command_context *command_context)
int remove_service(const char *name, const char *port)
static int add_connection(struct service *service, struct command_context *cmd_ctx)
int server_register_commands(struct command_context *cmd_ctx)
static struct service * services
COMMAND_HELPER(server_port_command, unsigned short *out)
int add_service(const struct service_driver *driver, const char *port, int max_connections, void *priv)
int server_init(struct command_context *cmd_ctx)
static void sigkey_handler(int sig)
static int polling_period
#define CONNECTION_LIMIT_UNLIMITED
struct command_context * cmd_ctx
const char * name
the name of the server
int(* connection_closed_handler)(struct connection *connection)
callback to tear down the connection
void(* keep_client_alive_handler)(struct connection *connection)
called periodically to send keep-alive messages on the connection
int(* new_connection_handler)(struct connection *connection)
complete code to accept a new connection.
int(* new_connection_during_keep_alive_handler)(struct connection *connection)
optional minimal setup to accept a connection during keep-alive
int(* input_handler)(struct connection *connection)
callback to handle incoming data
int(* new_connection_during_keep_alive)(struct connection *connection)
struct connection * connections
int(* input)(struct connection *connection)
int(* connection_closed)(struct connection *connection)
unsigned short portnumber
void(* keep_client_alive)(struct connection *connection)
enum connection_type type
int(* new_connection)(struct connection *connection)
int target_call_timer_callbacks()
int64_t target_timer_next_event(void)
Returns when the next registered event will take place.
void target_quit(void)
Free all the resources allocated by targets and the target layer.
bool target_got_message(void)
Read and clear the flag as to whether we got a message.
int tcl_register_commands(struct command_context *cmd_ctx)
void tcl_service_free(void)
void telnet_service_free(void)
int telnet_register_commands(struct command_context *cmd_ctx)
int telnet_init(char *banner)