W każdym przykładzie i dyskusji, na którą natknąłem się w kontekście programowania gniazd BSD, wydaje się, że zalecanym sposobem ustawienia deskryptora pliku na nieblokujący tryb I / O jest użycie O_NONBLOCK
flagi fcntl()
np.
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
Od ponad dziesięciu lat zajmuję się programowaniem sieciowym w systemie UNIX i zawsze używałem tego FIONBIO ioctl()
wywołania:
int opt = 1;
ioctl(fd, FIONBIO, &opt);
Nigdy tak naprawdę nie zastanawiałem się, dlaczego. Właśnie się tego nauczyłem.
Czy ktoś ma jakieś uwagi na temat możliwych zalet jednej lub drugiej? Wyobrażam sobie, że miejsce przenoszenia różni się nieco, ale nie wiem w jakim stopniu, ponieważ ioctl_list(2)
nie dotyczy tego aspektu poszczególnych ioctl
metod.
źródło
Jak powiedział @Sean,
fcntl()
jest w dużej mierze znormalizowany, a zatem dostępny na różnych platformach.ioctl()
Funkcja wyprzedzafcntl()
w Uniksie, ale nie jest znormalizowany w ogóle. To, żeioctl()
zadziałało dla Ciebie na wszystkich istotnych dla Ciebie platformach, jest szczęśliwe, ale nie jest gwarantowane. W szczególności nazwy użyte w drugim argumencie są tajemnicze i nie są wiarygodne na różnych platformach. W rzeczywistości są one często unikalne dla konkretnego sterownika urządzenia, do którego odnosi się deskryptor pliku. (Na przykładioctl()
wywołania używane do mapowanego bitowo urządzenia graficznego działającego na ICL Perq z systemem PNX (Perq Unix) sprzed dwudziestu lat nigdy nie zostały przetłumaczone na nic innego, na przykład).źródło
Uważam, że
fcntl()
jest to funkcja POSIX. Gdzieioctl()
jest standardowa rzecz UNIX. Oto lista POSIX io .ioctl()
jest bardzo specyficzną dla jądra / sterownika / systemu operacyjnego, ale jestem pewien, że to, czego używasz, działa na większości odmian Uniksa. niektóre inneioctl()
rzeczy mogą działać tylko na określonym systemie operacyjnym lub nawet na pewnych obrotach jego jądra.źródło