iopl(2)

๐Ÿ’… iopl(2) โ€” bestie, we gotta talk about this one

okay so this is a page from the System Calls Manual, and it's literally called iopl(2). sit down, get a snack ๐Ÿ“, because the tea here is that this syscall is deprecated and we're all just being polite about it.


โœจ NAME โœจ

iopl โ€” change I/O privilege level ๐Ÿ‘‘


๐Ÿ“š LIBRARY ๐Ÿ“š

Standard C library (that's libc, and you link it with -lc) ๐Ÿซถ


๐Ÿงš SYNOPSIS ๐Ÿงš

#include <sys/io.h>

[[deprecated]] int iopl(int level);
not the [[deprecated]] right there in the prototype ๐Ÿ’€ like, the compiler is also judging you. iconic honestly.

๐ŸŒธ DESCRIPTION ๐ŸŒธ

so iopl() changes the I/O privilege level of the calling thread, and it reads that level from the two least significant bits in level. yep, just the bottom two bits. the rest of the int is vibing, ignored.

the I/O privilege level for a normal thread is 0. and permissions? inherited from parents to children. family business, iykyk ๐Ÿ’œ

now the real talk ๐Ÿซ–: this call is deprecated. it's significantly slower than ioperm(2), and the only reason it's still here is for older X servers that need access to all 65536 I/O ports. it's mostly for the i386 architecture. on many other architectures it literally doesn't exist, or it will always return an error. no cap. ๐Ÿ˜ญ


๐ŸŽ€ RETURN VALUE ๐ŸŽ€

  • on success? zero comes back, slay โœจ
  • on error? -1, and errno gets set to tell you what went wrong

๐Ÿ”ฅ ERRORS ๐Ÿ”ฅ

  • EINVAL โ€” level is greater than 3. bestie, it's a two-bit field, what did you expect ๐Ÿ’€
  • ENOSYS โ€” this call is unimplemented. (so it just... isn't here. ghosted. ๐Ÿ‘ป)
  • EPERM โ€” the calling thread doesn't have enough privilege to call iopl(); you need the CAP_SYS_RAWIO capability to raise the I/O privilege level above its current value. no permission, no party ๐Ÿ™ˆ

๐Ÿฆ‹ VERSIONS ๐Ÿฆ‹

glibc2 has a prototype both in <sys/io.h> and in <sys/perm.h>. avoid the latter one โ€” it's available on i386 only. choose wisely ๐ŸŒˆ


โญ STANDARDS โญ

Linux. that's it, that's the standard. ๐Ÿง


๐Ÿ‘‘ HISTORY ๐Ÿ‘‘

grab a seat, this part is juicy:

  • Prior to Linux 5.5, iopl() allowed the thread to disable interrupts while running at a higher I/O privilege level. this will probably crash the system, and it is not recommended. like... do not do this. seriously. ๐Ÿšจ
  • Prior to Linux 3.7, on some architectures (such as i386), permissions were inherited by the child produced by fork(2) and were preserved across execve(2). that behavior was inadvertently changed in Linux 3.7, and it won't be reinstated. gone but not forgotten, I guess ๐Ÿ’”

๐Ÿซถ SEE ALSO ๐Ÿซถ


okay and for the little sign-off at the end ๐Ÿ’– this cutie lives in Linux man-pages 6.20, dated 2026-02-08, and that's the whole iopl(2) page โ€” deprecated but still serving looks ๐Ÿ’…โœจ

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ“œ the page's license: Linux-man-pages-copyleft
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms