Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
Macros | Functions | Variables
rle_open_f.c File Reference
#include "rle_config.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
Include dependency graph for rle_open_f.c:

Go to the source code of this file.

Macros

#define _XOPEN_SOURCE   /* Make sure fdopen() is in stdio.h */
 
#define MAX_CHILDREN   100
 

Functions

static FILE * my_popen ()
 
FILE * rle_open_f_noexit (char *prog_name, char *file_name, char *mode)
 
FILE * rle_open_f (char *prog_name, char *file_name, char *mode)
 
void rle_close_f (FILE *fd)
 
static FILE * my_popen (char *cmd, char *mode, int *pid)
 

Variables

static int catching_children = 0
 
static int pids [100]
 

Macro Definition Documentation

#define _XOPEN_SOURCE   /* Make sure fdopen() is in stdio.h */

Definition at line 13 of file rle_open_f.c.

#define MAX_CHILDREN   100

Definition at line 27 of file rle_open_f.c.

Function Documentation

static FILE* my_popen ( )
static
static FILE* my_popen ( char *  cmd,
char *  mode,
int pid 
)
static

Definition at line 256 of file rle_open_f.c.

259 {
260  FILE *retfile;
261  int thepid = 0;
262  int pipefd[2];
263  int i;
264  char *argv[4];
265 
266  /* Check args. */
267  if ( *mode != 'r' && *mode != 'w' )
268  {
269  errno = EINVAL;
270  return NULL;
271  }
272 
273  if ( pipe(pipefd) < 0 )
274  return NULL;
275 
276  /* Flush known files. */
277  fflush(stdout);
278  fflush(stderr);
279  if ( (thepid = fork()) < 0 )
280  {
281  close(pipefd[0]);
282  close(pipefd[1]);
283  return NULL;
284  }
285  else if (thepid == 0) {
286  /* In child. */
287  /* Rearrange file descriptors. */
288  if ( *mode == 'r' )
289  {
290  /* Parent reads from pipe, so reset stdout. */
291  close(1);
292  dup2(pipefd[1],1);
293  } else {
294  /* Parent writing to pipe. */
295  close(0);
296  dup2(pipefd[0],0);
297  }
298  /* Close anything above fd 2. (64 is an arbitrary magic number). */
299  for ( i = 3; i < 64; i++ )
300  close(i);
301 
302  /* Finally, invoke the program. */
303  if ( execl("/bin/sh", "sh", "-c", cmd, NULL) < 0 )
304  exit(127);
305  /* NOTREACHED */
306  }
307 
308  /* Close file descriptors, and gen up a FILE ptr */
309  if ( *mode == 'r' )
310  {
311  /* Parent reads from pipe. */
312  close(pipefd[1]);
313  retfile = fdopen( pipefd[0], mode );
314  } else {
315  /* Parent writing to pipe. */
316  close(pipefd[0]);
317  retfile = fdopen( pipefd[1], mode );
318  }
319 
320  /* Return the PID. */
321  *pid = thepid;
322 
323  return retfile;
324 }
int i
Definition: rletorla.c:82
void rle_close_f ( FILE *  fd)

Definition at line 244 of file rle_open_f.c.

246 {
247  if ( fd == NULL || fd == stdin || fd == stdout )
248  return;
249  else
250  fclose( fd );
251 }
FILE * fd
Definition: getfb.h:18
FILE* rle_open_f ( char *  prog_name,
char *  file_name,
char *  mode 
)

Definition at line 216 of file rle_open_f.c.

