I'm on my way to create a simple terminal. I have the following code to test bidirectional piping, where the parent process should only attempt to write when the child process expects it, however at the moment it doesn't even output anything. I guessed there might be something wrong with mixing read/write and scanf/printf being not buffered the first method, so I modified them to be buffered with fdopen, although I would prefer using simple read/write at the parent process.
Can you help me fix this code to achieve the main goal (eg. with returning true in can_write if the child expects an input)?
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
bool can_write(int parent_write)
{
return true;
}
int main()
{
int a[2], b[2], parent_read, parent_write, child_read, child_write;
char output[11] = {0};
pipe(a);
pipe(b);
parent_read = a[0];
child_write = a[1];
child_read = b[0];
parent_write = b[1];
FILE *parent_write_file = fdopen(parent_write, "w");
FILE *parent_read_file = fdopen(parent_read, "r");
if (fork() == 0) {
char message[5] = {0};
close(parent_read);
close(parent_write);
dup2(child_read, STDIN_FILENO);
dup2(child_write, STDOUT_FILENO);
//sleep(1);
scanf("%4s", message);
printf("%s %s\n", message, message);
close(child_read);
close(child_write);
exit(0);
}
fcntl(parent_read, F_SETFL, fcntl(parent_read, F_GETFL, 0) | O_NONBLOCK);
close(child_read);
close(child_write);
while(1) {
if (can_write(parent_write)) {
fprintf(parent_write_file, "test");
//write(parent_write, "test", 4);
}
//if (read(parent_read, output, 10) > 0) {
if (fread(output, 1, 10, parent_read_file) > 0) {
printf("%s\n", output);
exit(0);
}
}
}
poll()orselect()are useful for this.scanf("%s", message);, the unbounded%sspecifier is as dangerous asgets. To avoid buffer overflows, limit the length (buffer size minus one:%4s), or usefgets.