From 37b6cd942c34d64d5c02aabf1a47f10e13453911 Mon Sep 17 00:00:00 2001
From: Jeremy Soller <jackpot51@gmail.com>
Date: Sat, 14 Jul 2018 12:29:18 -0600
Subject: [PATCH] Fix pipe

---
 src/platform/src/linux/mod.rs |  2 +-
 src/platform/src/redox/mod.rs |  2 +-
 src/unistd/src/lib.rs         |  6 ++---
 tests/expected/pipe.stdout    |  1 +
 tests/pipe.c                  | 44 ++++++++++++++++++++++++++++++++---
 5 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/src/platform/src/linux/mod.rs b/src/platform/src/linux/mod.rs
index 8ecfbc54..0cf01a27 100644
--- a/src/platform/src/linux/mod.rs
+++ b/src/platform/src/linux/mod.rs
@@ -214,7 +214,7 @@ pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
     e(unsafe { syscall!(OPENAT, AT_FDCWD, path, oflag, mode) }) as c_int
 }
 
-pub fn pipe(mut fildes: [c_int; 2]) -> c_int {
+pub fn pipe(fildes: &mut [c_int]) -> c_int {
     e(unsafe { syscall!(PIPE2, fildes.as_mut_ptr(), 0) }) as c_int
 }
 
diff --git a/src/platform/src/redox/mod.rs b/src/platform/src/redox/mod.rs
index bcf4da44..60326c4c 100644
--- a/src/platform/src/redox/mod.rs
+++ b/src/platform/src/redox/mod.rs
@@ -459,7 +459,7 @@ pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
     e(syscall::open(path, (oflag as usize) | (mode as usize))) as c_int
 }
 
-pub fn pipe(mut fds: [c_int; 2]) -> c_int {
+pub fn pipe(fds: &mut [c_int]) -> c_int {
     let mut usize_fds: [usize; 2] = [0; 2];
     let res = e(syscall::pipe2(&mut usize_fds, 0));
     fds[0] = usize_fds[0] as c_int;
diff --git a/src/unistd/src/lib.rs b/src/unistd/src/lib.rs
index 408143a7..d04d44c9 100644
--- a/src/unistd/src/lib.rs
+++ b/src/unistd/src/lib.rs
@@ -11,7 +11,7 @@ extern crate stdio;
 extern crate string;
 extern crate sys_utsname;
 
-use core::ptr;
+use core::{ptr, slice};
 
 use platform::types::*;
 
@@ -347,8 +347,8 @@ pub extern "C" fn pause() -> c_int {
 }
 
 #[no_mangle]
-pub extern "C" fn pipe(fildes: [c_int; 2]) -> c_int {
-    platform::pipe(fildes)
+pub unsafe extern "C" fn pipe(fildes: *mut c_int) -> c_int {
+    platform::pipe(slice::from_raw_parts_mut(fildes, 2))
 }
 
 // #[no_mangle]
diff --git a/tests/expected/pipe.stdout b/tests/expected/pipe.stdout
index e69de29b..980a0d5f 100644
--- a/tests/expected/pipe.stdout
+++ b/tests/expected/pipe.stdout
@@ -0,0 +1 @@
+Hello World!
diff --git a/tests/pipe.c b/tests/pipe.c
index 703073cc..cbd3caff 100644
--- a/tests/pipe.c
+++ b/tests/pipe.c
@@ -1,4 +1,5 @@
 //http://www2.cs.uregina.ca/~hamilton/courses/330/notes/unix/pipes/pipes.html
+#include <stdio.h>
 #include <string.h>
 #include <unistd.h>
 
@@ -9,26 +10,63 @@ int main()
     char instring[20];
     char * outstring = "Hello World!";
 
-    pipe(pip);
+    if (pipe(pip) < 0) {
+        perror("pipe");
+        return 1;
+    }
 
     pid = fork();
     if (pid == 0)           /* child : sends message to parent*/
     {
         /* close read end */
         close(pip[0]);
+
         /* send 7 characters in the string, including end-of-string */
-        write(pip[1], outstring, strlen(outstring));
+        int bytes = write(pip[1], outstring, strlen(outstring));
+
         /* close write end */
         close(pip[1]);
+
+        /* check result */
+        if (bytes < 0) {
+            perror("pipe write");
+            return 1;
+        } else if (bytes != strlen(outstring)) {
+            fprintf(stderr, "pipe write: %d != %d\n", bytes, strlen(outstring));
+            return 1;
+        }
+
+        return 0;
     }
     else			/* parent : receives message from child */
     {
         /* close write end */
         close(pip[1]);
+
+        /* clear memory */
+        memset(instring, 0, sizeof(instring));
+
         /* read from the pipe */
-        read(pip[0], instring, 7);
+        int bytes = read(pip[0], instring, sizeof(instring) - 1);
+
         /* close read end */
         close(pip[0]);
+
+        /* check result */
+        if (bytes < 0) {
+            perror("pipe read");
+            return 1;
+        } else if (bytes != strlen(outstring)) {
+            fprintf(stderr, "pipe read: %d != %d\n", bytes, strlen(outstring));
+            return 1;
+        } else if (memcmp(instring, outstring, sizeof(outstring)) != 0) {
+            fprintf(stderr, "pipe read does not match pipe write\n");
+            return 1;
+        } else {
+            printf("%s\n", instring);
+        }
+
+        return 0;
     }
     return 0;
 }
-- 
GitLab