Функция отслеживания подключенных накопителей (kos_devfs.h)
API определен в заголовочном файле sysroot-*-kos/include/kos_devfs.h из состава KasperskyOS SDK.
Функция wait_for_dev() позволяет программам отслеживать появление новых устройств в системе, используя механизм уведомлений вместо постоянного опроса файловой системы. Функция принимает указатель на имя целевого устройства, время для ожидания в секундах и возвращает true, если ожидаемое устройство было подключено ранее или во время таймера ожидания, и false, если превышено время ожидания или произошла ошибка.
Функция wait_for_dev() также использует вспомогательную функцию normalize_blkdevname(), конвертирующую имя устройства из формата с запятыми в формат с подчеркиваниями, например, Ahci0Port0,0 преобразуется в Ahci0Port0_p0.
Константы WAIT_FOR_DEV_MAX_DEV_NAME_SIZE и WAIT_FOR_DEV_DEFAULT_TIMEOUT_SEC ограничивают максимальную длину имени устройства 128 символами и устанавливают значение времени ожидания по умолчанию равным 10 секундам.
Механизм работы
Функция wait_for_dev() выполняет следующие действия:
- Преобразует имя устройства из формата с запятыми в формат с подчеркиваниями с помощью функции
normalize_blkdevname(). - Проверяет наличие устройства в системе сразу после запуска. Если устройство присутствует в системе, то функция возвращает
trueи завершает свою работу. - Создает директорию
/devи монтирует/devfsпри необходимости. - Настраивает уведомления о событиях файловой системы:
- Создает объект подписки с помощью функции
subscribe_create(). - Открывает директорию
/devдля мониторинга. - Регистрирует подписку на событие создания объектов с помощью функции
subscribe_ctl().
- Создает объект подписки с помощью функции
- Использует
subscribe_wait()для ожидания события создания нужного устройства - Освобождает ресурсы с помощью функции
subscribe_free(), закрывает дескрипторы и возвращаетtrue, если ожидаемое устройство было подключено, иfalse, если превышено время ожидания или произошла ошибка.
Пример использования функции API:
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mount.h>
#define _VFS_SERVER_INTERFACE
#include <vfs/basic.h>
#include <kos_devfs.h>
static _vfs_server_thread_routine_t thread_routine;
static void *thread_routine_arg;
void _vfs_server_set_main_thread_routine(_vfs_server_thread_routine_t func, void *arg)
{
thread_routine = func;
thread_routine_arg = arg;
}
int main(void)
{
char *devname = BLKDEV0;
char *dirname = "/mnt1";
char *fsname = "fat32";
long unsigned int flags = 0;
char *options = "";
if (!wait_for_dev(devname, WAIT_FOR_DEV_DEFAULT_TIMEOUT_SEC))
{
fprintf(stderr, BLKDEV0" is missed\n");
return false;
}
if (mkdir(dirname, S_IRWXU | S_IRWXG | S_IRWXO) != 0 && errno != EEXIST)
{
perror("Failed to mkdir");
return false;
}
if (mount(devname, dirname, fsname, flags, options) != 0)
{
perror("Failed to mount fat32");
return false;
}
assert(thread_routine != NULL);
(*thread_routine)(thread_routine_arg);
return EXIT_SUCCESS;
}