218 {
219  FILE *fp;
220 
221  if ( (fp = rle_open_f_noexit( prog_name, file_name, mode )) == NULL )
222  exit( -1 );
223 
224  return fp;
225 }
FILE * rle_open_f_noexit(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:57
static Panel_item file_name
Definition: gettaac.c:59
FILE * fp
Definition: pgmtorle.c:49
FILE* rle_open_f_noexit ( char *  prog_name,
char *  file_name,
char *  mode 
)

Definition at line 57 of file rle_open_f.c.

Referenced by RLE::open:.

59 {
60  FILE *fp;
61  void perror();
62  CONST_DECL char *err_str;
63  register char *cp;
64  char *combuf;
65 
66 #ifdef STDIO_NEEDS_BINARY
67  char mode_string[32]; /* Should be enough. */
68 
69  /* Concatenate a 'b' onto the mode. */
70  mode_string[0] = mode[0];
71  mode_string[1] = 'b';
72  strcpy( mode_string + 2, mode + 1 );
73  mode = mode_string;
74 #endif
75 
76  if ( *mode == 'w' || *mode == 'a' )
77  fp = stdout; /* Set the default value */
78  else
79  fp = stdin;
80 
81  if ( file_name != NULL && strcmp( file_name, "-" ) != 0 )
82  {
83 #ifndef NO_OPEN_PIPES
84  /* Check for dead children. */
85  if ( catching_children > 0 )
86  {
87  int i, j;
88 
89  /* Check all children to see if any are dead, reap them if so. */
90  for ( i = 0; i < catching_children; i++ )
91  {
92  /* The assumption here is that if it's dead, the kill
93  * will fail, but, because we haven't waited for
94  * it yet, it's a zombie.
95  */
96  if (kill(pids[i], 0) < 0) {
97  int opid = pids[i], pid = 0;
98  /* Wait for processes & delete them from the list,
99  * until we get the one we know is dead.
100  * When removing one earlier in the list than
101  * the one we found, decrement our loop index.
102  */
103  while (pid != opid) {
104  pid = wait( NULL );
105  for ( j = 0;
106  j < catching_children && pids[j] != pid;
107  j++ )
108  ;
109 #ifdef DEBUG
110  fprintf( stderr, "Reaping %d at %d for %d at %d\n",
111  pid, j, opid, i );
112  fflush( stderr );
113 #endif
114  if ( pid < 0 )
115  break;
116  if ( j < catching_children ) {
117  if ( i >= j )
118  i--;
119  for ( j++; j < catching_children; j++ )
120  pids[j-1] = pids[j];
121  catching_children--;
122  }
123  }
124  }
125  }
126  }
127 
128  /* Real file, not stdin or stdout. If name ends in ".Z",
129  * pipe from/to un/compress (depending on r/w mode).
130  *
131  * If it starts with "|", popen that command.
132  */
133 
134  cp = file_name + strlen( file_name ) - 2;
135  /* Pipe case. */
136  if ( *file_name == '|' )
137  {
138  int thepid; /* PID from my_popen */
139  if ( (fp = my_popen( file_name + 1, mode, &thepid )) == NULL )
140  {
141  err_str = "%s: can't invoke <<%s>> for %s: ";
142  goto err;
143  }
144  /* One more child to catch, eventually. */
145  if (catching_children < MAX_CHILDREN) {
146 #ifdef DEBUG
147  fprintf( stderr, "Forking %d at %d\n",
148  thepid, catching_children );
149  fflush( stderr );
150 #endif
151  pids[catching_children++] = thepid;
152  }
153  }
154 
155  /* Compress case. */
156  else if ( cp > file_name && *cp == '.' && *(cp + 1) == 'Z' )
157  {
158  int thepid; /* PID from my_popen. */
159  combuf = (char *)malloc( 20 + strlen( file_name ) );
160  if ( combuf == NULL )
161  {
162  err_str = "%s: out of memory opening (compressed) %s for %s";
163  goto err;
164  }
165 
166  if ( *mode == 'w' )
167  sprintf( combuf, "compress > %s", file_name );
168  else if ( *mode == 'a' )
169  sprintf( combuf, "compress >> %s", file_name );
170  else
171  sprintf( combuf, "compress -d < %s", file_name );
172 
173  fp = my_popen( combuf, mode, &thepid );
174  free( combuf );
175 
176  if ( fp == NULL )
177  {
178  err_str =
179  "%s: can't invoke 'compress' program, trying to open %s for %s";
180  goto err;
181  }
182  /* One more child to catch, eventually. */
183  if (catching_children < MAX_CHILDREN) {
184 #ifdef DEBUG
185  fprintf( stderr, "Forking %d at %d\n", thepid, catching_children );
186  fflush( stderr );
187 #endif
188  pids[catching_children++] = thepid;
189  }
190  }
191 
192  /* Ordinary, boring file case. */
193  else
194 #endif /* !NO_OPEN_PIPES */
195  if ( (fp = fopen(file_name, mode)) == NULL )
196  {
197  err_str = "%s: can't open %s for %s: ";
198  goto err;
199  }
200  }
201 
202  return fp;
203 
204 err:
205  fprintf( stderr, err_str,
206  prog_name, file_name,
207  (*mode == 'w') ? "output" :
208  (*mode == 'a') ? "append" :
209  "input" );
210  perror( "" );
211  return NULL;
212 
213 }
static int catching_children
Definition: rle_open_f.c:28
#define CONST_DECL
Definition: rle_config.h:42
#define MAX_CHILDREN
Definition: rle_open_f.c:27
static Panel_item file_name
Definition: gettaac.c:59
static int pids[100]
Definition: rle_open_f.c:29
FILE * fp
Definition: pgmtorle.c:49
void * malloc()
int i
Definition: rletorla.c:82
static FILE * my_popen()

Here is the caller graph for this function:

Variable Documentation

int catching_children = 0
static

Definition at line 28 of file rle_open_f.c.

int pids[100]
static

Definition at line 29 of file rle_open_f.c.