浏览代码

feat(test_fifo_write): 增强FIFO写入测试,添加信号处理和多场景测试

xiaolin2004 4 月之前
父节点
当前提交
d1e5b8ffb4
共有 1 个文件被更改,包括 96 次插入13 次删除
  1. 96 13
      user/apps/test_fifo_write/main.c

+ 96 - 13
user/apps/test_fifo_write/main.c

@@ -3,35 +3,118 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
+#include <signal.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
 
 #define FIFO_PATH "/bin/test_fifo"
 
-int main() {
-    // 创建 FIFO
-    if (mkfifo(FIFO_PATH, 0666) == -1 && errno != EEXIST) {
-        perror("mkfifo failed");
-        exit(EXIT_FAILURE);
+// 信号处理函数
+void sigpipe_handler(int signo) {
+    if (signo == SIGPIPE) {
+        printf("Received SIGPIPE signal. Write operation failed.\n");
     }
+}
+
+void test_fifo_write(const char *scenario_desc, int nonblocking) {
+    int fd;
+    char *data = "Hello, FIFO!";
+    printf("\n--- Testing: %s ---\n", scenario_desc);
 
-    printf("Opening FIFO in write mode...\n");
+    // 设置 O_NONBLOCK 标志
+    int flags = O_WRONLY;
+    if (nonblocking) {
+        flags |= O_NONBLOCK;
+    }
 
-    // 尝试以非阻塞模式打开 FIFO 的写端
-    int fd = open(FIFO_PATH, O_WRONLY|O_NONBLOCK);
-    printf("fd: %d\n",fd);
+    // 打开 FIFO 写端
+    fd = open(FIFO_PATH, flags);
     if (fd == -1) {
         if (errno == ENXIO) {
-            printf("Error: No readers (ENXIO).\n");
+            printf("Result: Failed to open FIFO for writing (ENXIO: No readers).\n");
+        } else {
+            perror("Failed to open FIFO for writing");
+        }
+        return;
+    }
+
+    // 写入数据
+    ssize_t bytes_written = write(fd, data, sizeof(data));
+    if (bytes_written == -1) {
+        if (errno == EPIPE) {
+            printf("Result: Write failed with EPIPE (no readers available).\n");
+        } else if (errno == ENXIO) {
+            printf("Result: Write failed with ENXIO (FIFO never had readers).\n");
         } else {
-            perror("Failed to open FIFO");
+            perror("Write failed with an unexpected error");
         }
     } else {
-        printf("FIFO opened successfully in write mode.\n");
-        close(fd);
+        printf("Result: Write succeeded. Bytes written: %zd\n", bytes_written);
     }
 
+    // 关闭 FIFO 写端
+    close(fd);
+}
+
+void run_tests() {
+    pid_t reader_pid;
+
+    // Case 1: Test with no readers (FIFO never had readers)
+    test_fifo_write("No readers (FIFO never had readers)", 1);
+
+    // Case 2: Test with a reader that disconnects
+    reader_pid = fork();
+    if (reader_pid == 0) {
+        // 子进程充当读端
+        int reader_fd = open(FIFO_PATH, O_RDONLY);
+        if (reader_fd == -1) {
+            perror("Reader failed to open FIFO");
+            exit(EXIT_FAILURE);
+        }
+        sleep(1); // 模拟读端短暂存在
+        close(reader_fd);
+        exit(EXIT_SUCCESS);
+    }
+
+    sleep(5); // 确保读端已打开
+    test_fifo_write("Reader exists but disconnects", 0);
+    waitpid(reader_pid, NULL, 0); // 等待读端子进程退出
+
+    // Case 3: Test with an active reader
+    reader_pid = fork();
+    if (reader_pid == 0) {
+        // 子进程充当读端
+        int reader_fd = open(FIFO_PATH, O_RDONLY);
+        if (reader_fd == -1) {
+            perror("Reader failed to open FIFO");
+            exit(EXIT_FAILURE);
+        }
+        sleep(5); // 保持读端存在
+        close(reader_fd);
+        exit(EXIT_SUCCESS);
+    }
+
+    sleep(1); // 确保读端已打开
+    test_fifo_write("Active reader exists", 0);
+    waitpid(reader_pid, NULL, 0); // 等待读端子进程退出
+}
+
+int main() {
+    // 设置 SIGPIPE 信号处理
+    signal(SIGPIPE, sigpipe_handler);
+
+    // 创建 FIFO
+    if (mkfifo(FIFO_PATH, 0666) == -1 && errno != EEXIST) {
+        perror("mkfifo failed");
+        exit(EXIT_FAILURE);
+    }
+
+    // 运行测试
+    run_tests();
+
     // 删除 FIFO
     unlink(FIFO_PATH);
 
+    printf("\nAll tests completed.\n");
     return 0;
 }