When I am running the test for the “tail -f /tmp/bar/file-15 | head -n 5” pipeline command my tests are failing partially and I am not understanding why.
I managed to get the first part of the output right
but I am not sure how I am supposed to get the second part, because is not present in the file to begin with.
This is my code:
// Create a pipe to redirect the output of the previous command to the stdin of the next command
int inpipe[2], outpipe[2];
if (pipe(outpipe) == -1 || pipe(inpipe) == -1) {
std::cerr << "Error creating pipe" << std::endl;
return;
}
// Create a child process to execute the command
pid_t pid = fork();
if (pid < 0) {
std::cerr << "Error forking process" << std::endl;
return;
}
// Child process: execute the command
if (pid == 0) {
close(inpipe[1]); close(outpipe[0]); // Close unused pipe ends
dup2(inpipe[0], STDIN_FILENO);
dup2(outpipe[1], STDOUT_FILENO);
close(inpipe[0]); close(outpipe[1]); // Close the original pipe ends
// Prepare the argument list for execvp
std::vector<std::string> args;
std::vector<char*> argsVector;
argsVector.push_back(const_cast<char*>(command_path.c_str())); // Add the command
if (!commandData.args.empty()){
// Split the arguments by spaces and add them to the argsVector
args = split(commandData.args, ' ');
for (const auto &arg : args) {
argsVector.push_back(const_cast<char*>(arg.c_str())); // Add the argument and null-terminate it
}
}
argsVector.push_back(nullptr); // Null-terminate the argument list
execvp(command_path.c_str(), argsVector.data());
perror("execvp failed");
_exit(EXIT_FAILURE); // Exit if execvp fails
}
// Parent: write previous command output to stdin of the child process 1
close(inpipe[0]); close(outpipe[1]);
write(inpipe[1], commandData.stdinCmd.c_str(), commandData.stdinCmd.size());
close(inpipe[1]); // Close the write end of the pipe
// Read the output of the child process
char buffer[1024]; // Buffer to store the output
ssize_t bytesRead;
while ((bytesRead = read(outpipe[0], buffer, sizeof(buffer) - 1)) > 0) {
buffer[bytesRead] = '\0'; // Null-terminate the string
commandData.stdoutCmd += buffer; // Append the output to the string
if (originalCommand == "tail"){
kill(pid, SIGTERM); // Terminate the child process
}
}
close(outpipe[0]); // Close the read end of the pipe
// Wait for the child process to finish
waitpid(pid, nullptr, 0);
return;
killing the process is a temporary solution, planning to replace it with a timeout function