Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-target to MacOS 10.7 SDK. Add timeout functionality. #1

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions deviceconsole.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
SDKROOT = macosx10.5;
};
name = Debug;
};
Expand All @@ -187,7 +186,6 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = macosx10.5;
};
name = Release;
};
Expand Down
80 changes: 75 additions & 5 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ static CFMutableDictionaryRef liveConnections;
static int debug;
static CFStringRef requiredDeviceId;

static int exitAfterTimeout;
static int linesLogged;

static inline void write_fully(int fd, const void *buffer, size_t length)
{
while (length) {
Expand All @@ -24,6 +27,26 @@ static inline void write_fully(int fd, const void *buffer, size_t length)
}
}

static void Timeout()
{
static int logged = -1;

if(exitAfterTimeout) {
if(debug)
fprintf(stderr, "[!] Exit due to timeout.\n");
exit(0);
}

if(logged != linesLogged) {
logged = linesLogged;
} else {
if(debug)
fprintf(stderr, "[!] Exit after timeout (because nothing else has been logged.)\n");

exit(0);
}
}

static void SocketCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
// Skip null bytes
Expand All @@ -34,7 +57,7 @@ static void SocketCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef a
buffer++;
length--;
if (length == 0)
return;
goto exit;
}
size_t extentLength = 0;
while ((buffer[extentLength] != '\0') && extentLength != length) {
Expand All @@ -44,6 +67,15 @@ static void SocketCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef a
length -= extentLength;
buffer += extentLength;
}

exit:
/*
* It turns out that every time we get here, we've logged one complete log
* statement. (which could be more than one line, but you get the idea.)
*/
linesLogged++;

return;
}

static void DeviceNotificationCallback(am_device_notification_callback_info *info, void *unknown)
Expand All @@ -70,7 +102,11 @@ static void DeviceNotificationCallback(am_device_notification_callback_info *inf
if (AMDeviceStartSession(device) == MDERR_OK) {
service_conn_t connection;
if (AMDeviceStartService(device, AMSVC_SYSLOG_RELAY, &connection, NULL) == MDERR_OK) {
CFSocketRef socket = CFSocketCreateWithNative(kCFAllocatorDefault, connection, kCFSocketDataCallBack, SocketCallback, NULL);
CFSocketRef socket = CFSocketCreateWithNative(kCFAllocatorDefault,
connection,
kCFSocketDataCallBack,
SocketCallback,
NULL);
if (socket) {
CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0);
if (source) {
Expand Down Expand Up @@ -121,12 +157,25 @@ static void DeviceNotificationCallback(am_device_notification_callback_info *inf

int main (int argc, char * const argv[])
{
double timeout = 0;

if ((argc == 2) && (strcmp(argv[1], "--help") == 0)) {
fprintf(stderr, "Usage: %s [options]\nOptions:\n -d Include connect/disconnect messages in standard out\n -u <udid> Show only logs from a specific device\n\nControl-C to disconnect\nMail bug reports and suggestions to <[email protected]>\n", argv[0]);
fprintf(stderr,
"Usage: %s [options]\nOptions:\n"
" -d Include connect/disconnect messages in standard out,\n"
" and exit reason in standard err.\n"
" -u <udid> Show only logs from a specific device.\n"
" -t <timeout> Exit after the specified timeout, in seconds (can be decimal),\n"
" if there have been no more logs in that timeframe.\n"
" -x (Must use with -t.) Exit unconditionally after the timeout,\n"
" even if more logs are coming in.\n"
"\nControl-C to disconnect\n"
"Mail bug reports and suggestions to <[email protected]>\n",
argv[0]);
return 1;
}
int c;
while ((c = getopt(argc, argv, "du:")) != -1)
while ((c = getopt(argc, argv, "dxt:u:")) != -1)
switch (c)
{
case 'd':
Expand All @@ -137,8 +186,14 @@ int main (int argc, char * const argv[])
CFRelease(requiredDeviceId);
requiredDeviceId = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingASCII);
break;
case 't':
timeout = atof(optarg);
break;
case 'x':
exitAfterTimeout = 1;
break;
case '?':
if (optopt == 'u')
if (optopt == 'u' || optopt == 't')
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
else if (isprint(optopt))
fprintf(stderr, "Unknown option `-%c'.\n", optopt);
Expand All @@ -151,6 +206,21 @@ int main (int argc, char * const argv[])
liveConnections = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
am_device_notification *notification;
AMDeviceNotificationSubscribe(DeviceNotificationCallback, 0, 0, NULL, &notification);

if(timeout != 0) {
CFRunLoopTimerRef timer = CFRunLoopTimerCreate(NULL,
/* give it a couple extra seconds to connect */
CFAbsoluteTimeGetCurrent() + 2.0 + timeout,
timeout,
0, /* flags */
0, /* order */
(CFRunLoopTimerCallBack) Timeout,
NULL);

CFRunLoopAddTimer(CFRunLoopGetMain(), timer, kCFRunLoopCommonModes);
}


CFRunLoopRun();
return 0;
}