summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2015-01-22 01:46:02 +0100
committerGravatar Nikias Bassen2015-01-22 01:46:02 +0100
commita6ea54ec581470ed70c98c86b1619f9defca8b7e (patch)
tree2c30a554df06ee7c66395473b460c78f1591fee0
parent9c0e7ef16439b216f230341399275f15e9d0bfdf (diff)
downloadlibimobiledevice-a6ea54ec581470ed70c98c86b1619f9defca8b7e.tar.gz
libimobiledevice-a6ea54ec581470ed70c98c86b1619f9defca8b7e.tar.bz2
idevicedebugserverproxy: Properly handle server shutdown
-rw-r--r--tools/idevicedebugserverproxy.c120
1 files changed, 75 insertions, 45 deletions
diff --git a/tools/idevicedebugserverproxy.c b/tools/idevicedebugserverproxy.c
index 2209abc..fc1ead9 100644
--- a/tools/idevicedebugserverproxy.c
+++ b/tools/idevicedebugserverproxy.c
@@ -38,33 +38,25 @@ static int debug_mode = 0;
static int quit_flag = 0;
typedef struct {
- int server_fd;
int client_fd;
- uint16_t local_port;
idevice_t device;
debugserver_client_t debugserver_client;
volatile int stop_ctod;
volatile int stop_dtoc;
} socket_info_t;
-static socket_info_t global_socket_info;
+struct thread_info {
+ thread_t th;
+ struct thread_info *next;
+};
+
+typedef struct thread_info thread_info_t;
+
static void clean_exit(int sig)
{
- if (quit_flag == 0)
- fprintf(stderr, "Setting quit status. Cancel again to quit server.\n");
- else
- fprintf(stderr, "Exiting...\n");
-
+ fprintf(stderr, "Exiting...\n");
quit_flag++;
-
- /* shutdown server socket if we have to terminate to unblock the server loop */
- if (quit_flag > 1) {
- if (global_socket_info.server_fd > 0) {
- socket_shutdown(global_socket_info.server_fd, SHUT_RDWR);
- socket_close(global_socket_info.server_fd);
- }
- }
}
static void print_usage(int argc, char **argv)
@@ -83,7 +75,7 @@ static void print_usage(int argc, char **argv)
static void *thread_device_to_client(void *data)
{
socket_info_t* socket_info = (socket_info_t*)data;
- idevice_error_t res = IDEVICE_E_UNKNOWN_ERROR;
+ debugserver_error_t res = DEBUGSERVER_E_UNKNOWN_ERROR;
int recv_len;
int sent;
@@ -92,15 +84,14 @@ static void *thread_device_to_client(void *data)
debug("%s: started thread...\n", __func__);
debug("%s: client_fd = %d\n", __func__, socket_info->client_fd);
- debug("%s: server fd = %d\n", __func__, socket_info->server_fd);
- while (!quit_flag && !socket_info->stop_dtoc && socket_info->client_fd > 0 && socket_info->server_fd > 0) {
+ while (!quit_flag && !socket_info->stop_dtoc && socket_info->client_fd > 0) {
debug("%s: receiving data from device...\n", __func__);
res = debugserver_client_receive_with_timeout(socket_info->debugserver_client, buffer, sizeof(buffer), (uint32_t*)&recv_len, 5000);
if (recv_len <= 0) {
- if (recv_len == 0 && res == IDEVICE_E_SUCCESS) {
+ if (recv_len == 0 && res == DEBUGSERVER_E_SUCCESS) {
// try again
continue;
} else {
@@ -139,7 +130,7 @@ static void *thread_device_to_client(void *data)
static void *thread_client_to_device(void *data)
{
socket_info_t* socket_info = (socket_info_t*)data;
- idevice_error_t res = IDEVICE_E_UNKNOWN_ERROR;
+ debugserver_error_t res = DEBUGSERVER_E_UNKNOWN_ERROR;
int recv_len;
int sent;
@@ -149,7 +140,6 @@ static void *thread_client_to_device(void *data)
debug("%s: started thread...\n", __func__);
debug("%s: client_fd = %d\n", __func__, socket_info->client_fd);
- debug("%s: server_fd = %d\n", __func__, socket_info->server_fd);
/* spawn server to client thread */
socket_info->stop_dtoc = 0;
@@ -157,7 +147,7 @@ static void *thread_client_to_device(void *data)
fprintf(stderr, "Failed to start device to client thread...\n");
}
- while (!quit_flag && !socket_info->stop_ctod && socket_info->client_fd > 0 && socket_info->server_fd > 0) {
+ while (!quit_flag && !socket_info->stop_ctod && socket_info->client_fd > 0) {
debug("%s: receiving data from client...\n", __func__);
/* attempt to read incoming data from client */
@@ -177,7 +167,7 @@ static void *thread_client_to_device(void *data)
debug("%s: sending data to device...\n", __func__);
res = debugserver_client_send(socket_info->debugserver_client, buffer, recv_len, (uint32_t*)&sent);
- if (sent < recv_len || res != IDEVICE_E_SUCCESS) {
+ if (sent < recv_len || res != DEBUGSERVER_E_SUCCESS) {
if (sent <= 0) {
fprintf(stderr, "send failed: %s\n", strerror(errno));
break;
@@ -245,18 +235,34 @@ static void* connection_handler(void* data)
int main(int argc, char *argv[])
{
idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
- thread_t th;
+ idevice_t device = NULL;
+ thread_info_t *thread_list = NULL;
const char* udid = NULL;
uint16_t local_port = 0;
+ int server_fd;
int result = EXIT_SUCCESS;
int i;
+#ifndef WIN32
+ struct sigaction sa;
+ struct sigaction si;
+ memset(&sa, '\0', sizeof(struct sigaction));
+ memset(&si, '\0', sizeof(struct sigaction));
+
+ sa.sa_handler = clean_exit;
+ sigemptyset(&sa.sa_mask);
+
+ si.sa_handler = SIG_IGN;
+ sigemptyset(&si.sa_mask);
+
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGQUIT, &sa, NULL);
+ sigaction(SIGPIPE, &si, NULL);
+#else
/* bind signals */
signal(SIGINT, clean_exit);
signal(SIGTERM, clean_exit);
-#ifndef WIN32
- signal(SIGQUIT, clean_exit);
- signal(SIGPIPE, SIG_IGN);
#endif
/* parse cmdline arguments */
@@ -297,11 +303,8 @@ int main(int argc, char *argv[])
goto leave_cleanup;
}
- /* setup and create socket endpoint */
- global_socket_info.local_port = local_port;
-
/* start services and connect to device */
- ret = idevice_new(&global_socket_info.device, udid);
+ ret = idevice_new(&device, udid);
if (ret != IDEVICE_E_SUCCESS) {
if (udid) {
fprintf(stderr, "No device found with udid %s, is it plugged in?\n", udid);
@@ -313,40 +316,67 @@ int main(int argc, char *argv[])
}
/* create local socket */
- global_socket_info.server_fd = socket_create(global_socket_info.local_port);
- if (global_socket_info.server_fd < 0) {
+ server_fd = socket_create(local_port);
+ if (server_fd < 0) {
fprintf(stderr, "Could not create socket\n");
result = EXIT_FAILURE;
goto leave_cleanup;
}
while (!quit_flag) {
- debug("%s: Waiting for connection on local port %d\n", __func__, global_socket_info.local_port);
+ debug("%s: Waiting for connection on local port %d\n", __func__, local_port);
/* wait for client */
- global_socket_info.client_fd = socket_accept(global_socket_info.server_fd, global_socket_info.local_port);
- if (global_socket_info.client_fd < 0) {
+ int client_fd = socket_accept(server_fd, local_port);
+ if (client_fd < 0) {
continue;
}
debug("%s: Handling new client connection...\n", __func__);
- if (thread_new(&th, connection_handler, (void*)&global_socket_info) != 0) {
+ thread_info_t *el = (thread_info_t*)malloc(sizeof(thread_info_t));
+ if (!el) {
+ fprintf(stderr, "Out of memory\n");
+ exit(EXIT_FAILURE);
+ }
+ el->next = NULL;
+
+ if (thread_list) {
+ thread_list->next = el;
+ } else {
+ thread_list = el;
+ }
+
+ socket_info_t *sinfo = (socket_info_t*)malloc(sizeof(socket_info_t));
+ if (!sinfo) {
+ fprintf(stderr, "Out of memory\n");
+ exit(EXIT_FAILURE);
+ }
+ sinfo->client_fd = client_fd;
+ sinfo->device = device;
+
+ if (thread_new(&(el->th), connection_handler, (void*)sinfo) != 0) {
fprintf(stderr, "Could not start connection handler.\n");
- socket_shutdown(global_socket_info.server_fd, SHUT_RDWR);
- socket_close(global_socket_info.server_fd);
+ socket_shutdown(server_fd, SHUT_RDWR);
+ socket_close(server_fd);
continue;
}
-
- /* we do not need it anymore */
- thread_free(th);
}
debug("%s: Shutting down debugserver proxy...\n", __func__);
+ /* join and clean up threads */
+ while (thread_list) {
+ thread_info_t *el = thread_list;
+ thread_join(el->th);
+ thread_free(el->th);
+ thread_list = el->next;
+ free(el);
+ }
+
leave_cleanup:
- if (global_socket_info.device) {
- idevice_free(global_socket_info.device);
+ if (device) {
+ idevice_free(device);
}
return result;