-3

I'm trying to write test, in which some data should be read from file descriptor, so i'm using dup and pipe functions to check this.

 int main()
{
    char    *line;
    int     out;
    int     p[2];
    char    *str;
    int     len = 50;

    str = (char *)malloc(235436);
    for (int i = 0; i < 235436; ++i)
    {
        str[i]='h';
    }
    out = dup(1);
    pipe(p);
    dup2(p[1], 1);

    write(1, str, strlen(str)); //freezes there. malloc alocates memory, i've checked this with debuger
    close(p[1]);
    dup2(out, 1);
    get_next_line(p[0], &line);


}

And for some reason this code works perfectly although it does all the same.

str = (char *)malloc(1000 * 1000);
    *str = '\0';
    while (len--)
        strcat(str, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur in leo dignissim, gravida leo id, imperdiet urna. Aliquam magna nunc, maximus quis eleifend et, scelerisque non dolor. Suspendisse augue augue, tempus");
    out = dup(1);
    pipe(p);
    dup2(p[1], 1);

    if (str)
        write(1, str, strlen(str));
    close(p[1]);
    dup2(out, 1);
    get_next_line(p[0], &line);
Vladimir
  • 294
  • 1
  • 3
  • 10

4 Answers4

2

(Assuming you fix the strlen problem - i.e. write(1, str, 235436))

You are writing to a pipe. This pipe is not being read. Therefore the write will block.

Get something to read from the pipe.

Ed Heal
  • 59,252
  • 17
  • 87
  • 127
  • So, how should i fix this? i need to invoke read from pipe before write? – Vladimir Jan 18 '19 at 15:40
  • 1
    @Vladimir You can't read from the pipe "before write", because there's nothing to read at that time. Either you need to use non-blocking I/O (and accept that `write` may then return without writing everything) or accept that it may block until read _by some other thread/process_. – Arkku Jan 18 '19 at 15:50
  • is using of another fd will improve my situation? – Vladimir Jan 18 '19 at 15:51
0

The problem is in calling the strlen function!

strlen(str)

Because you didn't set the terminator at the end of the string.

Adding the following code after the initialization loop will fix the problem:

str[235435]='\0';
HmT
  • 856
  • 8
  • 14
0

Typical strlen implementation:

size_t strlen(char *s)
{
    size_t len = 0;
    while(*s++) len++;
    return len;
}

In other words, it determines the length of a string by incrementing a pointer to the start of the string until a null-terminator is reached. Since your buffer is just a block of the character 'h' without a null-terminator, calling strlen on it has undefined behavior.

Your second code-example, where you explicitly add a null-terminator after calling malloc and then use strcat to write to the string repeatedly does not have this problem since string literals are automatically null-terminated.

Also, don't cast the result of malloc unless you need your code to be compatible with C++ as well.

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
0

I'm using pipe on linux machine. Acording to this answer i'm trying to read more bytes, than pipe can contain. So, in this situation i need to create file an operate with it.

FILE *fptr;
fptr = fopen("buffer", "rb+");
if(fptr == NULL) //if file does not exist, create it
{
    fptr = fopen("buffer", "wb");
}
Vladimir
  • 294
  • 1
  • 3
  • 10