new fortune
[feisty_meow.git] / nucleus / library / processes / launch_process.h
1 #ifndef LAUNCH_PROCESS_CLASS
2 #define LAUNCH_PROCESS_CLASS
3
4 /*****************************************************************************\
5 *                                                                             *
6 *  Name   : launch_process
7 *  Author : Chris Koeritz
8 *                                                                             *
9 *******************************************************************************
10 * Copyright (c) 1994-$now By Author.  This program is free software; you can  *
11 * redistribute it and/or modify it under the terms of the GNU General Public  *
12 * License as published by the Free Software Foundation; either version 2 of   *
13 * the License or (at your option) any later version.  This is online at:      *
14 *     http://www.fsf.org/copyleft/gpl.html                                    *
15 * Please send any updates to: fred@gruntose.com                               *
16 \*****************************************************************************/
17
18 #include <basis/array.h>
19 #include <basis/astring.h>
20 #include <basis/definitions.h>
21
22 // forward.
23 struct tagMSG;
24
25 namespace processes {
26
27 //! a simple wrapper of an array of char *, used by launch_process::break_line().
28 class char_star_array : public basis::array<char *>
29 {
30 public:
31   char_star_array() : basis::array<char *>(0, NULL_POINTER, SIMPLE_COPY | EXPONE | FLUSH_INVISIBLE) {}
32   ~char_star_array() {
33     // clean up all the memory we're holding.
34     for (int i = 0; i < length(); i++) {
35       delete [] (use(i));
36     }
37   }
38 };
39
40 //////////////
41
42 //! Provides the capability to start processes in a variety of ways to run other applications.
43
44 class launch_process : public virtual basis::nameable
45 {
46 public:
47   DEFINE_CLASS_NAME("launch_process");
48
49   virtual ~launch_process() {}
50
51   enum launch_flags {
52     HIDE_APP_WINDOW = 0x1,
53       //!< launches the application invisibly if possible.
54     AWAIT_APP_EXIT = 0x2,
55       //!< stays in the function until the launched application has exited.
56     RETURN_IMMEDIATELY = 0x4,
57       //!< starts the application and comes right back to the caller.
58     AWAIT_VIA_POLLING = 0x8,
59       //!< launches the app but polls and doesn't block on its exit.
60     SHELL_EXECUTE = 0x10
61       //!< only valid on windows--uses ShellExecute instead of CreateProcess.
62   };
63
64   static basis::un_int run(const basis::astring &app_name, const basis::astring &command_line,
65           int flag, basis::un_int &child_id);
66     //!< starts an application using the "app_name" as the executable to run.
67     /*!< the "command_line" is the set of parameters to be passed to the app.
68     the return value is OS specific but can be identified using
69     system_error_text().  usually a zero return means success and non-zero
70     codes are errors.  the "flag" is an XORed value from the process launch
71     flags that dictates how the app is to be started.  in practice, only the
72     HIDE_APP_WINDOW flag can be combined with other values.  if either AWAIT
73     flag is used, then the return value will be the launched process's own
74     exit value.  the thread or process_id of the launched process is stored
75     in "child_id" if appropriate. */
76
77   static char_star_array break_line(basis::astring &app, const basis::astring &parameters);
78     //!< prepares an "app" to launch with the "parameters" (via exec).
79     /*!< this breaks the strings for an application named "app" and its
80     "parameters" into an array of char * that is appropriate for the execv
81     function. */
82
83 private:
84 #ifndef _MSC_VER
85   static void exiting_child_signal_handler(int sig_num);
86     //!< awaits the child processes rather than leaving process handles willy nilly.
87 #else
88   static bool event_poll(tagMSG &message);
89     //!< tries to process one win32 event and retrieve the "message" from it.
90     /*!< this is a very general poll and will retrieve any message that's
91     available for the current thread.  the message is actually processed
92     here also, by calling translate and dispatch.  the returned structure
93     is mainly interesting for knowing what was done. */
94 #endif
95   
96 };
97
98 } // namespace.
99
100 #endif // outer guard.
101