Интерпретируйте возвращаемое значение (несогласный) при попытке размонтировать том в OS X - PullRequest
8 голосов
/ 19 декабря 2011

Я пытаюсь размонтировать том в моем приложении Какао с помощью Disk Arbitration Framework.

Перед звонком:

DADiskUnmount(disk, 
              kDADiskUnmountOptionDefault, 
              unmountCallback, 
              self );

Я регистрирую функцию обратного вызова, которая впоследствии вызывается:

void unmountCallback(DADiskRef disk, DADissenterRef dissenter, void *context )
{
   if (dissenter != NULL) 
    {
        DAReturn ret = DADissenterGetStatus(dissenter);

        switch (ret) {
        case kDAReturnBusy:
            printf("kDAReturnBusy\n");
            break;
    } 
}

В этой функции я пытаюсь интерпретировать возвращаемое значение инакомыслящего, но застреваю. Я предполагаю, что он должен иметь тип DAReturn и иметь значение, подобное kDAReturnBusy Но когда, например, iTunes использует том, и его нельзя отключить «ret» имеет значение 0xc010, которое я не совсем понимаю.

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

1 Ответ

17 голосов
/ 19 декабря 2011

Но когда, например, iTunes использует том, и его нельзя отключить, "ret" имеет значение 0xc010, которое я не совсем понимаю.

Документация, на которую вы ссылалисьдля типа DAReturn перечисляет все константы дискового арбитража следующим образом:

    kDAReturnError = err_local | err_local_diskarbitration | 0x01, /* ( 0xF8DA0001 ) */

Итак, все возвраты ошибок DA состоят из трех компонентов, ИЛИ бы вместе.

Если вы посмотрите документацию для DADissenterGetStatus, там написано:

Код возврата BSD, если применимо, кодируется с помощью unix_err ().

Если вы затем ищете заголовки для unix_err, вы найдете его в /usr/include/mach/error.h, где написано:

/*    unix errors get lumped into one subsystem  */
#define   unix_err(errno)     (err_kern|err_sub(3)|errno)

и:

/*
 *    error number layout as follows:
 *
 *    hi                     lo
 *    | system(6) | subsystem(12) | code(14) |
 */

Снова эти три компонента.Некоторые другие макросы в error.h упорядочивают значения системы и подсистемы (например, err_kern и err_sub(3)) в эти позиции.

Итак, теперь давайте откроем калькулятор, нажмите ⌘3, чтобы поместить его в программаторпереключите его на base-16, введите код ошибки и посмотрите, что там написано:

0xC010

0000 0000 0000 0000 1100 0000 0001 0000
31                  15                0

Разбивая это в соответствии свыше макета, мы находим:

0000 00
31     

Система: 0, который error.h говорит, что err_kern.Эта ошибка произошла из ядра.

       00 0000 0000 11
31                  15

Подсистема: 3 (0b11).Этот плюс системный код соответствует вышеупомянутому определению unix_err.Так что это код возврата BSD, как сказано DADissenterGetStatus.

                      00 0000 0001 0000
31                  15                0

Индивидуальный код ошибки: 16 (0x10, 0b10000).

Ошибки UNIX / BSDопределены в <sys/errno.h>, где указано:

#define EBUSY       16      /* Device / Resource busy */

Это говорит о том, что вы не можете размонтировать это устройство, потому что оно используется.

...