ioctl(2)

NAZWA
ioctl - steruje urządzeniem

BIBLIOTEKA
Standardowa biblioteka C (libc, -lc)

SKŁADNIA
#include <sys/ioctl.h>

int ioctl(int fd, unsigned long op, ...);  /* glibc, BSD */
int ioctl(int fd, int op, ...);            /* musl, inny UNIX */

OPIS
Wywołanie systemowe ioctl manipuluje na podległych jej parametrach urządzeń, do których dostęp odbywa się poprzez pliki specjalne. W szczególności, za pomocą operacji ioctl() można kontrolować wiele właściwości operacyjnych specjalnych plików znakowych (np. terminali). Argument fd musi być otwartym deskryptorem pliku.

Drugi argument jest zależnym od urządzenia kodem operacji. Trzeci argument jest pozbawionym typu wskaźnikiem do obszaru pamięci, tradycyjnie char *argp (pochodzi z okresu zanim void * stało się poprawne w C) i tak będzie nazywany w niniejszej dyskusji.

op Ioctl() zawiera w sobie zakodowaną informację czy argument jest parametrem wejściowym czy wyjściowym oraz rozmiar argp tego argumentu w bajtach. Makra i definicje, używane do przekazywania op do ioctl(), znajdują się w pliku <sys/ioctl.h>. Zobacz UWAGI

WARTOŚĆ ZWRACANA
Zazwyczaj, po pomyślnym zakończeniu zwracane jest zero. Niektóre operacje ioctl() używają zwracanej wartości jako parametru wyjściowego i zwracają wówczas pewną wartość nieujemną. Po błędzie zwracane jest -1 i ustawiane errno wskazując błąd.

BŁĘDY

EBADF
    fd nie jest prawidłowym deskryptorem pliku.

EFAULT
    argp wskazuje na niedostępny obszar pamięci.

EINVAL
    op lub argp są nieprawidłowe.

ENOTTY
    fd nie jest związane z urządzeniem znakowym.

ENOTTY
    Podana operacja nie ma zastosowania do obiektu, na który wskazuje deskryptor fd.

WERSJE
Argumenty, zwracane wartości i semantyka ioctl() różnią się w zależności od sterownika urządzenia, którego dotyczą (wywołanie jest używane jako uniwersalne dla operacji, które nie dają się ładnie dopasować do uniksowego modelu strumieni wejścia/wyjścia).

STANDARDY
Brak.

HISTORIA
Wersja 7 AT&T UNIX posiadała
ioctl(int fildes, int op, struct sgttyb *argp);
(gdzie struct sgttyb historycznie używane było przez stty(2) i gtty(2) i jest polimorficzne, zależnie od typu operacji (podobnie, jak byłoby void *, gdyby było dostępne)).

SysIII dokumentuje arg bez żadnego typu.

4.3BSD miało
ioctl(int d, unsigned long op, char *argp);
(z char * podobnie jak w przypadku void *).

SysVr4 miało
int ioctl(int fildes, int op, ... /* arg */);

UWAGI
Aby używać niniejszego wywołanie, konieczny jest otwarty deskryptor pliku. Często wywołanie open(2) daje niepożądane skutki uboczne, którym pod Linuksem można zapobiec podając znacznik O_NONBLOCK.

  Struktura ioctl
Wartości op ioctl są 32-bitowymi stałymi. Generalnie stałe te są zupełnie przypadkowe, jednak niektórzy próbują je jakoś strukturyzować.

Wcześniej, w Linuksie większość 16-bitowych stałych składała się z ostatniego bajtu będącego numerem seryjnym i poprzedzającego go bajtu (bajtów) typu, który wskazuje sterownik. Czasem używany był numer główny: 0x03 do ioctl HDIO_*, 0x06 do ioctl LP*. Czasem używana była również litera (lub kilka) ASCII. Przykładowo TCGETS ma wartość 0x00005401, z 0x54 = „T” wskazującym sterownik terminala, a CYGETTIMEOUT ma wartość 0x00435906, gdzie 0x43 0x59 = „C” „Y” wskazuje sterownik cyclades.

Później (0.98p5) wbudowano w numer nieco więcej informacji. Miał on 2 bity kierunku (00: brak, 01: zapis, 10: odczyt, 11: odczyt/zapis), po których następowało 14 bitów rozmiaru (wskazujących rozmiar argumentu), po których następował 8-bitowy typ (zbierający ioctl-e w grupy wg wspólnego zastosowania lub wspólnego sterownika) i 8-bitowy numer seryjny.

Makra opisujące tę strukturę istnieją w <asm/ioctl.h> i są to _IO(type,nr) oraz {_IOR,_IOW,_IOWR}(type,nr,size). Używają sizeof(size), tak więc rozmiar (size) jest tu błędną nazwą: trzeci argument jest typem danych.

Proszę zauważyć, że bity rozmiaru są bardzo niepewne: w wielu przypadkach są nieprawidłowe, albo ze względu na błędne makra używające sizeof(sizeof(struct)), albo ze względu na przestarzałe wartości.

Wszystko wskazuje zatem na to, że nowa struktura ma same wady: nie pomaga w sprawdzaniu, a powoduje zróżnicowanie wartości na różnych architekturach.

ZOBACZ TAKŻE
execve(2), fcntl(2), ioctl_console(2), ioctl_fat(2), ioctl_fs(2), ioctl_fsmap(2), ioctl_nsfs(2), ioctl_tty(2), ioctl_userfaultfd(2), ioctl_eventpoll(2), open(2), sd(4), tty(4)

TŁUMACZENIE
Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Przemek Borys <pborys@dione.ids.pl>, Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl> i Michał Kułach <michal.kulach@gmail.com>

Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 (https://www.gnu.org/licenses/gpl-3.0.html) lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.

Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net.