Why _read() function of Windows cannot read from STDOUT?

123 views Asked by At

I am able to read() from STDOUT on linux,but in Windows, I can only read from STDIN and write to STDOUT.

Below is the code, I am using on Windows:

#include <io.h>  // Include for _read()
#include <stdio.h>
#include <string.h>
#include <stdio.h>

int main() {
    char buffer[256];
    int n;
    int fd = 1; // File descriptor for stdout (standard output)

    while ((n = _read(fd, buffer, sizeof(buffer) - 1)) > 0) {
        buffer[n] = '\0'; // Null-terminate the string if needed
        char* p = buffer;
        char* nl;

        while ((nl = strchr(p, '\n')) != NULL) {
            *nl = '\0'; // Null-terminate the line
            printf("Line: %s\n", p); // Process the line
            p = nl + 1; // Move to the next line
        }

        // If there's any remaining data in the buffer, process it
        if (*p != '\0') {
            printf("Remaining: %s\n", p);
        }
    }

    if (n == 0) {
        // End of input (Ctrl+Z on Windows)
        printf("End of input reached. Program exiting.\n");
    }
    else {
        perror("Error reading from stdin");
    }

    return 0;
}

The error I get is : Error reading from fd: Bad file descriptor.

But in Linux, I can give input on stdout and write to it as well. Why the behaviour is different in Windows? Is there a way, we can read from stdout on Windows using _read?

1

There are 1 answers

2
Lechatbleu13 On

I don't think using _read is a good choice, if you want your read to be non-blocking there is an option called O_NONBLOCK for read.

The function _read isn't thread safe and _read don't allow to read a fixed number of byte so read is better.

Note that when you use read in non blocking mode the read function will not wait for an input, if you wait 1 seconde until press a key the read function will have done a lot of read of 0 byte but you don't want to accept that as an input so we tchek if read return and error and if its the errno EAGAIN its just that we didn't have write any input so we just continue the loop.

#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int main() {
  char buffer[256];
  int n;
  int fd = stdout->_fileno;

  // Here we set the file descriptor to non-blocking mode using fcntl
  int flags = fcntl(fd, F_GETFL, 0);
  flags |= O_NONBLOCK;
  fcntl(fd, F_SETFL, flags);

  while (1) {
    n = read(fd, buffer, sizeof(buffer) - 1);
    if (n == -1) {
      if (errno == EAGAIN) {
        // We don't have any data to read so we can continue
        continue;
      } else {
        perror("read");
        return 1;
      }
    } else if (n == 0) {
      // End of input
      printf("End of input reached. Program exiting.\n");
      return 0;
    }

    buffer[n] = '\0';
    char* p = buffer;
    char* nl;

    while ((nl = strchr(p, '\n')) != NULL) {
      *nl = '\0';
      printf("Line: %s\n", p);
      p = nl + 1;
    }

    // Its possible that we have a partial line left in the buffer
    if (*p != '\0') {
      printf("Remaining: %s\n", p);
    }
  }

  return 0;
}```