瀏覽代碼

examples: add stdin_input

ambrop7 15 年之前
父節點
當前提交
34a1ff9ea5
共有 2 個文件被更改,包括 133 次插入0 次删除
  1. 3 0
      examples/CMakeLists.txt
  2. 130 0
      examples/stdin_input.c

+ 3 - 0
examples/CMakeLists.txt

@@ -36,6 +36,9 @@ if (NOT WIN32)
 
     add_executable(bprocess_example bprocess_example.c)
     target_link_libraries(bprocess_example system process)
+
+    add_executable(stdin_input stdin_input.c)
+    target_link_libraries(stdin_input system flow)
 endif ()
 
 if (CMAKE_SYSTEM_NAME STREQUAL "Linux")

+ 130 - 0
examples/stdin_input.c

@@ -0,0 +1,130 @@
+/**
+ * @file stdin_input.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.
+ * 
+ * @section DESCRIPTION
+ * 
+ * Example program which reads stdin and waits for SIGINT and SIGTERM.
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+
+#include <system/BReactor.c>
+#include <system/BSocket.h>
+#include <system/BUnixSignal.h>
+#include <system/DebugObject.h>
+#include <flow/StreamSocketSource.h>
+
+#define BUF_SIZE 64
+
+BReactor reactor;
+BSocket pipe_bsock;
+BUnixSignal usignal;
+FlowErrorDomain errdomain;
+StreamSocketSource source;
+StreamRecvInterface *source_if;
+uint8_t buf[BUF_SIZE + 1];
+
+static void signal_handler (void *user, int signo)
+{
+    fprintf(stderr, "received %s, exiting\n", (signo == SIGINT ? "SIGINT" : "SIGTERM"));
+    
+    // exit event loop
+    BReactor_Quit(&reactor, 1);
+}
+
+static void source_error_handle (void *user, int component, int code)
+{
+    if (code == 0) {
+        fprintf(stderr, "pipe closed\n");
+    } else {
+        fprintf(stderr, "pipe error\n");
+    }
+    
+    // exit event loop
+    BReactor_Quit(&reactor, (code == 0 ? 0 : 1));
+}
+
+static void input_handler_done (void *user, int data_len)
+{
+    // receive next chunk
+    StreamRecvInterface_Receiver_Recv(source_if, buf, BUF_SIZE);
+    
+    // print this chunk
+    buf[data_len] = '\0';
+    printf("Received: '%s'\n", buf);
+}
+
+int main ()
+{
+    int ret = 1;
+    
+    BLog_InitStdout();
+    
+    // init reactor (event loop)
+    if (!BReactor_Init(&reactor)) {
+        fprintf(stderr, "BReactor_Init failed\n");
+        goto fail1;
+    }
+    
+    // init signal handling
+    sigset_t set;
+    sigemptyset(&set);
+    sigaddset(&set, SIGINT);
+    sigaddset(&set, SIGTERM);
+    if (!BUnixSignal_Init(&usignal, &reactor, set, signal_handler, NULL)) {
+        fprintf(stderr, "BUnixSignal_Init failed\n");
+        goto fail2;
+    }
+    
+    // init BSocket object backed by the stdin fd
+    if (BSocket_InitPipe(&pipe_bsock, &reactor, 0) < 0) {
+        fprintf(stderr, "BSocket_InitPipe failed\n");
+        goto fail3;
+    }
+    
+    // init error handler
+    FlowErrorDomain_Init(&errdomain, source_error_handle, NULL);
+    
+    // init source (object for reading from a stream BSocket using StreamRecvInterface)
+    StreamSocketSource_Init(&source, FlowErrorReporter_Create(&errdomain, 0), &pipe_bsock, BReactor_PendingGroup(&reactor));
+    source_if = StreamSocketSource_GetOutput(&source);
+    
+    // init receive done callback
+    StreamRecvInterface_Receiver_Init(source_if, input_handler_done, NULL);
+    
+    // receive first chunk
+    StreamRecvInterface_Receiver_Recv(source_if, buf, BUF_SIZE);
+    
+    // run event loop
+    ret = BReactor_Exec(&reactor);
+    
+    StreamSocketSource_Free(&source);
+    BSocket_Free(&pipe_bsock);
+fail3:
+    BUnixSignal_Free(&usignal, 0);
+fail2:
+    BReactor_Free(&reactor);
+fail1:
+    BLog_Free();
+    DebugObjectGlobal_Finish();
+    return ret;
+}