Vaucanson  1.4.1
out_display.hxx
Go to the documentation of this file.
1 // out_display.hxx: this file is part of the Vaucanson project.
2 //
3 // Vaucanson, a generic library for finite state machines.
4 //
5 // Copyright (C) 2005, 2006, 2007, 2011 The Vaucanson Group.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // The complete GNU General Public Licence Notice can be found as the
13 // `COPYING' file in the root directory.
14 //
15 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
16 //
17 
26 #ifndef VCSN_TOOLS_OUT_DISPLAY_HXX
27 # define VCSN_TOOLS_OUT_DISPLAY_HXX
28 
30 # include <sys/types.h>
31 # include <sys/wait.h>
32 # include <unistd.h>
33 
34 namespace vcsn {
35 
36  namespace tools {
37 
38  template <class S, class T>
39  bool
40  out_display(const AutomataBase<S>&,
41  const T&,
42  const Element<S, T>& a,
43  const std::string& name,
44  const bool bg,
45  const char *const argv[],
46  void (*function)(std::ostream& o,
47  const Element<S, T>& a,
48  const std::string& name))
49 
50  {
51  int filedes[2];
52  if (pipe(filedes))
53  return false;
54 
55  pid_t child_pid = fork();
56  if (child_pid)
57  {
58  close(filedes[0]);
59  if (child_pid == -1)
60  {
61  close(filedes[1]);
62  return false;
63  }
64  else
65  {
66  // FIXME: That trick is dirty!
67  {
68  std::cout.flush();
69  int old = dup(STDOUT_FILENO);
70  if (old != -1)
71  dup2(filedes[1], STDOUT_FILENO);
72  close(filedes[1]);
73 
74  function(std::cout, a, name);
75 
76  if (old != -1)
77  {
78  dup2(old, STDOUT_FILENO);
79  close(old);
80  }
81  }
82  return bg or waitpid(child_pid, NULL, 0) == child_pid;
83  }
84  }
85  else
86  {
87  close(filedes[1]);
88  dup2(filedes[0], STDIN_FILENO);
89  close(filedes[0]);
90  // execvp will treat its second argument as if it was
91  // "const char* const*". See the following page for an
92  // explanation of why it is only declared as "char* const*".
93  // http://www.opengroup.org/onlinepubs/000095399/functions/exec.html
94  execvp(argv[0], const_cast<char *const *>(argv));
95  std::cerr << "Failed to execute `" << argv[0] << "'." << std::endl;
96  exit(1);
97  }
98  }
99 
100  } // End of namespace tools.
101 
102 } // End of namespace vcsn.
103 
104 #endif // ! VCSN_TOOLS_OUT_DISPLAY_HXX