Как обернуть ioctl(int d, unsigned long request, ...), используя LD_PRELOAD?

Вот шаблон, который я использую для обертывания функции с использованием LD_PRELOAD:

int gettimeofday(struct timeval *tv, struct timezone *tz) {
  static int (*gettimeofday_real)(struct timeval *tv, struct timezone *tz)=NULL;
  if (!gettimeofday_real) gettimeofday_real=dlsym(RTLD_NEXT,"gettimeofday");
  return gettimeofday_real(tv, tz);
}

Я понял, что у ioctl, похоже, следующая подпись:

   int ioctl(int d, unsigned long request, ...);

Как я мог обернуть его подобным образом, учитывая ... это в подписи?

2 ответа

Хотя Джон Боллинджер прав в этом согласно своему прототипу в ioctl.h, ioctl() это вариадная функция, на практике это не так.

Посмотрите, например, эту цитату из книги Драйверы устройств Linux

Прототип выделяется в списке системных вызовов Unix из-за точек, которые обычно отмечают функцию как имеющую переменное число аргументов. Однако в реальной системе системный вызов не может иметь переменное количество аргументов. Системные вызовы должны иметь четко определенный прототип, потому что пользовательские программы могут получить к ним доступ только через аппаратные "ворота". Поэтому точки в прототипе представляют не переменное число аргументов, а один необязательный аргумент, традиционно обозначаемый как char * argp. Точки просто существуют, чтобы предотвратить проверку типов во время компиляции.

Таким образом, вы можете написать свой susbtitute ioctl() следующее:

int ioctl(int d, unsigned long request, char *argp)
{
  /* follow the same recipe as for your example gettimeofday() */
  return ioctl_real(d, request, argp);
}

Если вы просто хотите создать библиотеку-оболочку для использования с LD_PRELOADтот факт, что ваш ioctl подпись противоречит тому, что в sys/ioctl.h не имеет значения: компоновщики не проверяют типы, а фальшивка вашей библиотеки-обёртки ioctl будет вызываться с теми же аргументами, что и реальный без LD_PRELOAD

Не существует переносимого способа для одной функции с переменными параметрами пересылать свои аргументы с переменными параметрами в другую функцию с переменными числами. Частично это связано с тем, что число и размер фактических аргументов должны быть известны во время компиляции, чтобы компилятор мог создать вызов переменной, но они не являются статически известными (даже параметрическим способом) внутри вызываемой функции.

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