This file is indexed.

/usr/include/assa-3.5/assa/Fork.h is in libassa3.5-5-dev 3.5.1-4.

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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
// -*- c++ -*-
//------------------------------------------------------------------------------
//                             Fork.h
//------------------------------------------------------------------------------
//  Copyright (C) 1997-2002,2005  Vladislav Grinchenko
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Library General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//------------------------------------------------------------------------------
#ifndef IS_FORK_H
#define IS_FORK_H

#include <unistd.h>		// fork
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <signal.h>

#ifndef WIN32
#    include <sys/wait.h>
#endif

#include <list>
using std::list;

/* Sun Solaris 2.6 has wait4(3C) function definition missing
 * from its header files. The function, however, is in the
 * standard library. Testing this scenario would require
 * writing custom m4 macro.
 */
#if defined(__sun)
#include <sys/time.h>
#include <sys/resource.h>
extern "C" pid_t
wait4(pid_t pid, int *statusp, int options, struct rusage *rusage);
#endif


#include "assa/Assure.h"
#include "assa/Singleton.h"
#include "assa/EventHandler.h"
#include "assa/SigHandler.h"
#include "assa/SigAction.h"

namespace ASSA {

/** @file Fork.h

    @brief A simple wrapper around fork() library function call.
*/

/** @class ChildStatusHandler

    @brief A helper class of Fork
*/
class ChildStatusHandler : public EventHandler
{
public:
	ChildStatusHandler ()
		: m_exit_status (-1), m_caught (false) { /* no-op */ }

	int handle_signal (int signum_);

	/** @return -1 if failed on wait(); otherwise an exit status of
		the child process as returned by either RETURN or EXIT
	*/
	int exit_status () const { return m_exit_status; }

	/** @return true if the signal has been caught; false otherwise
	 */
	bool caught () const { return m_caught; }

private:
	int m_exit_status;
	bool m_caught;
};

/** @class Fork

    @brief Fork class is a simple wrapper around C library function fork().
           Main advantage of using Fork over fork() is that child termination
           process is handles internally by Fork class static destructor.
*/
class Fork {
public:
	/** @enum state_t
	   Child completion states.
	*/
	enum state_t {
		KILL_ON_EXIT,			/**< Kill all childer on exit */
		WAIT_ON_EXIT,			/**< Wait for all children to exit */
		LEAVE_ALONE				/**< Ignore all running children on exit */
	};

	/** @enum wait4status_t
	 */
	enum wait4status_t {
		IGNORE_STATUS,			/**< Don't wait for child to complete */
		COLLECT_STATUS			/**< Wait for child to complete and collect its
								   exit status */
	};

#if !defined(WIN32)
	/**
	 *  Fork the current process in two immediately.
	 *
	 *  @param exit_action_  Specify (default=WAIT_ON_EXIT) whether to wait
	 *                       for the child to finish or kill it with SIGTERM
	 *                       on process exit.
	 *
	 *  @param catch_status_ If true (default=COLLECT_STATUS), pause for the
	 *                       child to exit and collect its exit status.
	 */
	Fork (state_t exit_action_ = WAIT_ON_EXIT,
		  wait4status_t catch_status_ = COLLECT_STATUS);

	/**
	 *  Destructor. Doesn't really do anything. All children
	 *  will be terminated according to state set when
	 *  process terminates.
	 */
	~Fork() { trace_with_mask("Fork::~Fork",FORK); }

	/**
	 *  Test whether we are in parent section of the code.
	 *  @return true if it is parent code, false otherwise
	 */
	bool isParent() const { return m_pid ? true : false; }

	/**
	 *  Test whether we are in child section of the code.
	 *  @return true if it is parent code, false otherwise
	 */
	bool isChild() const { return !m_pid ? true : false; }

	/**
	 *  Retrieve child process id.
	 *  @return child pid
	 */
	pid_t getChildPID() const {
		trace_with_mask("Fork::getChildPID",FORK);
		return m_pid;
	}

	/**
	 *  Retrieve exit status of a child process if the constructor's
	 *  parameter catch_status_ was set to TRUE.
	 */
	int get_exit_status () const { return m_chstath.exit_status (); }

#endif // !defined(WIN32)

	/**
	 *  Execute an external command.
	 *  Conveniently wraps fork()/execvp()/wait() sequence of calls.
	 *
	 *  @param cmd_                  Command to execute.
	 *  @param args_                 Command arguments as one string.
	 *  @param wait_for_completion_  If set to true, blocks until child exits;
	 *                               false otherwise.
	 *  @param ignore_output_        Discard child's output to stdout/stderr.
	 *
	 *  @return If wait_for_completion_ is false, returns child PID;
	 *          If wait_for_completion_ is true, returns command exit status:
	 *          0 returned means that command succeeded; 1 that it failed;
	 *          -1 that wait(2) failed (where it shouldn't).
	 */
	static int fork_exec (const string& cmd_,
						  const string& args_,
						  wait4status_t wait_for_completion_,
		                  bool ignore_output_ = false);

#if !defined(WIN32)
private:
	/// Child pid
	pid_t m_pid;

	/// Local signal handler
	SigHandler m_local_sh;

	/// Handler to catch Child's status
	ChildStatusHandler m_chstath;

	/// Old signal disposition
	SigAction m_old_disp;

#endif // !defined(WIN32)

};

/**  forknode_t class.
*/
class fnode_t {
public:
	/// Constructor.
	fnode_t (pid_t pid_, Fork::state_t state_)
		: m_pid(pid_), m_state(state_)
		{
			trace_with_mask("fnode_t::fnode_t",FORK);
		}

	/// Retrieve child pid
	pid_t getPID() const
		{
			trace_with_mask("fnode_t::getPID",FORK);
			return m_pid;
		}

	/// Retrieve kill flag
	bool needKill() const
		{
			trace_with_mask("fnode_t::needKill",FORK);
			return  m_state == Fork::KILL_ON_EXIT ? true : false;
		}
private:
	/// Child pid
	pid_t m_pid;

	/// Child state {kill, wait}
	Fork::state_t m_state;
};

/** ForkList is a singleton class that keeps a list of all forked
 *  children. Its task is on process exit, for each child forked,
 *  either terminate it with SIGTERM or wait for its exit. In any case,
 *  child's exit status is collected thus avoiding zombie processes.
*/

class ForkList : public Singleton < ForkList >
{
public:
	/// Constructor
	ForkList () { trace_with_mask("ForkList::ForkList",FORK); }

	/// Destructor. Wipe out childer based on their state.
	~ForkList();

	/// List of children's data structures
	list< fnode_t* > m_list;
};

} // end namespace ASSA

#endif // IS_FORK_H