00001
00002 #include "PreProcessFilter.h"
00003
00004 #include <iostream>
00005 #include <cstdlib>
00006 #include <unistd.h>
00007 #include <csignal>
00008
00009 #if defined(__GLIBCXX__) || defined(__GLIBCPP__)
00010
00011 #include "Fdstream.h"
00012
00013 using namespace std;
00014
00015 #define CHILD_STDIN_READ pipefds_input[0]
00016 #define CHILD_STDIN_WRITE pipefds_input[1]
00017 #define CHILD_STDOUT_READ pipefds_output[0]
00018 #define CHILD_STDOUT_WRITE pipefds_output[1]
00019 #define CHILD_STDERR_READ pipefds_error[0]
00020 #define CHILD_STDERR_WRITE pipefds_error[1]
00021
00022 namespace MosesTuning
00023 {
00024
00025
00026
00027 void exec_failed (int sig)
00028 {
00029 cerr << "Exec failed. Child process couldn't be launched." << endl;
00030 exit (EXIT_FAILURE);
00031 }
00032
00033 PreProcessFilter::PreProcessFilter(const string& filterCommand)
00034 : m_toFilter(NULL),
00035 m_fromFilter(NULL)
00036 {
00037 #if defined __MINGW32__
00038
00039 #else
00040
00041
00042 struct sigaction action;
00043 action.sa_handler = exec_failed;
00044 sigemptyset(&action.sa_mask);
00045 action.sa_flags = 0;
00046 if (sigaction(SIGUSR1, &action, NULL) < 0) {
00047 perror("SIGUSR1 install error");
00048 exit(EXIT_FAILURE);
00049 }
00050
00051 int pipe_status;
00052 int pipefds_input[2];
00053 int pipefds_output[2];
00054
00055
00056
00057
00058
00059
00060 pipe_status = pipe(pipefds_input);
00061 if (pipe_status == -1) {
00062 perror("Error creating the pipe");
00063 exit(EXIT_FAILURE);
00064 }
00065
00066 pipe_status = pipe(pipefds_output);
00067 if (pipe_status == -1) {
00068 perror("Error creating the pipe");
00069 exit(EXIT_FAILURE);
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 pid_t pid;
00082
00083 pid = fork();
00084
00085 if (pid == pid_t(0)) {
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 dup2 (CHILD_STDIN_READ,0);
00097 dup2 (CHILD_STDOUT_WRITE,1);
00098
00099
00100 close(CHILD_STDIN_WRITE);
00101 close(CHILD_STDOUT_READ);
00102
00103
00104
00105 execl("/bin/bash", "bash", "-c", filterCommand.c_str() , (char*)NULL);
00106
00107
00108
00109 kill(getppid(), SIGUSR1);
00110 exit(EXIT_FAILURE);
00111 } else if (pid > pid_t(0)) {
00112
00113
00114
00115 close(CHILD_STDIN_READ);
00116 close(CHILD_STDOUT_WRITE);
00117
00118
00119 m_toFilter = new ofdstream(CHILD_STDIN_WRITE);
00120 m_fromFilter = new ifdstream(CHILD_STDOUT_READ);
00121 } else {
00122 perror("Error: fork failed");
00123 exit(EXIT_FAILURE);
00124 }
00125 #endif // defined
00126 }
00127
00128 string PreProcessFilter::ProcessSentence(const string& sentence)
00129 {
00130 *m_toFilter << sentence << "\n";
00131 string processedSentence;
00132 m_fromFilter->getline(processedSentence);
00133 return processedSentence;
00134 }
00135
00136 PreProcessFilter::~PreProcessFilter()
00137 {
00138 delete m_toFilter;
00139 delete m_fromFilter;
00140 }
00141
00142 }
00143
00144 #endif