PIPS
wrapper.c File Reference
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+ Include dependency graph for wrapper.c:

Go to the source code of this file.

Macros

#define SIZE   1024 /**buffer size */
 UNIX headers. More...
 
#define SIGNAL_TAG   "# jpips send signal to tpips "
 
#define CHECKPOINT   "CHECKPOINT"
 available tags More...
 
#define INTERRUPT   "INTERRUPT"
 
#define KILLNOW   "EXIT"
 
#define ABORTIT   "ABORT"
 
#define WRAPPER   "[tpips_wrapper] "
 
#define starts_with(s1, s2)   (strncmp(s1, s2, strlen(s2))==0) /**a la java */
 
#define tpw_check(what, comment)    tpw_log(comment), tpw_check_perror(what, comment)
 
#define KILL(pid, sig)   if (pid!=0) { tpw_check(kill(pid,sig),"kill()"); }
 

Typedefs

typedef void(* sig_handler_t) (int)
 

Functions

static void tpw_log (__attribute__((__unused__)) char *message)
 Enable log with -DLOG for debug. More...
 
static void tpw_fatal_error (char *message)
 
static void tpw_check_perror (int en, char *message)
 checks returned value for most system commands (-1 and errno set). More...
 
static void tpw_sig_handler (int sn)
 signal handler for tpips_wrapper. More...
 
static void tpw_set_sig_handlers (void)
 special handlers for tpips wrapper. More...
 
static pid_t tpw_fork_inout (void)
 fork, with stdout-stdin link kept More...
 
static char * tpw_read_line (FILE *in)
 
static void tpw_send_string_to_tpips (char *line)
 send line to tpips. More...
 
void tpips_wrapper (void)
 fork a tpips to goes on, while the current process acts as a wrapper, which forwards orders, and perform some special signal handling. More...
 

Variables

static pid_t tpips_pid = 0
 global because needed in tpw_fatal_error. More...
 
static FILE * in_from_wrapper = NULL
 
static FILE * out_to_tpips = NULL
 

Macro Definition Documentation

◆ ABORTIT

#define ABORTIT   "ABORT"

Definition at line 73 of file wrapper.c.

◆ CHECKPOINT

#define CHECKPOINT   "CHECKPOINT"

available tags

Definition at line 70 of file wrapper.c.

◆ INTERRUPT

#define INTERRUPT   "INTERRUPT"

Definition at line 71 of file wrapper.c.

◆ KILL

#define KILL (   pid,
  sig 
)    if (pid!=0) { tpw_check(kill(pid,sig),"kill()"); }

Definition at line 118 of file wrapper.c.

◆ KILLNOW

#define KILLNOW   "EXIT"

Definition at line 72 of file wrapper.c.

◆ SIGNAL_TAG

#define SIGNAL_TAG   "# jpips send signal to tpips "

Definition at line 66 of file wrapper.c.

◆ SIZE

#define SIZE   1024 /**buffer size */

UNIX headers.

Standard C headers.

Definition at line 64 of file wrapper.c.

◆ starts_with

#define starts_with (   s1,
  s2 
)    (strncmp(s1, s2, strlen(s2))==0) /**a la java */

Definition at line 77 of file wrapper.c.

◆ tpw_check

#define tpw_check (   what,
  comment 
)     tpw_log(comment), tpw_check_perror(what, comment)

Definition at line 116 of file wrapper.c.

◆ WRAPPER

#define WRAPPER   "[tpips_wrapper] "

Definition at line 75 of file wrapper.c.

Typedef Documentation

◆ sig_handler_t

typedef void(* sig_handler_t) (int)

Definition at line 120 of file wrapper.c.

Function Documentation

◆ tpips_wrapper()

void tpips_wrapper ( void  )

fork a tpips to goes on, while the current process acts as a wrapper, which forwards orders, and perform some special signal handling.

wrapper.c

the child is a new tpips, it keeps on executing... the parent just acts as a wrapper, it never returns from here.

CHILD is tpips and returns.

code for the WRAPPER starts here. the PARENT.

special handlers.

forward to tpips. how to ensure that tpips is alive? SIGCHLD and SIGPIPE are caught.

handle signals.

stop tpips on EOF.

wrapper mission done.

Definition at line 270 of file wrapper.c.

