tcdrain() — Wait until output has been transmitted

Standards

Standards / Extensions C or C++ Dependencies

POSIX.1
XPG4
XPG4.2
Single UNIX Specification, Version 3

both  

Format

#define _POSIX_SOURCE
#include <termios.h>

int tcdrain(int fildes);

General description

The tcdrain() function waits until all output sent to fildes has actually been sent to the terminal device.

If tcdrain() is called from a background process group against the caller's controlling terminal, a SIGTTOU signal may be generated depending how the process is handling SIGTTOUs:

Processing for SIGTTOU System Behavior
Default or signal handler The SIGTTOU signal is generated, and the function is not performed. tcdrain() returns -1 and sets errno to EINTR.
Ignored or blocked The SIGTTOU signal is not sent, and the function continues normally.

Returned value

If successful, tcdrain() returns 0.

If unsuccessful, tcdrain() returns -1 and sets errno to one of the following values:
Error Code
Description
EBADF
fildes is not a valid open file descriptor.
EINTR
A signal interrupted tcdrain().
EIO
The process group of the process issuing the function is an orphaned, background process group, and the process issuing the function is not ignoring or blocking SIGTTOU.
ENOTTY
fildes is not associated with a terminal.

Example

CELEBT03
⁄* CELEBT03  *⁄

#define _POSIX_SOURCE
#include <termios.h>
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys⁄stat.h>

main() {
  char Master[]="master.tty";
  char Slave[]="slave.tty";
  char text[]="text to be written to tty";
  char data[80];
  int  master, slave;
  time_t T;

  if (mknod(Master, S_IFCHR|S_IRUSR|S_IWUSR, 0x00010000 + 10) !=0)
    perror("mknod() error for master tty");
  else {
    if (mknod(Slave, S_IFCHR|S_IRUSR|S_IWUSR, 0x00020000 + 10) !=0)
      perror("mknod() error for slave tty");
    else {
      if ((master = open(Master, O_RDWR|O_NONBLOCK)) < 0)
        perror("open() error for master tty");
      else {
        if ((slave = open(Slave, O_RDWR|O_NONBLOCK)) < 0)
          perror("open() error for slave tty");
        else {
          if (fork() == 0) {
            if (write(slave, text, strlen(text)+1) == -1)
              perror("write() error");
            time(&T);
            printf("child has written to tty, tcdrain() started at %s",
                   ctime(&T));
            if (tcdrain(slave) != 0)
              perror("tcdrain() error");
            time(&T);
            printf("tcdrain() returned at %s", ctime(&T));
            exit(0);
          }
          time(&T);
          printf("parent is starting nap at %s", ctime(&T));
          sleep(5);
          time(&T);
          printf("parent is done with nap at %s", ctime(&T));
          if (read(master, data, sizeof(data)) == -1)
            perror("read() error");
          else printf("read '%s' from the tty\n", data);
          sleep(5);
          close(slave);
        }
        close(master);
      }
      unlink(Slave);
    }
    unlink(Master);
  }
}
Output
parent is starting nap at Fri Jun 16 12:46:28 2001
child has written to tty, tcdrain() started at Fri Jun 16 12:46:28 2001
parent is done with nap at Fri Jun 16 12:46:34 2001
read 'text to be written to tty' from the tty
tcdrain() returned at Fri Jun 16 12:46:34 2001

Related information