Not able to read data from other terminal using re

2019-08-28 19:55发布

问题:

Hi everyone I am running the following code on pseudo terminal /dev/pts/1 and I am tryin to read the contents from the terminal /dev/pts/2.

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

int main(){

char str[50];

int fd = open("/dev/pts/2",O_RDONLY);
str[read(fd,str,20)] = '\0';

printf("%s\n",str);


return 0;

}

anirudh@anirudh-Aspire-5920:~$ gcc test.c
anirudh@anirudh-Aspire-5920:~$ ./a.out
n
anirudh@anirudh-Aspire-5920:~$ 

On the terminal /dev/pts/2 I had typed "anirudh" however it showed "airudh" on that and the missing character n was displayed on the terminal /dev/pts/1. However when I try to read from the terminal /dev/pts/1 I can read every character properly. So I am not able to understand the behavior of this program. Please help me out. Thanks in advance. :)

回答1:

First, you probably have another process reading from /dev/pts/2 and thus characters are send to it and not yours. Then the terminal is probably set in read "char per char" mode by that other process (that's what some shell do), you are reading just one character.



回答2:

Wow. First, it is a general good rule: check what syscalls are returned to you. Alaways.

int main(){

    char str[50];

    int fd = open("/dev/pts/2",O_RDONLY);
    if (fd == -1) {
        perror("open");
        ...
    }

Second, read may return fewer bytes than you request, look at the man:

It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal.

So even 1 byte may be returned from read. Third, read may return -1:

On error, -1 is returned, and errno is set appropriately.

So I guess it's better to write:

    ssize_t nread;
    if ((nread = read(fd, str, 20) > 0)) {
       str[nread] = '\0';
    } else if (nread == -1) {
       perror("read");
       ...
    }

    printf("%s\n",str);
    return 0;
}