tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Open master pty (/dev/ptmx) non blocking



Hi,

I have a piece of software that opens a master pty non-blocking:
fd = open("/dev/ptmx", O_RDWR | O_NOCTTY | O_NONBLOCK);

The intent is to make further read(2) on the master non blocking. But
the O_NONBLOCK flag seems to be ignored. Attached is a minimal sample
C program showing the issue.

Several remarks:
* open(2) manual does not mention a master pty as special regarding the
  O_NONBLOCK flag, and even says "this flag also has the effect of making
  all subsequent I/O on the open file non-blocking",
* explicitly setting the file descriptor as non-blocking with fcntl(2)
  works fine,
* a slave pty has no such issue (O_NONBLOCK in open(2) is honoured),
* FWIW, linux has no surprise here, the flag behaves as one would expect,
* POSIX does not mention the flag as supported in posix_openpt(3) (it
  does not says it's not supported either :).

So, I'm not sure if something should be changed here, and if someone
is willing to check that? I tried to track down where in the kernel
this happens, maybe in pty_alloc_master in kern/tty_ptm.c? I really
don't master those kernel aspects so I'm not confident in providing a
patch.

I guess the principle of least surprise would say that the flag should
be supported (e.g. for maximum portability). OTOH, if the current
behaviour is deemed correct or sufficient, maybe at least some manual
(posix_openpt, open, ...) should mention this is not supported?

Best,
Anthony

#include <sys/ioctl.h>

#include <err.h>
#include <fcntl.h>
#include <unistd.h>

int
main()
{
  char buf[8];
  ssize_t s;
  int fd;

  /* open non-blocking: ignored */
  fd = open("/dev/ptmx", O_RDWR | O_NOCTTY | O_NONBLOCK);
  if (fd < 0) err(2, "/dev/ptmx");

#if 0
  /* set non-blocking: OK */
  int flag;
  flag = fcntl(fd, F_GETFL);
  if (flag == -1) err(2, "F_GETFL");

  fcntl(fd, F_SETFL, flag | O_NONBLOCK);
#endif

  /* read */
  s = read(fd, buf, sizeof(buf));
  warn("read %zd", s);

  return 0;
}


Home | Main Index | Thread Index | Old Index