moving pty master by dup()/close() causes read() to fail

Jun T.
Mon Dec 16 13:21:00 GMT 2013

Hi all. I'm new to this list.

The test code at the end of this post has some problem on Cygwin.
What the code does are:
  use forkpty() to open pty master (and slave for child),
  write a character 'A' to the slave,
  duplicate the master file descriptor,
  and read() from the (duplicated) master.

If I run this code on either cygwin or cygwin64, I get:

$ ./a.exe
c = A
$ ./a.exe foo      # any argument is OK. just to make argc>1
read: Bad file descriptor

If no arg is given (argc=1) then the read() succeeds, while
if argc>1, in which case **the original master is closed**,
then read() fails with "Bad file descriptor".

Am I doing something stupid?

The code runs normally (read() never fails) on Linux and Mac OS X.
I tried dup2() or fcntl(oldfd,F_DUPFD) to no avail. Also tried
open("/dev/ptmx") to open the master but it didn't work either.

#include <stdio.h>
#ifdef __APPLE__
#include <util.h>
#include <pty.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char* argv[])
    int fd;
    pid_t pid = forkpty(&fd, 0, 0, 0);
    if(pid < 0) {
        return 1;
    else if(pid==0) {   /* child */
        write(1, "A", 1);
    else {              /* parent */
        char c;
        int oldfd = fd;
        fd = dup(oldfd);
        if(fd < 0) {
            return 2;
        if(argc > 1)
            close(oldfd); /* this causes a trouble */

        if(read(fd, &c, 1) == 1)
            fprintf(stderr, "c = %c\n", c);
        return 0;

Problem reports:
Unsubscribe info:

More information about the Cygwin mailing list