process.c File Reference

#include <glib.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <hal/libhal.h>
#include <liberkeyb/erkeyb-client.h>
#include "log.h"
#include "busy.h"
#include "conf.h"
#include "connections.h"
#include "display.h"
#include "ipc.h"
#include "hal.h"
#include "process.h"
#include "tasks.h"
#include "xwindow.h"
Include dependency graph for process.c:

Go to the source code of this file.

Functions

static void check_start_next (void)
static void on_process_exit (GPid pid, gint status, gpointer data)
static gboolean on_startup_completed_timeout (gpointer data)
static gboolean start_process (proc_t *proc)
static void check_respawn (proc_t *proc)
static void on_reply_error (eripc_context_t *context, const eripc_event_info_t *info, void *user_data)
static void post_process_startup (proc_t *proc, const char *application, gint window)
static proc_tcreate_process (const char *command, const char *working_dir, GCallback startup_callback, GCallback exit_callback, gint flags)
static void destroy_process (proc_t *proc)
gboolean process_add (const char *command, const char *working_dir, GCallback startup_callback, GCallback exit_callback, gint flags)
 Add a process to the queue. The queue is served First In First Out.
proc_tprocess_start (const char *command, const char *working_dir, GCallback startup_callback, GCallback exit_callback, gint flags)
 Start a process without queuing.
void process_stop (proc_t *proc)
 Stop a running process.
gboolean process_activate (const char *application)
 Activate a running process (set to top).
gboolean process_activate_ctb ()
 Activate content browser (set to top).
gboolean process_startup_complete (const char *application, gint pid, gboolean is_multidoc, const char *ipc_service, gint window)
 Call when application has finished starting.
proc_tprocess_get_by_pid (GPid pid)
void print_process_list ()
proc_tprocess_get_by_name (const char *application)

Variables

static const gint TIMEOUT_STARTUP_COMPLETED = 30
static GSList * g_proclist = NULL
static gint g_process_pending_source = 0

Function Documentation

static void check_respawn ( proc_t proc  )  [static]

Definition at line 492 of file process.c.

References check_start_next(), proc_t::command, destroy_process(), proc_t::exit_callback, proc_t::flags, proc_t::ipc_service, LOGPRINTF, proc_t::pid, PS_RESPAWN, proc_t::startup_callback, proc_t::state, STATE_DEVICE_STOPPING, STATE_IDLE, sys_get_device_state(), and WARNPRINTF.

Referenced by on_process_exit(), and on_reply_error().

