Pregunta

Estoy interesado en iterar todos los sistemas de archivos montados en OSX (actualmente ejecutando 10.9 Mavericks). Estoy buscando algo similar a getMntent () o la salida del comando Mount Shell (aunque quiero hacerlo desde el objetivo C, por lo que analizar la salida de un comando shell obviamente no es óptimo).

He estado mirando un poco en el marco de arbitraje de disco, y parece que podría ser notificado sobre los eventos de montaje y desmontaje utilizando este marco. Puede que me falte algo allí, pero no me queda claro si hay una manera de iterar los sistemas de archivos montados existentes usando el arbitraje de disco.

He explorado usando getfsent () que parecía que proporcionaría una solución, pero después de las pruebas descubrí que no obtengo más de una entrada de iterating getfsent (). Vea el siguiente código:

struct fstab* fsentry;
setfsent();
fsentry = getfsent();
while(fsentry)
{
    //do something with fsentry
    fsentry = getfsent();
}
endfsent();

La única entrada que recibo aquí es para el sistema / archivo. La segunda vez que llamo getfsent () devuelve nulo, como si no hubiera más entradas. El comando de montaje me muestra varios otros, incluido un sistema de archivos CIFS/SMB montado:

/dev/disk0s2 on / (hfs, local, journaled)
devfs on /dev (devfs, local, nobrowse)
map -hosts on /net (autofs, nosuid, automounted, nobrowse)
map auto_home on /home (autofs, automounted, nobrowse)
//user@<ip address>/public on /Volumes/public (smbfs, nodev, nosuid, mounted by user)

Entonces parece que GetFsent () comienza a hacer lo que espero, pero por alguna razón se detiene?

Mi pregunta en resumen es: ¿Cuál es la mejor manera de iterar los sistemas de archivos en OSX?

Si alguien tiene una respuesta a por qué solo obtengo un resultado de GetFsent (), también estaría interesado en eso.

¿Fue útil?

Solución

Hay un par de formas diferentes de enumerar los volúmenes montados en OS X, cada uno con un conjunto diferente de API. En el nivel más alto (y más fácil), puede usar NSFilemanager's mountedVolumeURLsIncludingResourceValuesForKeys:options:. Aquí hay un ejemplo abreviado:

NSArray *urls = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:@[NSURLVolumeNameKey] options:0];
for (NSURL *url in urls) {
  NSLog(@"Volume mounted at: %@", [url path]);
}

La siguiente opción nos lleva de regreso al territorio C, y estabas muy cerca con tu enfoque original. En OS X (y BSD), no hay getmntent(); en cambio, hay getmntinfo(), que es sorprendentemente similar. Para enumerar volúmenes montados a través de getmntinfo(), puedes hacer lo siguiente:

struct statfs* mounts;
int num_mounts = getmntinfo(&mounts, MNT_WAIT);
if (num_mounts < 0) {
  // do something with the error
}

for (int i = 0; i < num_mounts; i++) {
  NSLog(@"Disk type '%s' mounted at: %s", mounts[i].f_fstypename, mounts[i].f_mntonname);
}

He usado estas dos API de lado a lado desde el lanzamiento de 10.6. getmntinfo() siempre es más completo que [NSFileManager mountedVolumeURLsIncludingResourceValuesForKeys:options:]: este último filtrará el /dev y otros sistemas de archivos que puede o no querer saber. Sin embargo, es generalmente confiable para los discos que se conecta a su sistema.

El propósito detrás del marco de diskarbitration es diferente, como usted notó. Diskarbitration se trata de monitorear y administrar activos de disco. Con DA, puede ser llamado cada vez que se monte o se desmonte un nuevo disco. También puede administrar esos discos renombrando, montando, desmontándose o expulsándolos, además de insertarse en el proceso de montaje/desmontaje, y posiblemente suspendiendo las solicitudes para hacer lo mismo. Pero, como señaló, no proporciona una interfaz para enumerar los discos existentes. Una vez que obtenga su lista de volúmenes montados, DA es una excelente parada (dependiendo, por supuesto, en su razón para obtener esa lista!).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top