TIOCPKT(2const)

πŸ’… TIOCPKT: the pseudoterminal ioctls page, but make it make sense

okay bestie, sit down, we're talking about TIOCPKT, TIOCGPKT, TIOCSPTLCK, TIOCGPTLCK and TIOCGPTPEER β€” the pseudoterminal ioctls. yes that's the whole name. iconic, unhinged, five constants in a trench coat. 🫢


✨ LIBRARY ✨

Standard C library (libc, -lc). the basics, no cap.


🌈 SYNOPSIS 🌈

#include <asm/termbits.h>  /* Definition of TIOC* constants */
#include <sys/ioctl.h>

int ioctl(int fd, TIOCPKT, const int *mode);
int ioctl(int fd, TIOCPKT, int *mode);

int ioctl(int fd, TIOCSPTLCK, const int *lock);
int ioctl(int fd, TIOCGPTLCK, int *lock);

int ioctl(int fd, TIOCGPTPEER, int flags);

yes, TIOCPKT really does show up twice with const int *mode and then plain int *mode. it's giving "I contain multitudes". both are real, both are in the original, we respect both. πŸ’œ


πŸ’– DESCRIPTION πŸ’–

TIOCPKT

turn packet mode on (when *mode is nonzero) or off. and this is the tea: you can only do this on the master side of a pseudoterminal. try it anywhere else and it just returns ENOTTY at you. rude but consistent. πŸ’€

so once packet mode is on, every subsequent read(2) hands you back a packet that is either:

  • a single nonzero control byte, or
  • a single byte containing zero ('\0') followed by data written on the slave side of the pseudoterminal.

and if that first byte is not TIOCPKT_DATA (0), then it's an OR of one or more of these bits, bestie:

  • TIOCPKT_FLUSHREAD β€” the read queue for the terminal is flushed.
  • TIOCPKT_FLUSHWRITE β€” the write queue for the terminal is flushed.
  • TIOCPKT_STOP β€” output to the terminal is stopped.
  • TIOCPKT_START β€” output to the terminal is restarted.
  • TIOCPKT_DOSTOP β€” the start and stop characters are ^S/^Q.
  • TIOCPKT_NOSTOP β€” the start and stop characters are not ^S/^Q.

while packet mode is in use, you can spot control status info waiting on the master side by doing a select(2) for exceptional conditions, or a poll(2) for the POLLPRI event. yes, exceptional conditions. main character energy, honestly. πŸ‘‘

and why does this exist? because rlogin(1) and rlogind(8) use this mode to implement a remote-echoed, locally ^S/^Q flow-controlled remote login. it's old money. πŸŽ€

TIOCGPKT

gives you back the current packet mode setting, written into the integer that mode points at.

TIOCSPTLCK

sets the lock on the pseudoterminal slave device if *lock is nonzero, and removes it if *lock is zero. (also go peek at unlockpt(3), it's in the group chat.)

TIOCGPTLCK

puts the current lock state of the pseudoterminal slave device into the location that lock points to.

TIOCGPTPEER

you give it an fd that refers to a pseudoterminal master, and it opens β€” with the open(2)-style flags you pass β€” and returns a brand new file descriptor pointing at the peer pseudoterminal slave device. ✨ and here's the slay: this works regardless of whether the pathname of the slave device is even accessible through the calling process's mount namespace.

if you're a security-conscious program doing namespace stuff, you lowkey want this instead of open(2) with the pathname that ptsname(3) gave you, and instead of similar library functions with insecure APIs. because (and this is the actual warning, not me being dramatic) confusion can occur in some cases when you use ptsname(3) with a pathname where a devpts filesystem has been mounted in a different mount namespace. πŸ™ˆ


πŸ¦‹ RETURN VALUE πŸ¦‹

  • on success, <mint>0</mint> comes back. slay.
  • on error, <red>-1</red> comes back, and errno gets set to tell you what went wrong.

πŸ’€ ERRORS πŸ’€

  • ENOTTY

and that's it. that is the entire list. not a typo, not me skipping the boring part β€” ENOTTY is the whole squad. πŸ“


🌸 HISTORY 🌸

  • TIOCGPKT β€” Linux 3.8.
  • TIOCGPTLCK β€” Linux 3.8.
  • TIOCGPTPEER β€” Linux 4.13.

and for the record: the BSD ioctls TIOCSTOP, TIOCSTART, TIOCUCNTL, and TIOCREMOTE have not been implemented under Linux. they're not coming, bestie, don't wait up. 😭


πŸ‘€ SEE ALSO πŸ‘€


okay that's the whole page, you ate it, go go go 🫢

this was brought to you by Linux man-pages 6.20, dated 2026-02-08 β€” so when you cite this in the group chat, cite it with the date, periodt. πŸ’…

πŸ“¦ 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: GPL-1.0-or-later
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms