tags:

views:

52

answers:

1
+3  Q: 

Reading from a pty

I'd like to receive (and later process) write(1) and wall(1) messages using a (Unix 98-style) pseudo tty on Linux. I already have the following minimal implementation:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <utempter.h>

#define BUF_LENGTH 1024

int
main (void)
{
    FILE *lf;
    int masterfd, slavefd;
    char *slave_name = NULL;
    char buf[BUF_LENGTH];
    size_t nbytes = sizeof(buf);
    ssize_t bytes_read;
    int exit_code = EXIT_SUCESS;

    if ((masterfd = posix_openpt (O_RDWR | O_NOCTTY)) == -1 
            || grantpt (masterfd) == -1
            || unlockpt (masterfd) == -1
            || (slave_name = ptsname (masterfd)) == NULL)
        exit (EXIT_FAILURE);

    if (!(lf = fopen("term.log","w")))
        exit (EXIT_FAILURE);

    addToUtmp (slave_name, NULL, masterfd);

    for (;;)
    {
        bytes_read = read(masterfd, buf, nbytes);
        if (bytes_read <= 0)
            break
        fwrite (buf, 1, bytes_read, lf);
    }

    if (bytes_read < 0)
    {
        fprintf (stderr, "error reading from master pty: %s\n", strerror (errno));
        exit_code = EXIT_FAILURE;
    }

    fclose (lf);
    if (slavefd >= 0)
        close (slavefd);
    if (masterfd >= 0)
    {
        removeLineFromUtmp (slave_name, masterfd);
        close (masterfd);
    }
    exit (exit_code);
}

The problem is now that it only works for reading the first message, then read gives me a EIO error. Why is that?

+1  A: 

It looks like this happens simply when the last slave file descriptor is closed. Considering write(1) and wall(1) will have the only file descriptor to the slave, you get EIO as soon as those finish writing.

The easiest way to keep this from happening is by keeping a file descriptor around. Right after your ptsname call, do an open(slave_name, O_RDRW).

(Curiously, you already have a slavefd variable, and the code to clean it up. Are you testing us? :p)

Shtééf
D'oh, I must have accidentally deleted the open line while experimenting (as you noticed the fd variable and cleanup is already in there). Thanks a lot, another pair of eyes can sometimes be very helpful:)
gber