There are 2 things missing from your code. As @Hanzaplastique mentioned, you need to wait for the callback to be executed. Secondly, you need to pass a valid queue to DASessionSetDispatchQueue()
. If you pass NULL
as in your code, you're telling it to unschedule the session.
You can use a dispatch_semaphore_t
to wait between threads. Putting it all together, I get this:
#include <stdio.h>
#import <CoreFoundation/CoreFoundation.h>
#import <DiskArbitration/DiskArbitration.h>
static dispatch_semaphore_t semaphore;
void MountCallback(DADiskRef disk, DADissenterRef dissenter, void *context);
int main(int argc, const char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <disk>\n", argv[0]);
return EXIT_FAILURE;
}
const char *deviceName = argv[1];
// Create the semaphore we'll wait on.
semaphore = dispatch_semaphore_create(0);
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, deviceName);
// Pass NULL for a "standard" mount path.
DADiskMount(disk, NULL, kDADiskMountOptionWhole, MountCallback, (void *)deviceName);
// We'll pass the global concurrent queue here so it gets executed in the background
DASessionSetDispatchQueue(session, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0));
CFRelease(session);
session = NULL;
// Wait for the callback to signal that it's done
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// Clean up
dispatch_release(semaphore);
return EXIT_SUCCESS;
}
void MountCallback(DADiskRef disk, DADissenterRef dissenter, void *context) {
const char *mountedDisk = context;
fprintf(stderr, "Device mounted: %s\n", mountedDisk);
fflush(stderr);
// Tell the main thread that we've finished up.
dispatch_semaphore_signal(semaphore);
return;
}