У меня возникли проблемы с реализацией моей трубы. Он считывает команды терминала Unix из текстового файла для таких команд, как «ls | wc», где он открывает канал, так что вывод ls может использоваться для wc.Реализация трубы в C++
Я реализовал его для разбора имен программ («ls», «wc») и сохранил их в двух отдельных массивах (аргументы и аргументы2), разыграл дочерний процесс, а затем у этого дочернего вилка был еще один дочерний процесс, затем второй дочерний процесс вызывает команду execvp() и передает первую исполняемую программу.
Выход из («ls») записывается в трубу путем изменения стандартного выхода. Первый дочерний процесс, а затем execvp() - другой процесс («wc») и считывает из канала, изменяя стандартный ввод.
Однако wc петли бесконечно и, кажется, не подсчитывают количество слов из ls. Ls выполняется в каталоге, где есть слова, которые нужно пересчитать.
Любые советы? Большое вам спасибо и извините за длинное объяснение.
Вот еще один пример: он вилки, создает трубу и реализует «ls» и записывает свой вывод в трубу, возвращается к родительскому и считывает из канала вывод «ls». Кажется, он все время читает или не работает правильно.
//
// main.cpp
// Pipe_Test
//
// Created by Dillon Sheffield on 9/28/15.
// Copyright © 2015 Dillon Sheffield. All rights reserved.
//
#include <iostream>
using namespace std;
int main()
{
char* arguments[2];
char* programArguments[1];
int fd[2];
arguments[0] = new char[2];
arguments[1] = new char[2];
programArguments[0] = new char[1];
programArguments[0][0] = '\0';
string ls = "ls";
string wc = "wc";
for (int i = 0; i < 1; i++) {
arguments[0] = &ls.at(i);
arguments[1] = &wc.at(i);
}
pid_t pid = fork();
pipe(fd);
if (pid < 0) {
perror("Failed.\n");
} else if (pid == 0) {
dup2(fd[1], STDOUT_FILENO);
execvp(arguments[0], programArguments);
}
wait(NULL);
dup2(fd[0], STDIN_FILENO);
execvp(arguments[1], programArguments);
close(0);
close(1);
return 0;
}
Вот мой исходный код:
//
// main.cpp
// homework2
//
// Created by Dillon Sheffield on 9/19/15.
// Copyright © 2015 Dillon Sheffield. All rights reserved.
//
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
// Global Variable(s)
const short inputLineSize = 10; // Size of programName, arguments, and argument name.
char *arguments[inputLineSize];
char *arguments2[inputLineSize];
ifstream inputFile;
char* input;
void readLine()
{
// Create new char array(s)
input = new char[inputLineSize];
// Initialize the char array(s)
for (int i = 0; i < inputLineSize; i++)
{
input[i] = '\0';
}
// Read a line and skip tabs, spaces, and new line characters
for (int i = 0; !inputFile.eof() && inputFile.peek() != '\n'; i++)
{
while (inputFile.peek() == '\n' || inputFile.peek() == '\t' || inputFile.peek() == ' ') inputFile.get();
inputFile.get(input[i]);
}
// If the file is multi-spaced, keep reading new line char(s) to clear them
while (inputFile.peek() == '\n') inputFile.get();
}
void parseTokens()
{
//----------Parse the read line into tokens--------------------------------------------//
// Get the program name
for (int i = 0; i < inputLineSize; i++)
{
arguments[i] = new char[inputLineSize];
for (int j = 0; j < inputLineSize; j++)
arguments[i][j] = '\0';
}
int i = 0;
int j = 0;
while (input[i] != '\0' && input[i] != '-' && input[i] != '|')
{
arguments[j][i] = input[i];
i++;
}
// Tokenize arguments if supplied
j++;
int k;
while (input[i] == '-')
{
k = 0;
arguments[j][k] = input[i];
i++;
k++;
while (input[i] != '-' && input[i] != '\0')
{
arguments[j][k] = input[i];
i++;
k++;
}
j++;
}
// Delete unused arguments
while (j < inputLineSize)
{
delete arguments[j];
arguments[j] = NULL;
j++;
}
// Check if the pipe command '|' is supplied
if (input[i] == '|')
{
i++;
// Get the other program name
for (int x = 0; x < inputLineSize; x++)
{
arguments2[x] = new char[inputLineSize];
for (int y = 0; y < inputLineSize; y++)
arguments2[x][y] = '\0';
}
int x = 0;
int j = 0;
while (input[i] != '\0' && input[i] != '-' && input[i] != '|')
{
arguments2[j][x] = input[i];
i++;
x++;
}
// Tokenize arguments if supplied
j++;
int k;
while (input[i] == '-')
{
k = 0;
arguments2[j][k] = input[i];
i++;
k++;
while (input[i] != '-' && input[i] != '\0')
{
arguments2[j][k] = input[i];
i++;
k++;
}
j++;
}
// Delete unused arguments
while (j < inputLineSize)
{
delete arguments2[j];
arguments2[j] = NULL;
j++;
}
}
}
int main()
{
// Variable(s)
pid_t pid;
pid_t pid2;
int fd[2];
//--Open the file named "input"-------------------------------------------------------//
inputFile.open("input", ios::in);
// Check if opening the file was successful
if (inputFile.is_open())
{
// Read until the file has reached the end
while (!inputFile.eof())
{
// Read a line and parse tokens
readLine();
parseTokens();
//----------Now create a new process with parsed Program Name and Arguments-----------//
// Create a pipe
pipe(fd);
// Fork
pid = fork();
if (pid < 0)
{
perror("Fork failed.\n");
return -2;
}
else if (pid == 0)
{
// Fork again
pid2 = fork();
if (pid2 < 0)
{
perror("Fork failed.\n");
return -2;
}
else if (pid2 == 0)
{
// Change standard output
if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO) perror("dup2 error to stdout.\n");
// Execute the given program
execvp(arguments[0], arguments);
}
// Change the standard input to the pipe
if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) perror("dup2 error to stdin.\n");
int returnValue = execvp(arguments2[0], arguments2);
if (returnValue == -1) perror("Error has occurred.\n");
// Close the pipe and exit
close(fd[0]);
close(fd[1]);
exit(0);
}
// Wait for the child so it doesn't become a Zombie
wait(NULL);
//----------Clean up-----------------------------------------------------------------//
delete input;
input = NULL;
int i = 0;
while (arguments[i] != NULL)
{
delete arguments[i];
arguments[i] = NULL;
i++;
}
i = 0;
}
}
else perror("Cannot open file.\n");
inputFile.close();
return 0;
}
Кажется, что вы пытаетесь выполнить сразу две сложные вещи: чтение/разбор команд unix и выполнение их с помощью вилок и труб. * Разделите * эти две вещи и испытайте их изолированно; по крайней мере, это приблизит вас к [минимальному полному примеру] (http://stackoverflow.com/help/mcve). – Beta