Как перебрать все смонтированные файловые системы на OSX

Я заинтересован в переборе всех смонтированных файловых систем на OSX (в настоящее время работает 10,9 Mavericks). Я ищу что-то похожее на getmntent() или выходные данные команды mount shell (хотя я хочу сделать это из цели C, поэтому разбор выходных данных команды shell, очевидно, не оптимален).

Я немного посмотрел на структуру арбитража диска, и кажется, что я мог бы получать уведомления о событиях монтирования и размонтирования, используя эту платформу. Возможно, я чего-то там упускаю, но мне не ясно, есть ли способ перебрать существующие смонтированные файловые системы с помощью Дискового Арбитража.

Я исследовал использование getfsent(), которое, казалось, могло обеспечить решение, но после тестирования я обнаружил, что не получаю более одной записи от итерации getfsent(). Смотрите следующий код:

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

Единственная запись, которую я здесь получаю, относится к / файловой системе. Во второй раз, когда я вызываю getfsent(), он возвращает NULL, как будто больше нет записей. Команда mount показывает мне несколько других, включая смонтированную файловую систему cifs/smb:

/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)

Похоже, что getfsent() начинает делать то, что я ожидаю, но почему-то останавливается?

Вкратце мой вопрос: каков наилучший способ перебора файловых систем в OSX?

Если у кого-то есть ответ на вопрос, почему я получаю только один результат от getfsent(), меня это также заинтересует.

1 ответ

Решение

Существует несколько различных способов перечисления подключенных томов в OS X, каждый из которых использует свой набор API. На самом высоком (и самом простом) уровне вы можете использовать NSFileManager's mountedVolumeURLsIncludingResourceValuesForKeys:options:, Вот сокращенный пример:

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

Следующий вариант возвращает нас на территорию C - и вы были так близки с вашим первоначальным подходом. На OS X (и BSD) нет getmntent(); вместо этого есть getmntinfo(), что поразительно похоже. Чтобы просмотреть подключенные тома через getmntinfo() Вы можете сделать следующее:

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);
}

Я использовал оба этих API параллельно с выпуском 10.6. getmntinfo() всегда полнее, чем [NSFileManager mountedVolumeURLsIncludingResourceValuesForKeys:options:]: последний будет фильтровать /dev и другие файловые системы, о которых вы можете или не хотите знать. Однако, как правило, он надежен для дисков, которые вы подключаете к своей системе.

Как вы заметили, цель фреймворка DiskArbitration иная. DiskArbitration - это мониторинг и управление дисковыми ресурсами. С DA вы можете звонить всякий раз, когда новый диск монтируется или демонтируется. Вы также можете управлять этими дисками, переименовывая, монтируя, размонтируя или извлекая их, а также вставляя себя в процесс монтирования / размонтирования и, возможно, приостанавливая запросы на выполнение тех же действий. Но, как вы указали, он не предоставляет интерфейс для вывода списка существующих дисков. Как только вы получите свой список подключенных томов, DA станет отличной следующей остановкой (конечно, в зависимости от причины, по которой вы получили этот список!).

Другие вопросы по тегам