free(out_file);
if (c->fd_out == -1) {
LOG_ERROR("could not open %s", service->port);
- exit(1);
+ command_done(c->cmd_ctx);
+ free(c);
+ return ERROR_FAIL;
}
LOG_INFO("accepting '%s' connection from pipe %s", service->name, service->port);
return ERROR_OK;
}
-/* FIX! make service return error instead of invoking exit() */
+static void free_service(struct service *c)
+{
+ free(c->name);
+ free(c->port);
+ free(c);
+}
+
int add_service(char *name,
const char *port,
int max_connections,
c->fd = socket(AF_INET, SOCK_STREAM, 0);
if (c->fd == -1) {
LOG_ERROR("error creating socket: %s", strerror(errno));
- exit(-1);
+ free_service(c);
+ return ERROR_FAIL;
}
setsockopt(c->fd,
hp = gethostbyname(bindto_name);
if (hp == NULL) {
LOG_ERROR("couldn't resolve bindto address: %s", bindto_name);
- exit(-1);
+ close_socket(c->fd);
+ free_service(c);
+ return ERROR_FAIL;
}
memcpy(&c->sin.sin_addr, hp->h_addr_list[0], hp->h_length);
}
c->sin.sin_port = htons(c->portnumber);
if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
- LOG_ERROR("couldn't bind %s to socket: %s", name, strerror(errno));
- exit(-1);
+ LOG_ERROR("couldn't bind %s to socket on port %d: %s", name, c->portnumber, strerror(errno));
+ close_socket(c->fd);
+ free_service(c);
+ return ERROR_FAIL;
}
#ifndef _WIN32
if (listen(c->fd, 1) == -1) {
LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
- exit(-1);
+ close_socket(c->fd);
+ free_service(c);
+ return ERROR_FAIL;
}
+
+ struct sockaddr_in addr_in;
+ addr_in.sin_port = 0;
+ socklen_t addr_in_size = sizeof(addr_in);
+ if (getsockname(c->fd, (struct sockaddr *)&addr_in, &addr_in_size) == 0)
+ LOG_INFO("Listening on port %hu for %s connections",
+ ntohs(addr_in.sin_port), name);
} else if (c->type == CONNECTION_STDINOUT) {
c->fd = fileno(stdin);
/* we currenty do not support named pipes under win32
* so exit openocd for now */
LOG_ERROR("Named pipes currently not supported under this os");
- exit(1);
+ free_service(c);
+ return ERROR_FAIL;
#else
/* Pipe we're reading from */
c->fd = open(c->port, O_RDONLY | O_NONBLOCK);
if (c->fd == -1) {
LOG_ERROR("could not open %s", c->port);
- exit(1);
+ free_service(c);
+ return ERROR_FAIL;
}
#endif
}
return ERROR_OK;
}
+static void remove_connections(struct service *service)
+{
+ struct connection *connection;
+
+ connection = service->connections;
+
+ while (connection) {
+ struct connection *tmp;
+
+ tmp = connection->next;
+ remove_connection(service, connection);
+ connection = tmp;
+ }
+}
+
static int remove_services(void)
{
struct service *c = services;
while (c) {
struct service *next = c->next;
+ remove_connections(c);
+
if (c->name)
free(c->name);
FD_ZERO(&read_fds);
else {
LOG_ERROR("error during select: %s", strerror(errno));
- exit(-1);
+ return ERROR_FAIL;
}
#else
FD_ZERO(&read_fds);
else {
LOG_ERROR("error during select: %s", strerror(errno));
- exit(-1);
+ return ERROR_FAIL;
}
#endif
}
if (WSAStartup(wVersionRequested, &wsaData) != 0) {
LOG_ERROR("Failed to Open Winsock");
- exit(-1);
+ return ERROR_FAIL;
}
/* register ctrl-c handler */
int server_init(struct command_context *cmd_ctx)
{
int ret = tcl_init();
- if (ERROR_OK != ret)
+
+ if (ret != ERROR_OK)
return ret;
- return telnet_init("Open On-Chip Debugger");
+ ret = telnet_init("Open On-Chip Debugger");
+
+ if (ret != ERROR_OK) {
+ remove_services();
+ return ret;
+ }
+
+ return ERROR_OK;
}
int server_quit(void)
return last_signal;
}
+void server_free(void)
+{
+ tcl_service_free();
+ telnet_service_free();
+ jsp_service_free();
+}
+
void exit_on_signal(int sig)
{
#ifndef _WIN32