File: ext_proc.c

package info (click to toggle)
swish++ 1.1b3-3
  • links: PTS
  • area: main
  • in suites: slink
  • size: 416 kB
  • ctags: 409
  • sloc: ansic: 2,842; makefile: 247; sh: 48
file content (123 lines) | stat: -rw-r--r-- 3,133 bytes parent folder | download
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
/*
**	SWISH++
**	ext_proc.c
**
**	Copyright (C) 1998  Paul J. Lucas
**
**	This program 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 2 of the License, or
**	(at your option) any later version.
** 
**	This program 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 this program; if not, write to the Free Software
**	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

// standard
#include <cstdlib>
#include <sys/wait.h>
#include <unistd.h>

// local
#include "config.h"
#include "ext_proc.h"

#ifndef	PJL_NO_NAMESPACES
using namespace std;
#endif

extern char const	*me;

//*****************************************************************************
//
// SYNOPSIS
//
	ext_proc_map::ext_proc_map()
//
// DESCRIPTION
//
//	Construct (initialize) an ext_proc_map.  The entries in
//	ext_proc_table[] MUST be full paths.
//
// SEE ALSO
//
//	extract.c	do_file()
//
//*****************************************************************************
{
	struct ext_proc {
		char const *extension;
		char const *undo;
		char const *redo;
	};
	static ext_proc const ext_proc_table[] = {
		"Z",	"/bin/uncompress",		"/usr/bin/compress",
		"gz",	"/bin/gunzip",          "/bin/gzip",
		"bz2",  "/usr/bin/bunzip2",	"/usr/bin/bzip2",
		0
	};

	for ( register ext_proc const *e = ext_proc_table; e->extension; ++e )
		map_[ e->extension ] = value_type( e->undo, e->redo );
}

//*****************************************************************************
//
// SYNOPSIS
//
	bool process_file( char const *path_name, char const *file_name )
//
// DESCRIPTION
//
//	Process a file with another command by forking, execing, and waiting
//	for it to complete.
//
// RETURN VALUE
//
//	Returns true only if the file was processed successfully.
//
// SEE ALSO
//
//	exec(2), fork(2), wait(2), wstat(5)
//
//*****************************************************************************
{
	static pid_t const pid_error = STATIC_CAST( pid_t )( -1 );
	pid_t child_pid;
	int attempt_count = 0;

	while ( ( child_pid = ::fork() ) == pid_error ) {
		//
		// Try to fork a few times before giving up in case the system
		// is temporarily busy.
		//
		if ( ++attempt_count > Fork_Attempts ) {
			cerr << me << ": could not fork" << endl;
			::exit( 2 );
		}
		::sleep( Fork_Sleep );
	}

	if ( !child_pid ) {				// child process
		::execl( path_name, path_name, file_name, 0 );
		cerr << me << ": can not exec " << path_name << endl;
		::exit( 3 );
	}

	int child_stat;
	if ( ::wait( &child_stat ) == pid_error ) {
		cerr << me << ": error waiting for child process" << endl;
		::exit( 4 );
	}
	if ( WIFEXITED( child_stat ) && WEXITSTATUS( child_stat ) ) {
		cerr << me << ": child process terminated abnormally" << endl;
		::exit( 5 );
	}
	return true;
}