From b5a7434997c4668cc66b3e6a9527bd3922cf6f0d Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Thu, 28 Feb 2013 11:04:17 +0100 Subject: idevicesyslog: use events to allow automatic reconnect to device --- tools/idevicesyslog.c | 178 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 147 insertions(+), 31 deletions(-) (limited to 'tools') diff --git a/tools/idevicesyslog.c b/tools/idevicesyslog.c index 44c8246..d7e7463 100644 --- a/tools/idevicesyslog.c +++ b/tools/idevicesyslog.c @@ -24,6 +24,14 @@ #include #include #include +#include + +#ifdef WIN32 +#include +#define sleep(x) Sleep(x*1000) +#else +#include +#endif #include #include @@ -34,21 +42,137 @@ static int quit_flag = 0; void print_usage(int argc, char **argv); +static char* udid = NULL; + +static idevice_t device = NULL; +static service_client_t syslog = NULL; + +#ifdef WIN32 +HANDLE worker = NULL; +#else +pthread_t worker; +#endif + +static int logging = 0; + +static void *syslog_worker(void *arg) +{ + service_error_t ret = SERVICE_E_UNKNOWN_ERROR; + + fprintf(stdout, "[connected]\n"); + fflush(stdout); + + logging = 1; + + while (logging) { + char c; + uint32_t bytes = 0; + ret = service_receive_with_timeout(syslog, &c, 1, &bytes, 0); + if (ret < 0 || (bytes != 1)) { + printf("\n[connection interrupted]\n"); + fflush(stdout); + break; + } + if(c != 0) { + putchar(c); + } + } + + return NULL; +} + +static int start_logging() +{ + idevice_error_t ret = idevice_new(&device, udid); + if (ret != IDEVICE_E_SUCCESS) { + fprintf(stderr, "Device with udid %s not found!?\n", udid); + return -1; + } + + /* start and connect to syslog_relay service */ + service_error_t serr = SERVICE_E_UNKNOWN_ERROR; + service_client_factory_start_service(device, "com.apple.syslog_relay", (void**)&syslog, "idevicesyslog", NULL, &serr); + if (serr != SERVICE_E_SUCCESS) { + fprintf(stderr, "ERROR: Could not start service com.apple.syslog_relay.\n"); + idevice_free(device); + device = NULL; + return -1; + } + + /* start worker thread */ + logging = 1; +#ifdef WIN32 + worker = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)syslog_worker, NULL, 0, NULL); + if (worker == INVALID_HANDLE_VALUE) { + logging = 0; + return -1; + } +#else + if (pthread_create(&worker, NULL, syslog_worker, NULL) != 0) { + logging = 0; + return -1; + } +#endif + + return 0; +} + +static void stop_logging() +{ + if (logging) { + /* notify thread to finish */ + logging = 0; + if (syslog) { + service_client_free(syslog); + syslog = NULL; + } + + /* wait for thread to complete */ +#ifdef WIN32 + WaitForSingleObject(worker, INFINITE); +#else + pthread_join(worker, NULL); +#endif + } + + if (device) { + idevice_free(device); + device = NULL; + } +} + +static void device_event_cb(const idevice_event_t* event, void* userdata) +{ + if (event->event == IDEVICE_DEVICE_ADD) { + if (!logging) { + if (!udid) { + udid = strdup(event->udid); + } + if (strcmp(udid, event->udid) == 0) { + if (start_logging() != 0) { + fprintf(stderr, "Could not start logger for udid %s\n", udid); + } + } + } + } else if (event->event == IDEVICE_DEVICE_REMOVE) { + if (logging && (strcmp(udid, event->udid) == 0)) { + stop_logging(); + } + } +} + /** * signal handler function for cleaning up properly */ static void clean_exit(int sig) { - fprintf(stderr, "Exiting...\n"); + fprintf(stderr, "\nExiting...\n"); quit_flag++; } int main(int argc, char *argv[]) { - idevice_t device = NULL; - idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; int i; - const char* udid = NULL; signal(SIGINT, clean_exit); signal(SIGTERM, clean_exit); @@ -69,7 +193,7 @@ int main(int argc, char *argv[]) print_usage(argc, argv); return 0; } - udid = argv[i]; + udid = strdup(argv[i]); continue; } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { @@ -82,38 +206,30 @@ int main(int argc, char *argv[]) } } - ret = idevice_new(&device, udid); - if (ret != IDEVICE_E_SUCCESS) { - if (udid) { - printf("No device found with udid %s, is it plugged in?\n", udid); + int num = 0; + char **devices = NULL; + idevice_get_device_list(&devices, &num); + idevice_device_list_free(devices); + if (num == 0) { + if (!udid) { + fprintf(stderr, "No device found. Plug in a device or pass UDID with -u to wait for device to be available.\n"); + return -1; } else { - printf("No device found, is it plugged in?\n"); + fprintf(stderr, "Waiting for device with UDID %s to become available...\n", udid); } - return -1; } - service_error_t serr = SERVICE_E_UNKNOWN_ERROR; - service_client_t syslog = NULL; + idevice_event_subscribe(device_event_cb, NULL); - service_client_factory_start_service(device, "com.apple.syslog_relay", (void**)&syslog, "idevicesyslog", NULL, &serr); - if (serr == SERVICE_E_SUCCESS) { - while (!quit_flag) { - char c; - uint32_t bytes = 0; - if (service_receive(syslog, &c, 1, &bytes) != SERVICE_E_SUCCESS) { - fprintf(stderr, "Error receiving data. Exiting...\n"); - break; - } - if (c != 0) { - putchar(c); - fflush(stdout); - } - } - service_client_free(syslog); - } else { - printf("ERROR: Could not start service com.apple.syslog_relay.\n"); + while (!quit_flag) { + sleep(1); + } + idevice_event_unsubscribe(); + stop_logging(); + + if (udid) { + free(udid); } - idevice_free(device); return 0; } -- cgit v1.1-32-gdbae