This file is indexed.

/usr/include/jellyfish/generator_manager.hpp is in libjellyfish-2.0-dev 2.2.4-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*  This file is part of Jellyfish.

    Jellyfish is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Jellyfish is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Jellyfish.  If not, see <http://www.gnu.org/licenses/>.
*/


#ifndef __JELLYFISH_SPAWN_EXTERNAL_HPP_
#define __JELLYFISH_SPAWN_EXTERNAL_HPP_

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <iostream>
#include <vector>
#include <map>
#include <stdexcept>

#ifdef HAVE_EXT_STDIO_FILEBUF_H
#include <ext/stdio_filebuf.h>
#define STDIO_FILEBUF_TYPE __gnu_cxx::stdio_filebuf<std::istream::char_type>
#else
#include <jellyfish/stdio_filebuf.hpp>
#define STDIO_FILEBUF_TYPE jellyfish::stdio_filebuf<std::istream::char_type>
#endif

#include <jellyfish/err.hpp>

namespace jellyfish {
// Open a path and set CLOEXEC flags
int open_cloexec(const char* path, int flags);

// Input stream (inherit from std::istream, behaves mostly like an
// ifstream), with flag O_CLOEXEC (close-on-exec) turned on.
class cloexec_istream : public std::istream
{
  static std::streambuf* open_file(const char* path) {
    int fd = open_cloexec(path, O_RDONLY);
    return new STDIO_FILEBUF_TYPE(fd, std::ios::in);
  }

public:
  cloexec_istream(const cloexec_istream&) = delete;
  cloexec_istream(const char* path) :
  std::istream((open_file(path)))
  { }
  cloexec_istream(const std::string& path) :
    std::istream(open_file(path.c_str()))
  { }
  virtual ~cloexec_istream() { close(); }
  void close() { delete std::istream::rdbuf(0); }
};


// This class is responsible for creating a tmp directory and
// populating it with fifos.
class tmp_pipes {
  static std::string create_tmp_dir();
  std::vector<std::string> create_pipes(const std::string& tmpdir, int nb_pipes);

  std::string              tmpdir_;
  std::vector<std::string> pipes_;
  std::vector<const char*> pipes_paths_;

public:
  tmp_pipes(int nb_pipes):
  tmpdir_(create_tmp_dir()),
  pipes_(create_pipes(tmpdir_, nb_pipes))
  {
    for(auto it = pipes_.cbegin(); it != pipes_.cend(); ++it)
      pipes_paths_.push_back(it->c_str());
  }
  ~tmp_pipes() { cleanup(); }

  size_t size() const { return pipes_.size(); }
  const char* operator[](int i) const { return pipes_[i].c_str(); }
  std::vector<const char*>::const_iterator begin() const { return pipes_paths_.cbegin(); }
  std::vector<const char*>::const_iterator end() const { return pipes_paths_.cend(); }

  // Discard a pipe: unlink it while it is open for writing. The
  // reading process will get no data and won't be able to reopen the
  // file, marking the end of this pipe.
  void discard(int i);
  // Discard all pipes
  void cleanup();
};

// This class creates a new process which manages a bunch of
// "generators", sub-processes that writes into a fifo (named pipe)
// and generate sequence.
class generator_manager {
  cloexec_istream cmds_;
  tmp_pipes       pipes_;
  pid_t           manager_pid_;
  const char*     shell_;
  int             kill_signal_; // if >0, process has received that signal

  struct cmd_info_type {
    std::string command;
    int         pipe;
  };
  typedef std::map<pid_t, cmd_info_type> pid2pipe_type;
  pid2pipe_type pid2pipe_;

public:
  generator_manager(const char* cmds, int nb_pipes, const char* shell = 0) :
    cmds_(cmds),
    pipes_(nb_pipes),
    manager_pid_(-1),
    shell_(shell),
    kill_signal_(0)
  {
    if(!cmds_.good())
      throw std::runtime_error(err::msg() << "Failed to open cmds file '" << cmds << "'");
    if(!shell_)
      shell_ = getenv("SHELL");
    if(!shell_)
      shell_ = "/bin/sh";
  }
  ~generator_manager() { wait(); }

  const tmp_pipes& pipes() const { return pipes_; }
  pid_t pid() const { return manager_pid_; }

  // Start the manager process
  void start();
  // Wait for manager process to finish. Return true if it finishes
  // with no error, false otherwise.
  bool wait();

private:
  /// Read commands from the cmds stream. There is one command per
  /// line. Empty lines or lines whose first non-white space character
  /// is a # are ignored. Return an empty string when no more commands
  /// are available.
  std::string get_cmd();
  void start_commands();
  void start_one_command(const std::string& command, int pipe);
  bool display_status(int status, const std::string& command);
  int  setup_signal_handlers();
  void unset_signal_handlers();
  static void signal_handler(int signal);
  void cleanup();
};
}

#endif /* __JELLYFISH_SPAWN_EXTERNAL_HPP_ */