src/bg.c File Reference

#include "main.h"
#include <signal.h>
#include "bg.h"
Include dependency graph for bg.c:

Go to the source code of this file.

Data Structures

struct  bg_comm_t
struct  bg_t

Enumerations

enum  bg_state_t { BG_NONE = 0, BG_SPLIT, BG_PARENT }

Functions

static void bg_do_detach (pid_t p)
void bg_prepare_split (void)
static void bg_send_pidfile (void)
void bg_send_quit (bg_quit_t q)
void bg_do_split (void)

Variables

char pid_file []
static bg_t bg = { 0 }

Enumeration Type Documentation

enum bg_state_t
Enumerator:
BG_NONE 
BG_SPLIT 
BG_PARENT 

Definition at line 82 of file bg.c.

00082              {
00083   BG_NONE = 0,         /* No forking has taken place yet.                */
00084   BG_SPLIT,            /* I'm the newly forked process.                  */
00085   BG_PARENT            /* I'm the original process.                      */
00086 } bg_state_t;


Function Documentation

static void bg_do_detach ( pid_t  p  )  [static]

Definition at line 102 of file bg.c.

References EGG_NOWRITE, NULL, and pid_file.

Referenced by bg_do_split(), and bg_prepare_split().

00103 {
00104   FILE *fp;
00105 
00106   /* Need to attempt to write pid now, not later. */
00107   unlink(pid_file);
00108   fp = fopen(pid_file, "w");
00109   if (fp != NULL) {
00110     fprintf(fp, "%u\n", p);
00111     if (fflush(fp)) {
00112       /* Kill bot incase a botchk is run from crond. */
00113       printf(EGG_NOWRITE, pid_file);
00114       printf("  Try freeing some disk space\n");
00115       fclose(fp);
00116       unlink(pid_file);
00117       exit(1);
00118     }
00119     fclose(fp);
00120   } else
00121     printf(EGG_NOWRITE, pid_file);
00122   printf("Launched into the background  (pid: %d)\n\n", p);
00123 #ifdef HAVE_SETPGID
00124   setpgid(p, p);
00125 #endif
00126   exit(0);
00127 }

Here is the caller graph for this function:

void bg_do_split ( void   ) 

Definition at line 230 of file bg.c.

References bg_do_detach(), BG_QUIT, bg_send_quit(), fatal, and fork_before_tcl().

Referenced by main().

00231 {
00232   if (fork_before_tcl()) {
00233     /* Tell our parent process to go away now, as we don't need it anymore. */
00234     bg_send_quit(BG_QUIT);
00235 
00236   } else {
00237     /* Split off a new process. */
00238     int xx = fork();
00239 
00240     if (xx == -1)
00241       fatal("CANNOT FORK PROCESS.", 0);
00242     if (xx != 0)
00243       bg_do_detach(xx);
00244   }
00245 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bg_prepare_split ( void   ) 

Definition at line 129 of file bg.c.

References bg_do_detach(), BG_PARENT, BG_SPLIT, bg_t::child_pid, bg_comm_t::comm_data, bg_t::comm_recv, bg_t::comm_send, bg_comm_t::comm_type, fatal, fork_before_tcl(), pid_file, bg_t::state, and bg_comm_t::transferpf.

Referenced by main().

00130 {
00131   pid_t p;
00132   bg_comm_t message;
00133 
00134   if (!fork_before_tcl())
00135     return;
00136 
00137   /* Create a pipe between parent and split process, fork to create a
00138    * parent and a split process and wait for messages on the pipe. */
00139   {
00140     int comm_pair[2];
00141 
00142     if (pipe(comm_pair) < 0)
00143       fatal("CANNOT OPEN PIPE.", 0);
00144 
00145     bg.comm_recv = comm_pair[0];
00146     bg.comm_send = comm_pair[1];
00147   }
00148 
00149   p = fork();
00150   if (p == -1)
00151     fatal("CANNOT FORK PROCESS.", 0);
00152   if (p == 0) {
00153     bg.state = BG_SPLIT;
00154     return;
00155   } else {
00156     bg.child_pid = p;
00157     bg.state = BG_PARENT;
00158   }
00159 
00160   while (read(bg.comm_recv, &message, sizeof(message)) > 0) {
00161     switch (message.comm_type) {
00162     case BG_COMM_QUIT:
00163       bg_do_detach(p);
00164       break;
00165     case BG_COMM_ABORT:
00166       exit(1);
00167       break;
00168     case BG_COMM_TRANSFERPF:
00169       /* Now transferring file from split process.
00170        */
00171       if (message.comm_data.transferpf.len >= 40)
00172         message.comm_data.transferpf.len = 40 - 1;
00173       /* Next message contains data. */
00174       if (read(bg.comm_recv, pid_file, message.comm_data.transferpf.len) <= 0)
00175         goto error;
00176       pid_file[message.comm_data.transferpf.len] = 0;
00177       break;
00178     }
00179   }
00180 
00181 error:
00182   /* We only reach this point in case of an error.
00183    */
00184   fatal("COMMUNICATION THROUGH PIPE BROKE.", 0);
00185 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void bg_send_pidfile ( void   )  [static]

Definition at line 191 of file bg.c.

References bg_comm_t::comm_data, bg_t::comm_send, bg_comm_t::comm_type, fatal, pid_file, and bg_comm_t::transferpf.

Referenced by bg_send_quit().

00192 {
00193   bg_comm_t message;
00194 
00195   message.comm_type = BG_COMM_TRANSFERPF;
00196   message.comm_data.transferpf.len = strlen(pid_file);
00197 
00198   /* Send type message. */
00199   if (write(bg.comm_send, &message, sizeof(message)) < 0)
00200     goto error;
00201   /* Send data. */
00202   if (write(bg.comm_send, pid_file, message.comm_data.transferpf.len) < 0)
00203     goto error;
00204   return;
00205 error:
00206   fatal("COMMUNICATION THROUGH PIPE BROKE.", 0);
00207 }

Here is the caller graph for this function:

void bg_send_quit ( bg_quit_t  q  ) 

Definition at line 209 of file bg.c.

References BG_PARENT, BG_QUIT, bg_send_pidfile(), BG_SPLIT, bg_t::child_pid, bg_t::comm_send, bg_comm_t::comm_type, fatal, fork_before_tcl(), and bg_t::state.

Referenced by bg_do_split(), do_arg(), fatal(), got_bus(), got_segv(), and main().

00210 {
00211   if (!fork_before_tcl())
00212     return;
00213 
00214   if (bg.state == BG_PARENT) {
00215     kill(bg.child_pid, SIGKILL);
00216   } else if (bg.state == BG_SPLIT) {
00217     bg_comm_t message;
00218 
00219     if (q == BG_QUIT) {
00220       bg_send_pidfile();
00221       message.comm_type = BG_COMM_QUIT;
00222     } else
00223       message.comm_type = BG_COMM_ABORT;
00224     /* Send message. */
00225     if (write(bg.comm_send, &message, sizeof(message)) < 0)
00226       fatal("COMMUNICATION THROUGH PIPE BROKE.", 0);
00227   }
00228 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

bg_t bg = { 0 } [static]

Definition at line 95 of file bg.c.

char pid_file[]

Definition at line 112 of file main.c.

Referenced by bg_do_detach(), bg_prepare_split(), bg_send_pidfile(), fatal(), and main().


Generated on 7 Sep 2016 for Eggdrop by  doxygen 1.6.1