using getfsstat() to get the list of mounted devices in the file system. Usign disk arbitration framework to register for volume mount/unmount callbacks.
The sample program pasted below, enumerates the mounted file systems, each time a volume mount/unmount takes place. In the line no.4 if sleep is commented out, getfsstat does not return the new set of mounted file systems. But once sleep is added, everything works fine.
Yep i've tried MNT_NOWAIT as well.
Is this a bug in disk arbitration, may be it prematurely invokes the mount/unmount callbacks ?
Ameen.
void listMountedDevices(DADiskRef disk, void *context) { //1st line
static struct statfs *fsList = 0x0; //2nd line
size_t nDevices = 0x0; //3rd line
sleep(1); //4th line. If no sleep then getfsstat returns the same statfs array it returned the last time.
nDevices = getfsstat(NULL,0,MNT_NOWAIT);
if(nDevices) {
struct statfs *fsListPtr = 0x0;
if(fsList) {
free(fsList);
fsList = 0x0;
}
if(fsList = static_cast <struct statfs *> (malloc(nDevices * sizeof(struct statfs)))) {
if(nDevices = getfsstat(fsList,nDevices * sizeof(struct statfs),MNT_NOWAIT)) {
for(size_t index = 0;index < nDevices;index++) {
fsListPtr = fsList + index;
printf("************** file system no: %d ************** \n",index);
printf("file system type: %s\n",fsListPtr->f_fstypename);
printf("mounted on directory: %s\n",fsListPtr->f_mntonname);
printf("mounted filesystem: %s\n",fsListPtr->f_mntfromname);
printf("fsListPtr->f_fsid.val[0]: %d\n",fsListPtr->f_fsid.val[0]);
printf("fsListPtr->f_fsid.val[1]: %d\n",fsListPtr->f_fsid.val[1]);
printf("************** file system no: %d ************** \n\n",index);
}
}
}//if(fsList = static_cast <statfs *> (malloc(nDevices * sizeof(struct statfs))))
printf("number o devices: %d\n",nDevices);
}
}
main()
{
DASessionRef session;
session = DASessionCreate(kCFAllocatorDefault);
DARegisterDiskAppearedCallback(session,kDADiskDescriptionMatchVolumeMountable,listMountedDevices,NULL);
DARegisterDiskDisappearedCallback(session,kDADiskDescriptionMatchVolumeMountable,listMountedDevices,NULL);
DASessionScheduleWithRunLoop(session,CFRunLoopGetCurrent(),kCFRunLoopDefaultMode);
CFRunLoopRun();
CFRelease(session);
exit(0);
}