SYSCTL(2)

ИМЯ
sysctl - читает/записывает параметры системы

ОБЗОР
#include <unistd.h>
#include <linux/sysctl.h>

int _sysctl(struct __sysctl_args *args);

Замечание: В glibc нет обёрточной функции для данного системного вызова; смотрите ЗАМЕЧАНИЯ.

ОПИСАНИЕ
Не используйте этот системный вызов! Смотрите ЗАМЕЧАНИЯ.

Системный вызов _sysctl считывает и/или изменяет параметры ядра. К ним относятся, например, имя машины или максимальное количество открытых файлов. Параметр имеет следующую структуру:

    struct __sysctl_args {
        int    *name;    /* целочисленный вектор, описывающий
                            переменную */
        int     nlen;    /* длина этого вектора */
        void   *oldval;  /* 0 или адрес старого значения */
        size_t *oldlenp; /* размер старого значения, заменяется
                            реальным размером старого значения */
        void   *newval;  /* 0 или адрес нового значения */
        size_t  newlen;  /* размер нового значения */
    };

Этот вызов производит поиск в древовидной структуре, возможно, похожей на структуру каталогов /proc/sys, и, если запрашиваемый элемент найден, вызывает соответствующую процедуру, читающую или изменяющую значение.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении _sysctl() возвращает 0. При ошибке возвращается -1, а переменной errno присваивается номер ошибки.

ОШИБКИ

EACCES, EPERM
    Нет прав на поиск в одном из встретившихся «каталогов» или нет прав на чтение, если oldval не равно нулю; или нет прав на запись, если newval не равно нулю.

EFAULT
    Был сделан запрос предыдущего значения путём установки не-NULL значения oldval, но размер места под него в oldlenp равен нулю.

ENOTDIR
    name не найден.

СООТВЕТСТВИЕ СТАНДАРТАМ
Этот вызов есть только в Linux и не должен использоваться в переносимых программах. Вызов sysctl() впервые появился в Linux 1.3.57. Впервые он появился в 4.4BSD. Только в Linux существует зеркало /proc/sys, и схемы именования объектов в Linux и 4.4BSD различаются, но объявление функции sysctl() одинаково в обеих системах.

ЗАМЕЧАНИЯ
В glibc отсутствует обёрточная функция для этого системного вызова; вызывайте его через syscall(2). Или лучше совсем не используйте: использование данного системного вызова уже давно не рекомендуется и он так всем не нравится, что, вероятно, исчезнет в новой версии ядра. Начиная с Linux 2.6.24, при использовании данного системного вызова записывается предупреждение в журнал ядра. Удалите вызов из своих программ прямо сейчас; вместо него используйте интерфейс /proc/sys.

Данный системный вызов доступен только, если ядро было собрано с параметром CONFIG_SYSCTL_SYSCALL.

ДЕФЕКТЫ
Названия объектов различаются в разных версиях ядра, что делает данный вызов в приложениях бесполезным.

Не все существующие объекты описаны соответствующим образом.

В настоящее время невозможно изменить тип операционной системы путём записи в файл /proc/sys/kernel/ostype.

ПРИМЕР
    #define _GNU_SOURCE
    #include <unistd.h>
    #include <sys/syscall.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <linux/sysctl.h>
    int _sysctl(struct __sysctl_args *args );
    #define OSNAMESZ 100
    int
    main(void)
    {
        struct __sysctl_args args;
        char osname[OSNAMESZ];
        size_t osnamelth;
        int name[] = { CTL_KERN, KERN_OSTYPE };
        memset(&args, 0, sizeof(struct __sysctl_args));
        args.name = name;
        args.nlen = sizeof(name)/sizeof(name[0]);
        args.oldval = osname;
        args.oldlenp = &osnamelth;
        osnamelth = sizeof(osname);
        if (syscall(SYS__sysctl, &args) == -1) {
            perror("_sysctl");
            exit(EXIT_FAILURE);
        }
        printf("Эта машина работает в %*s\n", osnamelth, osname);
        exit(EXIT_SUCCESS);
    }

СМОТРИТЕ ТАКЖЕ
proc(5)