00493 {
00494     GPid pid = proc->pid;
00495     
00496     if (proc->flags & PS_RESPAWN)
00497     {
00498         LOGPRINTF("should respawn, new state STATE_IDLE");
00499         WARNPRINTF("respawn application %s", proc->command);
00500         // reset to initial values
00501         proc->state = STATE_IDLE;
00502         proc->pid   = 0;
00503         g_free(proc->ipc_service);
00504         proc->ipc_service = NULL;
00505         // don't use callbacks when respawning
00506         proc->startup_callback = NULL;
00507         proc->exit_callback = NULL;
00508     }
00509     else
00510     {
00511         LOGPRINTF("no respawn, remove from list");
00512         destroy_process(proc);
00513         proc = NULL;
00514     }
00515     
00516     // graciously close pid
00517     g_spawn_close_pid(pid);
00518     
00519     if (sys_get_device_state() != STATE_DEVICE_STOPPING)
00520     {
00521         // start next process
00522         check_start_next();
00523     }
00524 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void check_start_next ( void   )  [static]

Definition at line 547 of file process.c.

References proc_t::command, proc_t::flags, g_proclist, LOGPRINTF, proc_t::pid, PS_WAIT_EXIT, PS_WAIT_STARTED, start_process(), proc_t::state, STATE_DEVICE_STOPPING, STATE_IDLE, STATE_RUNNING, STATE_STARTING, sys_get_device_state(), and WARNPRINTF.

Referenced by check_respawn(), on_startup_completed_timeout(), process_add(), process_startup_complete(), and start_process().

00548 {
00549     LOGPRINTF("entry");
00550     
00551     proc_t *cur_proc = NULL;
00552     GSList *proc_ptr = g_proclist;
00553     gboolean is_ready = TRUE;
00554     
00555     if (sys_get_device_state() == STATE_DEVICE_STOPPING)
00556     {
00557         WARNPRINTF("device is shutting down, process not started");
00558         return;
00559     }
00560     
00561     while (proc_ptr)
00562     {
00563         cur_proc = (proc_t *) proc_ptr->data;
00564         
00565         if (((cur_proc->state == STATE_STARTING) && (cur_proc->flags & PS_WAIT_STARTED)) ||
00566             ((cur_proc->state == STATE_RUNNING) && (cur_proc->flags & PS_WAIT_EXIT)))
00567         {
00568             LOGPRINTF("wait for process %d to complete", cur_proc->pid);
00569             is_ready = FALSE;
00570             break;
00571         }
00572             
00573         proc_ptr = proc_ptr->next;
00574     }
00575     
00576     if (is_ready)
00577     {
00578         proc_ptr = g_proclist;
00579         
00580         while (proc_ptr)
00581         {
00582             cur_proc = (proc_t *) proc_ptr->data;
00583             
00584             if (cur_proc->state == STATE_IDLE)
00585             {
00586                 LOGPRINTF("start next process: %s", cur_proc->command);
00587                 start_process(cur_proc);
00588                 return;
00589             }
00590                 
00591             proc_ptr = proc_ptr->next;
00592         }
00593     }
00594     return;
00595 }

Here is the call graph for this function:

Here is the caller graph for this function:

static proc_t * create_process ( const char *  command,
const char *  working_dir,
GCallback  startup_callback,
GCallback  exit_callback,
gint  flags 
) [static]

Definition at line 326 of file process.c.

References proc_t::command, ERRORPRINTF, proc_t::exit_callback, proc_t::flags, g_proclist, proc_t::ipc_service, proc_t::is_multidoc, LOGPRINTF, proc_t::pid, proc_t::startup_callback, proc_t::state, STATE_IDLE, and proc_t::working_dir.

Referenced by process_add(), and process_start().

00327 {
00328     LOGPRINTF("entry: %s, %d", command, flags);
00329     
00330     proc_t *proc = g_new0 (proc_t, 1);
00331     if (!proc)
00332     {
00333         ERRORPRINTF("mem alloc failed");
00334         return NULL;
00335     }
00336     
00337     // init defaults
00338     //
00339     proc->command           = g_strdup(command);
00340     proc->working_dir       = NULL;
00341     if (working_dir)
00342     {
00343         proc->working_dir   = g_strdup(working_dir);
00344     }
00345     proc->ipc_service       = NULL;
00346     proc->pid               = 0;
00347     proc->is_multidoc       = FALSE;
00348     proc->flags             = flags;
00349     proc->startup_callback  = startup_callback;
00350     proc->exit_callback     = exit_callback;
00351     proc->state             = STATE_IDLE;
00352     
00353     // add to list
00354     g_proclist = g_slist_append(g_proclist, proc);
00355     
00356     return proc;
00357 }

Here is the caller graph for this function:

static void destroy_process ( proc_t proc  )  [static]

Definition at line 360 of file process.c.

References proc_t::command, g_proclist, proc_t::ipc_service, and proc_t::working_dir.

Referenced by check_respawn(), and process_start().

00361 {
00362     // remove from list
00363     g_proclist = g_slist_remove(g_proclist, proc);
00364 
00365     // free memory
00366     g_free(proc->command);
00367     g_free(proc->ipc_service);
00368     g_free(proc->working_dir);
00369     g_free(proc);
00370     proc = NULL;
00371 }    

Here is the caller graph for this function:

static void on_process_exit ( GPid  pid,
gint  status,
gpointer  data 
) [static]

Definition at line 374 of file process.c.

References busy_reset_pid(), check_respawn(), proc_t::command, conn_disconnect(), display_cleanup_pid(), erkeyb_client_hide(), ERRORPRINTF, proc_t::exit_callback, proc_t::flags, g_process_pending_source, ipc_refresh_ctb(), proc_t::ipc_service, ipc_show_message(), LOGPRINTF, on_reply_error(), proc_t::pid, PS_RESPAWN, proc_t::state, STATE_CARD_INDEXING, STATE_STARTING, sys_get_card(), task_cleanup_pid(), and WARNPRINTF.

Referenced by start_process().

00375 {
00376     LOGPRINTF("entry");
00377     
00378 #if (WARNING_ON)
00379     // see signal.h and man 3 waitpid
00380     const char *status_text[]  = { "", "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL",
00381                                    "SIGTRAP", "SIGABRT", "SIGBUS", "SIGFPE",
00382                                    "SIGKILL", "SIGUSR1", "SIGSEGV", "SIGUSR2", "SIGPIPE",
00383                                    "SIGALRM", "SIGTERM", "SIGSTKFLT", "SIGCHLD", 0};
00384     if (WIFSIGNALED(status))
00385    {
00386         WARNPRINTF("pid %d was terminated by signal %d [%s]", pid, WTERMSIG(status), 
00387             WTERMSIG(status) <= 17 ? status_text[WTERMSIG(status)] : "");
00388     }
00389     else if (WIFEXITED(status))
00390     {
00391         WARNPRINTF("pid %d has exited with status %d", pid, WEXITSTATUS(status));
00392     }
00393     else
00394     {
00395         // it's not likely this will ever be reached, but just to be sure
00396         WARNPRINTF("pid %d is gone, status %d", pid, status);
00397     }
00398 #endif
00399 
00400     proc_t *proc = data;
00401     gboolean try_respawn = TRUE;
00402     
00403     g_return_if_fail(proc != NULL);
00404     g_return_if_fail(proc->pid == pid);
00405     gchar *proc_app = g_path_get_basename(proc->command);
00406 
00407     if (proc->state == STATE_STARTING)
00408     {
00409         // stop pending timeout
00410         if (g_process_pending_source)
00411         { 
00412             g_source_remove(g_process_pending_source);
00413             g_process_pending_source = 0;
00414         }
00415         
00416         // clear respawn bit
00417         // when application crashes while starting, it makes 
00418         // no sense to retry this over and over again.
00419         proc->flags &= ~(PS_RESPAWN);
00420         
00421         ERRORPRINTF("application [%s] exited", proc->command);
00422     }
00423     
00424     // Check if app is adobe-fulfill or downloadmgr
00425     // and notify ctb. Needed because these apps are Dialogs, so
00426     // ctb does not get a WindowActivated/Deactivated call
00427     if (proc_app && 
00428         ((strcmp(proc_app, "downloadmgr") == 0) || (strcmp(proc_app, "adobe-fulfill") == 0)))
00429     {
00430         ipc_refresh_ctb();
00431     }
00432 
00433     // remove tasks for this process
00434     task_cleanup_pid(pid);
00435 
00436     // remove busy for this process
00437     busy_reset_pid(pid);
00438     
00439     // remove display info for this process
00440     display_cleanup_pid(pid);
00441     
00442     // remove connection when process died
00443     if ((status !=0) && proc->ipc_service)
00444     {
00445         conn_disconnect(proc->ipc_service);
00446     }
00447     
00448     // call post exit callback
00449     if (proc->exit_callback)
00450     {
00451         (proc->exit_callback)();
00452     }
00453 
00454     if (((WIFEXITED(status) && WEXITSTATUS(status) == 1) ||
00455          (WIFSIGNALED(status) && 
00456          (WTERMSIG(status) == SIGFPE || WTERMSIG(status) == SIGABRT || WTERMSIG(status) == SIGSEGV))) &&
00457           proc_app)
00458     {
00459         // unexpected error ocurred
00460         if (strcmp(proc_app, "uds") == 0)
00461         {
00462             if (sys_get_card() == STATE_CARD_INDEXING)
00463             {
00464                 // indexer caused UDS to fail, terminate it to prevent more errors
00465                 system("killall mdbindex");
00466                 ipc_show_message("indexerror", on_reply_error, proc);
00467                 // delay respawning UDS until user confirmed error dialog
00468                 try_respawn = FALSE;
00469             }
00470             else
00471             {
00472                 ipc_show_message("udserror", on_reply_error, proc);
00473                 // delay respawning UDS until user confirmed error dialog
00474                 try_respawn = FALSE;
00475             }
00476         }
00477         else if (strcmp(proc_app, "erbrowser") == 0)
00478         {
00479             erkeyb_client_hide();
00480             ipc_show_message("browsererror", NULL, NULL);
00481         }
00482     }
00483     
00484     if (try_respawn)
00485     {
00486         check_respawn(proc);
00487     }
00488     g_free(proc_app);
00489 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void on_reply_error ( eripc_context_t context,
const eripc_event_info_t info,
void *  user_data 
) [static]

Definition at line 687 of file process.c.

References eripc_event_info_t::args, check_respawn(), ERIPC_EVENT_REPLY, ERIPC_TYPE_BOOL, eripc_event_info_t::event_type, LOGPRINTF, and WARNPRINTF.

Referenced by on_process_exit().

00690 {
00691     LOGPRINTF("entry");
00692     
00693     const eripc_arg_t *arg_array = info->args;
00694     
00695     if (info->event_type != ERIPC_EVENT_REPLY)
00696     {
00697         WARNPRINTF("invalid event: %d", info->event_type);
00698     }
00699     else if ((arg_array == NULL) || (arg_array[0].type != ERIPC_TYPE_BOOL))
00700     {
00701         WARNPRINTF("invalid arguments in reply");
00702     }
00703     else 
00704     {
00705         LOGPRINTF("User clicked ok");
00706         proc_t *proc = user_data;
00707         check_respawn(proc);
00708     }
00709 }

Here is the call graph for this function:

Here is the caller graph for this function:

static gboolean on_startup_completed_timeout ( gpointer  data  )  [static]

Definition at line 527 of file process.c.

References check_start_next(), proc_t::command, g_process_pending_source, LOGPRINTF, proc_t::state, and STATE_RUNNING.

Referenced by start_process().

00528 {
00529     proc_t *proc = data;
00530     
00531     LOGPRINTF("entry");
00532     LOGPRINTF("timeout waiting for startupComplete (%s), new state STATE_RUNNING", proc->command);
00533     
00534     // callback startupComplete not received, assume it is running 
00535     proc->state = STATE_RUNNING;
00536     
00537     // start next process
00538     check_start_next();
00539     
00540     g_process_pending_source = 0;
00541     
00542     // stop and destroy this timer
00543     return FALSE; 
00544 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void post_process_startup ( proc_t proc,
const char *  application,
gint  window 
) [static]

Definition at line 665 of file process.c.

References ipc_send_changed_locale(), ipc_send_volume_mounted_to(), proc_t::ipc_service, LOGPRINTF, MOUNTPOINT_CARD, STATE_CARD_MOUNTED, sys_get_card(), and task_startup_completed().

Referenced by process_startup_complete().

00666 {
00667     LOGPRINTF("entry");
00668 
00669     // inform tasks of new window
00670     task_startup_completed(proc, window);
00671 
00672     // report mountpoint when card is available
00673     if (sys_get_card() == STATE_CARD_MOUNTED)
00674     {
00675         ipc_send_volume_mounted_to(proc->ipc_service, MOUNTPOINT_CARD);
00676     }
00677     
00678     // report current language as it may have changed during startup
00679     const char *locale = g_getenv("LANG");
00680     if (locale)
00681     {
00682         ipc_send_changed_locale(locale);
00683     }
00684 }

Here is the call graph for this function:

Here is the caller graph for this function:

void print_process_list (  ) 

Definition at line 272 of file process.c.

References proc_t::command, g_proclist, proc_t::ipc_service, proc_t::is_multidoc, and proc_t::pid.

Referenced by testing_list_tasks().

00273 {
00274     GSList *proc_ptr    = g_proclist;
00275 
00276     printf("%s() PROCESS LIST:\n", __func__);
00277     int i = 0;
00278     while (proc_ptr)
00279     {
00280         proc_t *cur = (proc_t *) proc_ptr->data;
00281         printf("  [%d] cmd=%s  ipc=%s  multi=%d  pid=%d\n", i,
00282             cur->command, cur->ipc_service, cur->is_multidoc, cur->pid);
00283 
00284         proc_ptr = proc_ptr->next;
00285         i++;
00286     }
00287 }

Here is the caller graph for this function:

gboolean process_activate ( const char *  application  ) 

Activate a running process (set to top).

---------------------------------------------------------------------------

Name : process_activate

Parameters:
application Full path of the application
Returns:
Returns TRUE on success, FALSE on failure

--------------------------------------------------------------------------

Definition at line 149 of file process.c.

References get_application_window(), LOGPRINTF, WARNPRINTF, and window_activate().

Referenced by cb_menu_item_activated(), and process_activate_ctb().

00150 {
00151     LOGPRINTF("entry");
00152     
00153     gboolean result = FALSE;
00154     Window win_found;
00155     
00156     win_found = get_application_window(application);
00157     
00158     if (win_found != None)
00159     {
00160         window_activate(win_found);
00161         result = TRUE;
00162     }
00163     else
00164     {
00165         WARNPRINTF("No window found for: %s", application);
00166     }
00167 
00168     return result;
00169 }

Here is the call graph for this function:

Here is the caller graph for this function:

gboolean process_activate_ctb ( void   ) 

Activate content browser (set to top).

---------------------------------------------------------------------------

Name : process_activate_ctb

Parameters:
-- 
Returns:
Returns TRUE on success, FALSE on failure

--------------------------------------------------------------------------

Definition at line 172 of file process.c.

References display_get_active_window(), LOGPRINTF, process_activate(), STATE_DEVICE_STOPPING, and sys_get_device_state().

Referenced by task_activate_by_xid(), task_cleanup_pid(), and task_cleanup_window().

00173 {
00174     LOGPRINTF("entry");
00175     
00176     gboolean retval = TRUE;
00177 
00178     if (sys_get_device_state() == STATE_DEVICE_STOPPING)
00179     {
00180         // don't activate CTB when device is shutting down
00181         return FALSE;
00182     }
00183     
00184     // set to top when not already active
00185     gchar *app_active = display_get_active_window();
00186     if (app_active && strcmp(app_active, "ctb") != 0 )
00187     {
00188         retval = process_activate("ctb");
00189     }
00190     
00191     return retval;
00192 }

Here is the call graph for this function:

Here is the caller graph for this function:

gboolean process_add ( const char *  command,
const char *  working_dir,
GCallback  startup_callback,
GCallback  exit_callback,
gint  flags 
)

Add a process to the queue. The queue is served First In First Out.

---------------------------------------------------------------------------

Name : process_add

Parameters:
application Full path of the application
working_dir Working directory, or NULL to inherit parent's
startup_callback Callback function when received startupCopmlete, or NULL
exit_callback Callback function when processes was terminated, or NULL
flags Bit field PS_WAIT_STARTED | PS_WAIT_EXIT | PS_RESPAWN
Returns:
Returns TRUE on success, FALSE on failure

--------------------------------------------------------------------------

Definition at line 97 of file process.c.

References check_start_next(), create_process(), and LOGPRINTF.

Referenced by main(), start_phase_2(), and start_phase_3().

00098 {
00099     LOGPRINTF("entry: %s, %d", command, flags);
00100     
00101     proc_t *proc = create_process(command, working_dir, startup_callback, exit_callback, flags);
00102     if (proc == NULL)
00103     {
00104         return FALSE;
00105     }
00106     
00107     check_start_next();
00108     
00109     return TRUE;
00110 }

Here is the call graph for this function:

Here is the caller graph for this function:

proc_t* process_get_by_name ( const char *  application  ) 

Definition at line 290 of file process.c.

References proc_t::command, g_proclist, and LOGPRINTF.

Referenced by parse_wm_messages(), and task_start().

00291 {
00292     LOGPRINTF("entry [%s]", application);
00293     
00294     GSList *proc_ptr    = g_proclist;
00295 
00296     while (proc_ptr)
00297     {
00298         proc_t *cur_proc = (proc_t *) proc_ptr->data;
00299 
00300         gint   argc         = 0;
00301         char   **argv_ptr   = NULL;
00302         if (g_shell_parse_argv(cur_proc->command, &argc, &argv_ptr, NULL))
00303         {
00304             gchar  *proc_app = g_path_get_basename(argv_ptr[0]);
00305 //            LOGPRINTF("check [%s]", proc_app);
00306             if (application && proc_app && (strcmp(proc_app, application) == 0))
00307             {
00308 //                LOGPRINTF("match [%s] pid [%d]", proc_app, cur_proc->pid);
00309                 g_free(proc_app);
00310                 return cur_proc;
00311             }
00312             g_free(proc_app);
00313             g_strfreev(argv_ptr);
00314         }
00315         proc_ptr = proc_ptr->next;
00316     }
00317     
00318     return NULL;
00319 }

Here is the caller graph for this function:

proc_t* process_get_by_pid ( GPid  pid  ) 

Definition at line 248 of file process.c.

References proc_t::command, g_proclist, proc_t::ipc_service, LOGPRINTF, and proc_t::pid.

Referenced by process_startup_complete(), and task_add().

00249 {
00250     LOGPRINTF("entry  pid [%d]", pid);
00251     
00252     GSList *proc_ptr = g_proclist;
00253     proc_t *cur_proc = NULL;
00254     
00255     while (proc_ptr)
00256     {
00257         cur_proc = (proc_t *) proc_ptr->data;
00258         
00259         if (cur_proc->pid == pid)
00260         {
00261             LOGPRINTF("found [%p] command [%s] ipc service [%s]", cur_proc, cur_proc->command, cur_proc->ipc_service);
00262             return cur_proc;
00263         }
00264             
00265         proc_ptr = proc_ptr->next;
00266     }
00267     
00268     return NULL;
00269 }

Here is the caller graph for this function:

proc_t* process_start ( const char *  command,
const char *  working_dir,
GCallback  startup_callback,
GCallback  exit_callback,
gint  flags 
)

Start a process without queuing.

---------------------------------------------------------------------------

Name : process_start

Parameters:
application Full path of the application
working_dir Working directory, or NULL to inherit parent's
startup_callback Callback function when received startupCopmlete, or NULL
exit_callback Callback function when processes was terminated, or NULL
flags Bit field PS_WAIT_STARTED | PS_RESPAWN
Returns:
Process created and started, or NULL on error.

--------------------------------------------------------------------------

Definition at line 113 of file process.c.

References create_process(), destroy_process(), LOGPRINTF, and start_process().

Referenced by child_new(), and start_medium().

00114 {
00115     LOGPRINTF("entry: %s, %d", command, flags);
00116     
00117     gboolean result = FALSE;
00118     
00119     proc_t *proc = create_process(command, working_dir, startup_callback, exit_callback, flags);
00120     if (proc == NULL)
00121     {
00122         return NULL;
00123     }
00124     
00125     result = start_process(proc);
00126     if (result == FALSE)
00127     {
00128         LOGPRINTF("failed to spawn, remove from list");
00129         destroy_process(proc);
00130         proc = NULL;
00131     }
00132     
00133     return proc;
00134 }

Here is the call graph for this function:

Here is the caller graph for this function:

gboolean process_startup_complete ( const char *  application,
gint  pid,
gboolean  is_multidoc,
const char *  ipc_service,
gint  window 
)

Call when application has finished starting.

---------------------------------------------------------------------------

Name : process_startup_complete

Parameters:
application Full path of the application
pid Process ud
is_multidoc TRUE if multiple documents are supported, FALSE otherwise
ipc_service IPC service
window Window id
Returns:
Returns TRUE on success, FALSE on failure

--------------------------------------------------------------------------

Definition at line 195 of file process.c.

References check_start_next(), display_set_ctb_window(), g_process_pending_source, proc_t::ipc_service, proc_t::is_multidoc, LOGPRINTF, post_process_startup(), process_get_by_pid(), proc_t::startup_callback, proc_t::state, STATE_RUNNING, STATE_STARTING, and WARNPRINTF.

Referenced by cb_startup_complete().

00196 {
00197     LOGPRINTF("entry");
00198     gboolean retval = FALSE;
00199     
00200     // find proc by pid
00201     proc_t *proc = process_get_by_pid(pid);
00202 
00203     if (proc == NULL)
00204     {
00205         WARNPRINTF("%s (pid %d) is not started sysd", application, pid);
00206     }
00207     else if (proc->state != STATE_STARTING)
00208     {
00209         WARNPRINTF("unexpected startupComplete received from %s (pid %d), state [%d]", application, pid, proc->state);
00210     }
00211     else
00212     {
00213         // stop pending timeout
00214         if (g_process_pending_source)
00215         { 
00216             g_source_remove(g_process_pending_source);
00217             g_process_pending_source = 0;
00218         }
00219 
00220         LOGPRINTF("received startupComplete from %s (pid %d, window %d), new state STATE_RUNNING", application, pid, window);
00221         if (strcmp(application, "ctb") == 0) {
00222             display_set_ctb_window(window);
00223         }
00224         
00225         // update process info
00226         proc->state = STATE_RUNNING;
00227         proc->is_multidoc = is_multidoc;
00228         proc->ipc_service = g_strdup(ipc_service);
00229 
00230         // do post startup actions
00231         post_process_startup(proc, application, window);
00232         
00233         // call post startup callback
00234         if (proc->startup_callback)
00235         {
00236             (proc->startup_callback)();
00237         }
00238 
00239         // start next process
00240         check_start_next();
00241         
00242         retval = TRUE;
00243     }
00244     return retval;
00245 }

Here is the call graph for this function:

Here is the caller graph for this function:

void process_stop ( proc_t proc  ) 

Stop a running process.

---------------------------------------------------------------------------

Name : process_stop

Parameters:
process The process to be stopped
Returns:
--

--------------------------------------------------------------------------

Definition at line 137 of file process.c.

References proc_t::command, LOGPRINTF, and proc_t::pid.

Referenced by stop_medium().

00138 {
00139     g_assert(proc);
00140     LOGPRINTF("entry: %s, %d", proc->command, proc->pid);
00141     
00142     if (proc && proc->pid > 0)
00143     {
00144         kill(proc->pid, SIGTERM);
00145     }
00146 }

Here is the caller graph for this function:

static gboolean start_process ( proc_t proc  )  [static]

Definition at line 598 of file process.c.

References check_start_next(), proc_t::command, proc_t::flags, g_process_pending_source, LOGPRINTF, on_process_exit(), on_startup_completed_timeout(), proc_t::pid, PS_WAIT_EXIT, PS_WAIT_STARTED, proc_t::state, STATE_RUNNING, STATE_STARTING, TIMEOUT_STARTUP_COMPLETED, WARNPRINTF, and proc_t::working_dir.

Referenced by check_start_next(), and process_start().

00599 {
00600     LOGPRINTF("entry");
00601     
00602     GPid child_pid   = 0;
00603     gint argc        = 0;
00604     char **argv_ptr  = NULL;
00605     gboolean retval  = FALSE;
00606     GError *error    = NULL;
00607 
00608     LOGPRINTF("Starting: %s", proc->command);
00609 
00610     retval = g_shell_parse_argv(proc->command, &argc, &argv_ptr, &error);
00611     if (error)
00612     {
00613         WARNPRINTF("Error parsing command '%s' failed with error: %s", proc->command, error->message);
00614         g_error_free(error);
00615         return FALSE;
00616     }
00617     
00618     retval = g_spawn_async(proc->working_dir, argv_ptr, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &child_pid, &error);
00619     if (error)
00620     {
00621         WARNPRINTF("Execution of '%s' failed with error: %s", proc->command, error->message);
00622         g_error_free(error);
00623         if (argv_ptr) g_strfreev(argv_ptr);
00624         return FALSE;
00625     }
00626     
00627     if (proc->flags & PS_WAIT_STARTED)
00628     {
00629         if (g_process_pending_source)
00630         { 
00631             g_source_remove(g_process_pending_source);
00632             WARNPRINTF("A process is started while a previous one was still pending. Previous pending timer stopped.");
00633         }
00634         
00635         // set maximum time to wait for startupComplete
00636         g_process_pending_source = g_timeout_add_seconds(TIMEOUT_STARTUP_COMPLETED, on_startup_completed_timeout, proc);
00637         
00638         // update process entry
00639         LOGPRINTF("wait for startupComplete (pid %d), new state STATE_STARTING", child_pid);
00640         proc->state = STATE_STARTING;
00641         proc->pid = child_pid;
00642     }
00643     else
00644     {
00645         // update process entry
00646         LOGPRINTF("don't wait for startup, new state STATE_RUNNING");
00647         proc->state = STATE_RUNNING;
00648         proc->pid = child_pid;
00649         
00650         if (!(proc->flags & PS_WAIT_EXIT))
00651         {
00652             // start next process
00653             check_start_next();
00654         }
00655     }
00656     
00657     // watch child lifetime
00658     g_child_watch_add(child_pid, on_process_exit, proc);
00659     
00660     g_strfreev(argv_ptr);
00661     return TRUE;    
00662 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

gint g_process_pending_source = 0 [static]
GSList* g_proclist = NULL [static]
const gint TIMEOUT_STARTUP_COMPLETED = 30 [static]

Copyright (C) 2008 iRex Technologies B.V. All rights reserved.

Definition at line 67 of file process.c.

Referenced by start_process().

Generated by  doxygen 1.6.2-20100208