271 {
272  char * line;
273 
275 
276  /* the child is a new tpips, it keeps on executing...
277  * the parent just acts as a wrapper, it never returns from here.
278  */
279  if (tpips_pid==0) return; /* CHILD is tpips and returns. */
280 
281  /* code for the WRAPPER starts here. the PARENT.
282  */
283 
284  /* special handlers.
285  */
287 
288  while ((line = tpw_read_line(stdin)))
289  {
290  /* forward to tpips.
291  * how to ensure that tpips is alive?
292  * SIGCHLD and SIGPIPE are caught.
293  */
295 
296  /* handle signals.
297  */
299  {
300  line += strlen(SIGNAL_TAG);
301 
302  if (starts_with(line, CHECKPOINT)) {
303  KILL(tpips_pid, SIGUSR1);
304  } else if (starts_with(line, INTERRUPT)) {
305  KILL(tpips_pid, SIGINT);
306  } else if (starts_with(line, ABORTIT)) {
307  KILL(tpips_pid, SIGABRT);
308  } else if (starts_with(line, KILLNOW)) {
309  KILL(tpips_pid, SIGUSR2);
310  } else {
312  }
313  }
314  }
315 
316  /* stop tpips on EOF.
317  */
318  tpw_log("exiting...");
319  fputs("exit\n", stdout);
320  fclose(stdout);
321  KILL(tpips_pid, SIGKILL);
322 
323  exit(0); /* wrapper mission done. */
324 }
#define exit(code)
Definition: misc-local.h:54
static int line
FLEX_SCANNER.
Definition: scanner.c:852
static char * tpw_read_line(FILE *in)
Definition: wrapper.c:238
static void tpw_fatal_error(char *message)
Definition: wrapper.c:97
#define starts_with(s1, s2)
Definition: wrapper.c:77
static void tpw_set_sig_handlers(void)
special handlers for tpips wrapper.
Definition: wrapper.c:166
#define KILL(pid, sig)
Definition: wrapper.c:118
#define ABORTIT
Definition: wrapper.c:73
static void tpw_log(__attribute__((__unused__)) char *message)
Enable log with -DLOG for debug.
Definition: wrapper.c:85
static pid_t tpw_fork_inout(void)
fork, with stdout-stdin link kept
Definition: wrapper.c:190
#define INTERRUPT
Definition: wrapper.c:71
static void tpw_send_string_to_tpips(char *line)
send line to tpips.
Definition: wrapper.c:254
#define KILLNOW
Definition: wrapper.c:72
#define CHECKPOINT
available tags
Definition: wrapper.c:70
#define SIGNAL_TAG
Definition: wrapper.c:66
static pid_t tpips_pid
global because needed in tpw_fatal_error.
Definition: wrapper.c:81

References ABORTIT, CHECKPOINT, exit, INTERRUPT, KILL, KILLNOW, line, SIGNAL_TAG, starts_with, tpips_pid, tpw_fatal_error(), tpw_fork_inout(), tpw_log(), tpw_read_line(), tpw_send_string_to_tpips(), and tpw_set_sig_handlers().

Referenced by parse_arguments().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ tpw_check_perror()

static void tpw_check_perror ( int  en,
char *  message 
)
static

checks returned value for most system commands (-1 and errno set).

Definition at line 107 of file wrapper.c.

108 {
109  if (en==-1)
110  {
111  perror(message);
113  }
114 }

References tpw_fatal_error().

+ Here is the call graph for this function:

◆ tpw_fatal_error()

static void tpw_fatal_error ( char *  message)
static

Definition at line 97 of file wrapper.c.

98 {
99  fprintf(stderr, WRAPPER "fatal error: %s\n", message);
100  fflush(stderr);
101  kill(tpips_pid, SIGKILL);
102  exit(1);
103 }
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
#define WRAPPER
Definition: wrapper.c:75

References exit, fprintf(), tpips_pid, and WRAPPER.

Referenced by tpips_wrapper(), tpw_check_perror(), tpw_send_string_to_tpips(), and tpw_sig_handler().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ tpw_fork_inout()

static pid_t tpw_fork_inout ( void  )
static

fork, with stdout-stdin link kept

Returns
the created pid. should be in_from_jpips instead of stdin? what about out_to_jpips and the wrapper??? fdopen() might be of some help.

create pipe.

fork

CHILD

stdin = in_from_wrapper;

PARENT

the output might be interleaved with tpips output... maybe I should lock stderr.

Definition at line 190 of file wrapper.c.

191 {
192  int filedes[2];
193  pid_t process;
194 
195  /* create pipe.
196  */
197  tpw_check(pipe(filedes), "pipe()");
198 
199  /* fork
200  */
201  process = fork();
202  tpw_check(process, "fork()");
203 
204  if (process==0)
205  {
206  /* CHILD
207  */
208  in_from_wrapper = fdopen(filedes[0], "r");
209  if (!in_from_wrapper) tpw_check(-1, "fdopen()");
210 
211  tpw_check(dup2(filedes[0], 0), "dup2()"); /* stdin = in_from_wrapper; */
212  }
213  else
214  {
215  /* PARENT
216  */
217  out_to_tpips = fdopen(filedes[1], "w");
218  if (!out_to_tpips) tpw_check(-1, "fdopen()");
219  }
220 
221  if (process)
222  {
223  /* the output might be interleaved with tpips output...
224  * maybe I should lock stderr.
225  */
226  fprintf(stderr, WRAPPER "started, tpips pid is %d\n", (int) process);
227  fflush(stderr);
228  }
229 
230  tpw_log("tpw_fork_inout() done");
231 
232  return process;
233 }
static FILE * out_to_tpips
Definition: wrapper.c:182
#define tpw_check(what, comment)
Definition: wrapper.c:116
static FILE * in_from_wrapper
Definition: wrapper.c:181

References fprintf(), in_from_wrapper, out_to_tpips, tpw_check, tpw_log(), and WRAPPER.

