1 /**
2  * Copyright: Copyright Jason White, 2014-2016
3  * License:   $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4  * Authors:   Jason White
5  */
6 module io.file.pipe;
7 
8 import io.file.stream;
9 
10 struct Pipe(F = File)
11     if (is(F == struct))
12 {
13     F readEnd;  // Read end
14     F writeEnd; // Write end
15 }
16 
17 /**
18  * Creates an unnamed, unidirectional pipe that can be written to on one end and
19  * read from on the other.
20  */
21 Pipe!F pipe(F = File)()
22     if (is(F == struct))
23 {
24     version (Posix)
25     {
26         import core.sys.posix.unistd : pipe;
27 
28         int[2] fd = void;
29         sysEnforce(pipe(fd) != -1);
30         return Pipe!F(F(fd[0]), F(fd[1]));
31     }
32     else version(Windows)
33     {
34         import core.sys.windows.windows : CreatePipe;
35 
36         F.Handle readEnd = void, writeEnd = void;
37         sysEnforce(CreatePipe(&readEnd, &writeEnd, null, 0));
38         return Pipe!F(F(readEnd), F(writeEnd));
39     }
40     else
41     {
42         static assert(false, "Unsupported platform.");
43     }
44 }
45 
46 ///
47 unittest
48 {
49     import core.thread : Thread;
50 
51     immutable message = "The quick brown fox jumps over the lazy dog.";
52 
53     auto p = pipe();
54 
55     void writer()
56     {
57         p.writeEnd.write(message);
58 
59         // Since this is buffered, it must be flushed in order to avoid a
60         // deadlock.
61         p.writeEnd.flush();
62     }
63 
64     auto thread = new Thread(&writer).start();
65 
66     // Read the message from the other thread.
67     char[message.length] buf;
68     assert(buf[0 .. p.readEnd.read(buf)] == message);
69 
70     thread.join();
71 }