How to prevent buffer overflow in C / C ++?

I use the following code to redirect stdout to a pipe, then read all the data from the pipe to the buffer. I have 2 problems:

first problem: when I send a line (after redirection) more than the BUFF_SIZE pipe, the program stops responding (dead end or something else).

second problem: when I try to read from a pipe before something was sent to stdout. I get the same answer, the program stops responding - the _read command is stuck ...

The problem is that I do not know the amount of data that will be sent to the channel after the redirect.

The first problem, I do not know how to handle, and I will be happy for the help. The second problem, which I solved in a simple workaround, immediately after the redirection, I print a space character in stdout. but I think this solution is not correct ...

#include <fcntl.h>
#include <io.h>
#include <iostream>

#define READ 0
#define WRITE 1
#define BUFF_SIZE 5

using namespace std;

int main()
{

  int stdout_pipe[2];
  int saved_stdout;

  saved_stdout = _dup(_fileno(stdout));            // save stdout 

  if(_pipe(stdout_pipe,BUFF_SIZE, O_TEXT) != 0 )   // make a pipe
  {    
    exit(1);
  }

  fflush( stdout );

  if(_dup2(stdout_pipe[1], _fileno(stdout)) != 0 ) //redirect stdout to the pipe 
  { 
    exit(1);
  }

  ios::sync_with_stdio();    
  setvbuf( stdout, NULL, _IONBF, 0 );

  //anything sent to stdout goes now to the pipe
  //printf(" ");//workaround for the second problem

  printf("123456");//first problem

  char buffer[BUFF_SIZE] = {0};
  int nOutRead = 0;
  nOutRead = _read(stdout_pipe[READ], buffer, BUFF_SIZE); //second problem
  buffer[nOutRead] = '\0';

  // reconnect stdout

  if (_dup2(saved_stdout, _fileno(stdout)) != 0 ) 
  {        
         exit(1);
  }
  ios::sync_with_stdio();

  printf("buffer: %s\n", buffer);
  }
+3
source share
3 answers

Your problem is that you are using blocking I / O calls and both ends of the channel are connected to the same process. If you don’t know how much data will be, it will be just a dead end waiting for this to happen.

printf - , , , ( ) (, ).
_read . , , ( ).

:

  • - ( , , printf),
  • .
+1

. . (x), .

, ( C, ++):

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

int main(int argc)
{
    int pfds[2];

    pipe(pfds);

    if (!fork()) {
        close(1);       /* close stdout, check for errors */
        dup(pfds[1]);   /* make stdout same as pfds[1], dup reuses lowest fd */
        close(pfds[0]); /* not needed */
        execlp("ls", "ls", NULL); /* or write() in whatever way you want */
    } else {
        close(0);       /* close stdin, check for errors please! */
        dup(pfds[0]);   /* make stdin same as pfds[0] */
        close(pfds[1]); /* not needed on this end */
        execlp("wc", "wc", "-l", NULL); /* or read() */
    }

    return 0;
}

[edit] , . , ... read() , sizeof buffer, .

+1

You should use non-blocking I / O if you do not want the read or write to be blocked in this case.

0
source

Source: https://habr.com/ru/post/1784927/


All Articles