Просмотр исходного кода

BInputProcess: allow starting the process after initializing the object, in case of errors after the object was initialized

ambrop7 14 лет назад
Родитель
Сommit
45d7499b49
3 измененных файлов с 59 добавлено и 21 удалено
  1. 45 18
      inputprocess/BInputProcess.c
  2. 5 1
      inputprocess/BInputProcess.h
  3. 9 2
      udevmonitor/NCDUdevMonitor.c

+ 45 - 18
inputprocess/BInputProcess.c

@@ -90,6 +90,7 @@ void pipe_source_handler_error (BInputProcess *o, int component, int code)
 void process_handler (BInputProcess *o, int normally, uint8_t normally_exit_status)
 {
     DebugObject_Access(&o->d_obj);
+    ASSERT(o->started)
     ASSERT(o->have_process)
     
     // free process
@@ -103,12 +104,13 @@ void process_handler (BInputProcess *o, int normally, uint8_t normally_exit_stat
     return;
 }
 
-int BInputProcess_Init (BInputProcess *o, const char *file, char *const argv[], const char *username, BReactor *reactor, BProcessManager *manager, void *user,
+int BInputProcess_Init (BInputProcess *o, BReactor *reactor, BProcessManager *manager, void *user,
                         BInputProcess_handler_terminated handler_terminated,
                         BInputProcess_handler_closed handler_closed)
 {
     // init arguments
     o->reactor = reactor;
+    o->manager = manager;
     o->user = user;
     o->handler_terminated = handler_terminated;
     o->handler_closed = handler_closed;
@@ -125,22 +127,12 @@ int BInputProcess_Init (BInputProcess *o, const char *file, char *const argv[],
         goto fail1;
     }
     
-    // start process
-    int fds[] = { pipefds[1], -1 };
-    int fds_map[] = { 1 };
-    if (!BProcess_InitWithFds(&o->process, manager, (BProcess_handler)process_handler, o, file, argv, username, fds, fds_map)) {
-        BLog(BLOG_ERROR, "BProcess_Init failed");
-        goto fail2;
-    }
-    
-    // set have process
-    o->have_process = 1;
-    
-    // remember pipe read end
+    // remember pipe fds
     o->pipe_fd = pipefds[0];
+    o->pipe_write_fd = pipefds[1];
     
-    // close pipe write end
-    ASSERT_FORCE(close(pipefds[1]) == 0)
+    // set not started
+    o->started = 0;
     
     DebugObject_Init(&o->d_obj);
     return 1;
@@ -158,9 +150,14 @@ void BInputProcess_Free (BInputProcess *o)
 {
     DebugObject_Free(&o->d_obj);
     
-    // free process
-    if (o->have_process) {
-        BProcess_Free(&o->process);
+    if (!o->started) {
+        // close pipe write end
+        ASSERT_FORCE(close(o->pipe_write_fd) == 0)
+    } else {
+        // free process
+        if (o->have_process) {
+            BProcess_Free(&o->process);
+        }
     }
     
     if (o->pipe_fd >= 0) {
@@ -172,9 +169,38 @@ void BInputProcess_Free (BInputProcess *o)
     }
 }
 
+int BInputProcess_Start (BInputProcess *o, const char *file, char *const argv[], const char *username)
+{
+    DebugObject_Access(&o->d_obj);
+    ASSERT(!o->started)
+    
+    // start process
+    int fds[] = { o->pipe_write_fd, -1 };
+    int fds_map[] = { 1 };
+    if (!BProcess_InitWithFds(&o->process, o->manager, (BProcess_handler)process_handler, o, file, argv, username, fds, fds_map)) {
+        BLog(BLOG_ERROR, "BProcess_Init failed");
+        goto fail0;
+    }
+    
+    // close pipe write end
+    ASSERT_FORCE(close(o->pipe_write_fd) == 0)
+    
+    // set started
+    o->started = 1;
+    
+    // set have process
+    o->have_process = 1;
+    
+    return 1;
+    
+fail0:
+    return 0;
+}
+
 int BInputProcess_Terminate (BInputProcess *o)
 {
     DebugObject_Access(&o->d_obj);
+    ASSERT(o->started)
     ASSERT(o->have_process)
     
     return BProcess_Terminate(&o->process);
@@ -183,6 +209,7 @@ int BInputProcess_Terminate (BInputProcess *o)
 int BInputProcess_Kill (BInputProcess *o)
 {
     DebugObject_Access(&o->d_obj);
+    ASSERT(o->started)
     ASSERT(o->have_process)
     
     return BProcess_Kill(&o->process);

+ 5 - 1
inputprocess/BInputProcess.h

@@ -34,9 +34,12 @@ typedef void (*BInputProcess_handler_closed) (void *user, int is_error);
 
 typedef struct {
     BReactor *reactor;
+    BProcessManager *manager;
     void *user;
     BInputProcess_handler_terminated handler_terminated;
     BInputProcess_handler_closed handler_closed;
+    int pipe_write_fd;
+    int started;
     int have_process;
     BProcess process;
     int pipe_fd;
@@ -46,10 +49,11 @@ typedef struct {
     DebugObject d_obj;
 } BInputProcess;
 
-int BInputProcess_Init (BInputProcess *o, const char *file, char *const argv[], const char *username, BReactor *reactor, BProcessManager *manager, void *user,
+int BInputProcess_Init (BInputProcess *o, BReactor *reactor, BProcessManager *manager, void *user,
                         BInputProcess_handler_terminated handler_terminated,
                         BInputProcess_handler_closed handler_closed) WARN_UNUSED;
 void BInputProcess_Free (BInputProcess *o);
+int BInputProcess_Start (BInputProcess *o, const char *file, char *const argv[], const char *username);
 int BInputProcess_Terminate (BInputProcess *o);
 int BInputProcess_Kill (BInputProcess *o);
 StreamRecvInterface * BInputProcess_GetInput (BInputProcess *o);

+ 9 - 2
udevmonitor/NCDUdevMonitor.c

@@ -111,7 +111,7 @@ int NCDUdevMonitor_Init (NCDUdevMonitor *o, BReactor *reactor, BProcessManager *
     const char **argv = (is_info_mode ? argv_info : argv_monitor);
     
     // init process
-    if (!BInputProcess_Init(&o->process, STDBUF_EXEC, (char **)argv, NULL, reactor, manager, o,
+    if (!BInputProcess_Init(&o->process, reactor, manager, o,
                             (BInputProcess_handler_terminated)process_handler_terminated,
                             (BInputProcess_handler_closed)process_handler_closed
     )) {
@@ -132,6 +132,12 @@ int NCDUdevMonitor_Init (NCDUdevMonitor *o, BReactor *reactor, BProcessManager *
         goto fail1;
     }
     
+    // start process
+    if (!BInputProcess_Start(&o->process, STDBUF_EXEC, (char **)argv, NULL)) {
+        BLog(BLOG_ERROR, "BInputProcess_Start failed");
+        goto fail2;
+    }
+    
     // set process running, input running
     o->process_running = 1;
     o->input_running = 1;
@@ -140,9 +146,10 @@ int NCDUdevMonitor_Init (NCDUdevMonitor *o, BReactor *reactor, BProcessManager *
     DebugObject_Init(&o->d_obj);
     return 1;
     
+fail2:
+    NCDUdevMonitorParser_Free(&o->parser);
 fail1:
     StreamRecvConnector_Free(&o->connector);
-    BInputProcess_Kill(&o->process);
     BInputProcess_Free(&o->process);
 fail0:
     return 0;