new fortune
[feisty_meow.git] / nucleus / applications / utilities / await_app_exit.cpp
1 /*
2 *  Name   : await_app_exit
3 *  Author : Chris Koeritz
4 *  Purpose:                                                                   *
5 *    This program waits for a particular application to exit before this app  *
6 *  itself exits.  This allows a pause while another possibly slow process is  *
7 *  leaving.                                                                   *
8 * Copyright (c) 2003-$now By Author.  This program is free software; you can  *
9 * redistribute it and/or modify it under the terms of the GNU General Public  *
10 * License as published by the Free Software Foundation; either version 2 of   *
11 * the License or (at your option) any later version.  This is online at:      *
12 *     http://www.fsf.org/copyleft/gpl.html                                    *
13 * Please send any updates to: fred@gruntose.com                               *
14 \*****************************************************************************/
15
16 #include <basis/functions.h>
17 #include <basis/astring.h>
18 #include <structures/set.h>
19 #include <timely/time_control.h>
20 #include <timely/time_stamp.h>
21 #include <application/hoople_main.h>
22 #include <filesystem/byte_filer.h>
23 #include <loggers/console_logger.h>
24 #include <loggers/file_logger.h>
25 #include <filesystem/filename.h>
26 #include <configuration/ini_configurator.h>
27 #include <configuration/application_configuration.h>
28 #include <structures/static_memory_gremlin.h>
29 #include <processes/process_control.h>
30 #include <processes/process_entry.h>
31
32 using namespace application;
33 using namespace basis;
34 using namespace loggers;
35 using namespace filesystem;
36 using namespace processes;
37 using namespace structures;
38 using namespace textual;
39 using namespace timely;
40
41 #undef BASE_LOG
42 #define BASE_LOG(to_print) EMERGENCY_LOG(program_wide_logger::get(), astring(to_print))
43 #undef LOG
44 #define LOG(to_print) CLASS_EMERGENCY_LOG(program_wide_logger::get(), astring(to_print))
45
46 class await_app_exit : public application_shell
47 {
48 public:
49   await_app_exit() : application_shell() {}
50   DEFINE_CLASS_NAME("await_app_exit");
51   int execute();
52 };
53
54 int await_app_exit::execute()
55 {
56   FUNCDEF("execute");
57   SETUP_COMBO_LOGGER;
58   if (_global_argc < 3) {
59     BASE_LOG("This program needs two parameters on the command line.  The first is an");
60     BASE_LOG("application name (e.g. 'blofeld.exe' is a valid example--no path should be");
61     BASE_LOG("included but the .exe suffix must be included) to seek out in the process");
62     BASE_LOG("list and the second parameter is the time to wait for it to exit (in seconds).");
63     BASE_LOG("This program will not exit until the specified application is no longer");
64     BASE_LOG("running or the timeout elapses.  If the timeout elapses, then a failure exit");
65     BASE_LOG("will occur from this program so that it is known that the target application");
66     BASE_LOG("never exited.");
67     return 2;
68   }
69
70   astring app_name = _global_argv[1];  // get the app's name.
71   astring duration = _global_argv[2];  // get the time to wait.
72   int timeout = duration.convert(0) * 1000;
73   if (timeout < 0) {
74     LOG(astring("The timeout specified is invalid: ") + duration);
75     return 3;
76   }
77
78   // now see if that app is even running.
79   process_control querier;
80   process_entry_array processes;
81   querier.query_processes(processes);
82   int_set pids;
83   time_stamp when_to_leave(timeout);  // when we should stop checking.
84
85   // wait for the app to go away.
86   while (querier.find_process_in_list(processes, app_name, pids)) {
87     // the program of interest is still running.
88     time_control::sleep_ms(100);
89     querier.query_processes(processes);
90     if (time_stamp() > when_to_leave) {
91       LOG(astring("The timeout elapsed and ") + app_name + " is still running.");
92       return 4;
93     }
94   }
95   LOG(astring("The ") + app_name + " process has exited.");
96   return 0;
97 }
98
99 HOOPLE_MAIN(await_app_exit, )
100
101 #ifdef __BUILD_STATIC_APPLICATION__
102   // static dependencies found by buildor_gen_deps.sh:
103   #include <basis/byte_array.cpp>
104   #include <basis/callstack_tracker.cpp>
105   #include <basis/utf_conversion.cpp>
106   #include <basis/definitions.cpp>
107   #include <basis/earth_time.cpp>
108   #include <basis/guards.cpp>
109   #include <basis/astring.cpp>
110   #include <basis/log_base.cpp>
111   #include <basis/memory_checker.cpp>
112   #include <basis/mutex.cpp>
113   #include <basis/contracts.h>
114   #include <basis/outcome.cpp>
115   #include <basis/packable.cpp>
116   #include <basis/portable.cpp>
117   #include <basis/trap_new.addin>
118   #include <basis/untrap_new.addin>
119   #include <basis/utility.cpp>
120   #include <basis/version_record.cpp>
121   #include <structures/bit_vector.cpp>
122   #include <structures/byte_hasher.cpp>
123   #include <structures/configurator.cpp>
124   #include <structures/hash_table.h>
125   #include <structures/pointer_hash.h>
126   #include <structures/stack.h>
127   #include <structures/static_memory_gremlin.cpp>
128   #include <structures/string_hash.h>
129   #include <structures/string_hasher.cpp>
130   #include <structures/string_table.cpp>
131   #include <structures/symbol_table.h>
132   #include <structures/table_configurator.cpp>
133   #include <loggers/console_logger.cpp>
134   #include <loggers/file_logger.cpp>
135   #include <loggers/locked_logger.cpp>
136   #include <loggers/null_logger.cpp>
137   #include <loggers/program_wide_logger.cpp>
138   #include <timely/time_stamp.cpp>
139   #include <application/base_application.cpp>
140   #include <application/application_shell.cpp>
141   #include <filesystem/byte_filer.cpp>
142   #include <application/command_line.cpp>
143   #include <opsystem/critical_events.cpp>
144   #include <filesystem/directory.cpp>
145   #include <filesystem/filename.cpp>
146   #include <configuration/ini_configurator.cpp>
147   #include <opsystem/ini_parser.cpp>
148   #include <configuration/application_configuration.cpp>
149   #include <application/rendezvous.cpp>
150   #include <processes/process_control.cpp>
151   #include <processes/process_entry.cpp>
152   #include <textual/byte_formatter.cpp>
153   #include <textual/parser_bits.cpp>
154   #include <textual/string_manipulation.cpp>
155   #include <configuration/variable_tokenizer.cpp>
156 #endif // __BUILD_STATIC_APPLICATION__
157