Referenced by tpips_wrapper().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ tpw_log()

static void tpw_log ( __attribute__((__unused__)) char *  message)
static

Enable log with -DLOG for debug.

Definition at line 85 of file wrapper.c.

90 {
91 #if defined(LOG)
92  fprintf(stderr, WRAPPER "%s\n", message);
93  fflush(stderr);
94 #endif
95 }

References fprintf(), and WRAPPER.

Referenced by tpips_wrapper(), and tpw_fork_inout().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ tpw_read_line()

static char* tpw_read_line ( FILE *  in)
static
Returns
a line from "in", or NULL at EOF. @caution a pointer to a static buffer is returned!

Definition at line 238 of file wrapper.c.

239 {
240  static char buffer[SIZE];
241  int c=0, i=0;
242 
243  while (c != '\n' && i<SIZE-1 && (c = getc(in))!=EOF)
244  buffer[i++] = (char) c;
245 
246  if (i==0) return NULL;
247 
248  buffer[i++] = '\0';
249  return buffer;
250 }
static string buffer
Definition: string.c:113
#define SIZE
UNIX headers.
Definition: wrapper.c:64

References buffer, and SIZE.

Referenced by tpips_wrapper().

+ Here is the caller graph for this function:

◆ tpw_send_string_to_tpips()

static void tpw_send_string_to_tpips ( char *  line)
static

send line to tpips.

could send a signal to tpips to warn about the incoming command. it would be read from in_from_wrapper only.

Definition at line 254 of file wrapper.c.

255 {
256  if (!out_to_tpips)
257  tpw_fatal_error("no out_to_tpips");
258 
259  fputs(line, out_to_tpips);
260  fflush(out_to_tpips);
261 
262  /* could send a signal to tpips to warn about the incoming command.
263  * it would be read from in_from_wrapper only.
264  */
265 }

References line, out_to_tpips, and tpw_fatal_error().

Referenced by tpips_wrapper().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ tpw_set_sig_handlers()

static void tpw_set_sig_handlers ( void  )
static

special handlers for tpips wrapper.

Definition at line 166 of file wrapper.c.

167 {
168  (void) signal(SIGHUP, tpw_sig_handler);
169  (void) signal(SIGINT, tpw_sig_handler);
170  (void) signal(SIGTERM, tpw_sig_handler);
171 
172  (void) signal(SIGUSR1, tpw_sig_handler);
173  (void) signal(SIGUSR2, tpw_sig_handler);
174 
175  (void) signal(SIGQUIT, tpw_sig_handler);
176  (void) signal(SIGABRT, tpw_sig_handler);
177  (void) signal(SIGCHLD, tpw_sig_handler);
178  (void) signal(SIGPIPE, tpw_sig_handler);
179 }
static void tpw_sig_handler(int sn)
signal handler for tpips_wrapper.
Definition: wrapper.c:127

References tpw_sig_handler().

Referenced by tpips_wrapper().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ tpw_sig_handler()

static void tpw_sig_handler ( int  sn)
static

signal handler for tpips_wrapper.

basically forwards signals to tpips. tries to stop tpips before exiting. stops if tpips is stopped.

these signals are traced.

forward signals to tpips.

tpips stopped.

idem?

reset signal handler.

Parameters
snsignal number

Definition at line 127 of file wrapper.c.

128 {
129  /* these signals are traced.
130  */
131  fprintf(stderr, WRAPPER "signal %d caught!\n", sn);
132  fflush(stderr);
133 
134  switch (sn)
135  {
136  case SIGHUP:
137  case SIGINT:
138  case SIGTERM:
139  case SIGUSR1:
140  case SIGUSR2:
141  /* forward signals to tpips.
142  */
143  KILL(tpips_pid, sn);
144  break;
145  case SIGQUIT:
146  case SIGABRT:
147  case SIGCHLD: /* tpips stopped. */
148  case SIGPIPE: /* idem? */
149  fprintf(stderr, WRAPPER "killing tpips...\n");
150  fflush(stderr);
151  KILL(tpips_pid, SIGKILL);
152  exit(2);
153  break;
154  default:
155  fprintf(stderr, WRAPPER "unexpected signal (%d)\n", sn);
156  tpw_fatal_error("unexpected signal");
157  }
158 
159  /* reset signal handler.
160  */
161  (void) signal(sn, tpw_sig_handler);
162 }

References exit, fprintf(), KILL, tpips_pid, tpw_fatal_error(), and WRAPPER.

Referenced by tpw_set_sig_handlers().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ in_from_wrapper

FILE* in_from_wrapper = NULL
static

Definition at line 181 of file wrapper.c.

Referenced by tpw_fork_inout().

◆ out_to_tpips

FILE* out_to_tpips = NULL
static

Definition at line 182 of file wrapper.c.

Referenced by tpw_fork_inout(), and tpw_send_string_to_tpips().

◆ tpips_pid

pid_t tpips_pid = 0
static

global because needed in tpw_fatal_error.

Definition at line 81 of file wrapper.c.

Referenced by tpips_wrapper(), tpw_fatal_error(), and tpw_sig_handler().