ambrop7 15 лет назад
Родитель
Сommit
bb22f364a0
2 измененных файлов с 139 добавлено и 0 удалено
  1. 3 0
      examples/CMakeLists.txt
  2. 136 0
      examples/bprocess_example.c

+ 3 - 0
examples/CMakeLists.txt

@@ -36,4 +36,7 @@ if (NOT WIN32)
 
     add_executable(dhcpclient_test dhcpclient_test.c)
     target_link_libraries(dhcpclient_test dhcpclient)
+
+    add_executable(bprocess_example bprocess_example.c)
+    target_link_libraries(bprocess_example system)
 endif ()

+ 136 - 0
examples/bprocess_example.c

@@ -0,0 +1,136 @@
+/**
+ * @file bprocess_example.c
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * This file is part of BadVPN.
+ * 
+ * BadVPN is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ * 
+ * BadVPN is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stddef.h>
+#include <unistd.h>
+
+#include <misc/debug.h>
+#include <system/DebugObject.h>
+#include <system/BLog.h>
+#include <system/BReactor.h>
+#include <system/BSignal.h>
+#include <system/BTime.h>
+#include <system/BProcess.h>
+
+BReactor reactor;
+BProcessManager manager;
+BProcess process;
+
+static void terminate (int ret);
+static void signal_handler (void *user);
+static void process_handler (void *user, int normally, uint8_t normally_exit_status);
+
+int main (int argc, char **argv)
+{
+    if (argc <= 0) {
+        return 1;
+    }
+    
+    if (argc < 2) {
+        printf("Usage: %s <program> [argument ...]\n", argv[0]);
+        goto fail0;
+    }
+    
+    char *program = argv[1];
+    
+    BTime_Init();
+    
+    BLog_InitStdout();
+    
+    if (!BReactor_Init(&reactor)) {
+        DEBUG("BReactor_Init failed");
+        goto fail1;
+    }
+    
+    if (!BSignal_Init()) {
+        DEBUG("BSignal_Init failed");
+        goto fail2;
+    }
+    
+    BSignal_Capture();
+    
+    if (!BSignal_SetHandler(&reactor, signal_handler, NULL)) {
+        DEBUG("BSignal_SetHandler failed");
+        goto fail2;
+    }
+    
+    if (!BProcessManager_Init(&manager, &reactor)) {
+        DEBUG("BProcessManager_Init failed");
+        goto fail3;
+    }
+    
+    char **p_argv = argv + 1;
+    
+    if (!BProcess_Init(&process, &manager, process_handler, NULL, program, p_argv)) {
+        DEBUG("BProcess_Init failed");
+        goto fail4;
+    }
+    
+    int ret = BReactor_Exec(&reactor);
+    
+    BReactor_Free(&reactor);
+    
+    BLog_Free();
+    
+    DebugObjectGlobal_Finish();
+    
+    return ret;
+    
+fail4:
+    BProcessManager_Free(&manager);
+fail3:
+    BSignal_RemoveHandler();
+fail2:
+    BReactor_Free(&reactor);
+fail1:
+    BLog_Free();
+fail0:
+    DebugObjectGlobal_Finish();
+    return 1;
+}
+
+void terminate (int ret)
+{
+    BProcess_Free(&process);
+    
+    BProcessManager_Free(&manager);
+    
+    BSignal_RemoveHandler();
+    
+    BReactor_Quit(&reactor, ret);
+}
+
+void signal_handler (void *user)
+{
+    DEBUG("termination requested, passing to child");
+    
+    BProcess_Terminate(&process);
+}
+
+void process_handler (void *user, int normally, uint8_t normally_exit_status)
+{
+    DEBUG("process terminated");
+    
+    int ret = (normally ? normally_exit_status : 1);
+    
+    terminate(ret);
+}