public
Last active

On Mac OS X: Block until the network stack is ready. Useful for daemons which need the network to do anything useful.

  • Download Gist
waitForNetwork.m
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
 
// Wait for the network to be configured. Equivalent to `ipconfig waitall`. Adapted from ipconfig/client.c
static void _doneWaitingForNetwork(SCDynamicStoreRef session, CFArrayRef changes, void * arg){
CFRunLoopStop(CFRunLoopGetCurrent());
}
 
#define STARTUP_KEY CFSTR("Plugin:IPConfiguration")
#define NETWORK_RUN_LOOP_MODE CFSTR("WaitingForNetwork")
void waitForNetwork(){
SCDynamicStoreRef session = SCDynamicStoreCreate(NULL, (CFStringRef)[[NSProcessInfo processInfo] processName], _doneWaitingForNetwork, NULL);
if (session == NULL) {
asl_log(NULL, NULL, ASL_LEVEL_ERR, "SCDynamicStoreCreate failed while checking for network: %s", SCErrorString(SCError()));
exit(EXIT_FAILURE);
}
CFMutableArrayRef keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
CFArrayAppendValue(keys, STARTUP_KEY);
SCDynamicStoreSetNotificationKeys(session, keys, NULL);
CFRelease(keys);
CFRunLoopSourceRef rls = SCDynamicStoreCreateRunLoopSource(NULL, session, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, NETWORK_RUN_LOOP_MODE);
CFPropertyListRef value = SCDynamicStoreCopyValue(session, STARTUP_KEY);
if (value == NULL) {
CFRunLoopRunInMode(NETWORK_RUN_LOOP_MODE, 90, false);
} else {
CFRelease(value);
}
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), rls, NETWORK_RUN_LOOP_MODE);
CFRelease(rls);
CFRelease(session);
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.