Welcome to mirror list, hosted at ThFree Co, Russian Federation.

PreProcessFilter.cpp « mert - github.com/moses-smt/mosesdecoder.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 7a3add789705ba1dea7d03407c3183caceb55ae8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

#include "PreProcessFilter.h"

#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <csignal>

#if defined(__GLIBCXX__) || defined(__GLIBCPP__)

#include "Fdstream.h"

using namespace std;

#define CHILD_STDIN_READ pipefds_input[0]
#define CHILD_STDIN_WRITE pipefds_input[1]
#define CHILD_STDOUT_READ pipefds_output[0]
#define CHILD_STDOUT_WRITE pipefds_output[1]
#define CHILD_STDERR_READ pipefds_error[0]
#define CHILD_STDERR_WRITE pipefds_error[1]

namespace MosesTuning
{


// Child exec error signal
void exec_failed (int sig)
{
  cerr << "Exec failed. Child process couldn't be launched." << endl;
  exit (EXIT_FAILURE);
}

PreProcessFilter::PreProcessFilter(const string& filterCommand)
  : m_toFilter(NULL),
    m_fromFilter(NULL)
{
#if defined __MINGW32__
  //TODO(jie): replace this function with boost implementation
#else
  // Child error signal install
  // sigaction is the replacement for the traditional signal() method
  struct sigaction action;
  action.sa_handler = exec_failed;
  sigemptyset(&action.sa_mask);
  action.sa_flags = 0;
  if (sigaction(SIGUSR1, &action, NULL) < 0) {
    perror("SIGUSR1 install error");
    exit(EXIT_FAILURE);
  }

  int pipe_status;
  int pipefds_input[2];
  int pipefds_output[2];
  // int pipefds_error[2];

  // Create the pipes
  // We do this before the fork so both processes will know about
  // the same pipe and they can communicate.

  pipe_status = pipe(pipefds_input);
  if (pipe_status == -1) {
    perror("Error creating the pipe");
    exit(EXIT_FAILURE);
  }

  pipe_status = pipe(pipefds_output);
  if (pipe_status == -1) {
    perror("Error creating the pipe");
    exit(EXIT_FAILURE);
  }

  /*
  pipe_status = pipe(pipefds_error);
  if (pipe_status == -1)
  {
      perror("Error creating the pipe");
      exit(EXIT_FAILURE);
  }
  */

  pid_t pid;
  // Create child process; both processes continue from here
  pid = fork();

  if (pid == pid_t(0)) {
    // Child process

    // When the child process finishes sends a SIGCHLD signal
    // to the parent

    // Tie the standard input, output and error streams to the
    // appropiate pipe ends
    // The file descriptor 0 is the standard input
    // We tie it to the read end of the pipe as we will use
    // this end of the pipe to read from it
    dup2 (CHILD_STDIN_READ,0);
    dup2 (CHILD_STDOUT_WRITE,1);
    // dup2 (CHILD_STDERR_WRITE,2);
    // Close in the child the unused ends of the pipes
    close(CHILD_STDIN_WRITE);
    close(CHILD_STDOUT_READ);
    //close(CHILD_STDERR_READ);

    // Execute the program
    execl("/bin/bash", "bash", "-c", filterCommand.c_str() , (char*)NULL);

    // We should never reach this point
    // Tell the parent the exec failed
    kill(getppid(), SIGUSR1);
    exit(EXIT_FAILURE);
  } else if (pid > pid_t(0)) {
    // Parent

    // Close in the parent the unused ends of the pipes
    close(CHILD_STDIN_READ);
    close(CHILD_STDOUT_WRITE);
    // close(CHILD_STDERR_WRITE);

    m_toFilter = new ofdstream(CHILD_STDIN_WRITE);
    m_fromFilter = new ifdstream(CHILD_STDOUT_READ);
  } else {
    perror("Error: fork failed");
    exit(EXIT_FAILURE);
  }
#endif // defined
}

string PreProcessFilter::ProcessSentence(const string& sentence)
{
  *m_toFilter << sentence << "\n";
  string processedSentence;
  m_fromFilter->getline(processedSentence);
  return processedSentence;
}

PreProcessFilter::~PreProcessFilter()
{
  delete m_toFilter;
  delete m_fromFilter;
}

}

#endif