IPC via named pipe: Difference between revisions

Added FreeBASIC
(added Perl programming solution)
(Added FreeBASIC)
 
(7 intermediate revisions by 3 users not shown)
Line 12:
=={{header|C}}==
{{libheader|pthread}}
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
Line 102:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="vbnet">#Include "file.bi"
 
Type FileInfo
As String path
As Integer oflag
End Type
 
Function OpenFile(file As FileInfo) As Integer
Dim As Integer f = Freefile
Open file.path For Binary Access Read Write As #f
If Lof(f) > 0 Then
Print "Error opening file"
Return -1
End If
Return f
End Function
 
Function ReadFromFile(f As Integer, Byref buf As String, size As Integer) As Integer
Get #f, , buf
Return Len(buf)
End Function
 
Sub WriteToFile(f As Integer, buf As String, size As Integer)
Put #f, , buf
End Sub
 
Dim As FileInfo inputFile
inputFile.path = "in.fifo"
inputFile.oflag = 0
 
Dim As FileInfo outputFile
outputFile.path = "out.fifo"
outputFile.oflag = 1
 
Dim As Integer entrada = OpenFile(inputFile)
Dim As Integer salida = OpenFile(outputFile)
 
If entrada = -1 Or salida = -1 Then
Print "Error opening files"
End
End If
 
Dim As String buffer
Dim As Integer bytesRead
Do
bytesRead = ReadFromFile(entrada, buffer, 64)
If bytesRead > 0 Then WriteToFile(salida, buffer, bytesRead)
Loop</syntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 177 ⟶ 227:
output.Close()
}
}</langsyntaxhighlight>
 
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight Perllang="perl"># 20200924 added Perl programming solution
 
use strict;
Line 214 ⟶ 264:
}
sleep .5;
}</langsyntaxhighlight>
{{out}}
Terminal 1
Line 239 ⟶ 289:
cat /tmp/DdWOGVOaBI
7083641^C</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\IPC_via_named_pipe.exw
-- ===================================
--
-- Note: uses a single bidirectional pipe, Windows only, and no attempt has been
-- made to avoid blocking, this sort of code should be put in a separate thread.
--
-- Running normally starts this as a server which automatically creates a client.
--
-- Several additional Windows-only routines have been added to builtins/pipeio.e
-- which will not be formally documented until they are fully Linux-compatible.
--</span>
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.1"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #004600;">WINDOWS</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (obviously this will never ever run in a browser!)</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">/</span><span style="color: #000000;">pipeio</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">szPipename</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">`\\.\pipe\mynamedpipe`</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">cl</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">command_line</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">rand_string</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">100</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand_range</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'Z'</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"-client"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cl</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Server\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">dwPipeMode</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">or_all</span><span style="color: #0000FF;">({</span><span style="color: #000000;">PIPE_TYPE_MESSAGE</span><span style="color: #0000FF;">,</span><span style="color: #000000;">PIPE_READMODE_MESSAGE</span><span style="color: #0000FF;">,</span><span style="color: #000000;">PIPE_WAIT</span><span style="color: #0000FF;">}),</span>
<span style="color: #000000;">totalsofar</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">pBuffer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1024</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">pBytesRead</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">pBytesWritten</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">hPipe</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">create_named_pipe</span><span style="color: #0000FF;">(</span><span style="color: #000000;">szPipename</span><span style="color: #0000FF;">,</span><span style="color: #000000;">PIPE_ACCESS_DUPLEX</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dwPipeMode</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">system_exec</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`"%s" "%s" -client`</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cl</span><span style="color: #0000FF;">),</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">connect_named_pipe</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hPipe</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">read_pipe</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hPipe</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pBuffer</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1024</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pBytesRead</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">res</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\nsleep??\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">sleep</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.25</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">else</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">bytesread</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">peek4s</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pBytesRead</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">msg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">peek</span><span style="color: #0000FF;">({</span><span style="color: #000000;">pBuffer</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bytesread</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">bytesread</span><span style="color: #0000FF;">=</span><span style="color: #000000;">4</span> <span style="color: #008080;">and</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">=</span><span style="color: #008000;">"quit"</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\nquit recieved, quitting\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">totalsofar</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">bytesread</span>
<span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"bytesread:%,d total so far:%,d "</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">bytesread</span><span style="color: #0000FF;">,</span><span style="color: #000000;">totalsofar</span><span style="color: #0000FF;">})</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">reply</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%,d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">totalsofar</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">write_pipe</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hPipe</span><span style="color: #0000FF;">,</span><span style="color: #000000;">reply</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pBytesWritten</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">res</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">peek4s</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pBytesWritten</span><span style="color: #0000FF;">)!=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">reply</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">flush_pipe</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hPipe</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">disconnect_pipe</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hPipe</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">free</span><span style="color: #0000FF;">({</span><span style="color: #000000;">pBytesWritten</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pBuffer</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pBytesRead</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">close_handle</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hPipe</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">else</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Client\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Press Escape or Q to quit\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">running_total</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">get_key</span><span style="color: #0000FF;">(),{</span><span style="color: #008000;">'q'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'Q'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#1B</span><span style="color: #0000FF;">})</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">msg</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rand_string</span><span style="color: #0000FF;">(),</span>
<span style="color: #000000;">reply</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">call_named_pipe</span><span style="color: #0000FF;">(</span><span style="color: #000000;">szPipename</span><span style="color: #0000FF;">,</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">running_total</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">bOK</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">reply</span><span style="color: #0000FF;">==</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%,d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">running_total</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"set %d bytes, reply:%s, running_total:%,d (same:%t)"</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">reply</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">running_total</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">bOK</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">bOK</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\nsome error, quitting...\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">call_named_pipe</span><span style="color: #0000FF;">(</span><span style="color: #000000;">szPipename</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"quit"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</syntaxhighlight>-->
{{out}}
After letting it run for about 5s before hitting escape, on separate terminal windows:
<pre>
Server
bytesread:19 total so far:2,136,798
quit recieved, quitting
 
Client
Press Escape or Q to quit
set 19 bytes, reply:2,136,798, running_total:2,136,798 (same:true)
</pre>
 
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(call 'mkfifo "in" "out") # Create pipes
 
(zero *Cnt) # Initialize byte counter
Line 260 ⟶ 406:
 
(push '*Bye '(call 'rm "in" "out")) # Remove pipes upon exit
(wait) # (Terminate with Ctrl-C)</langsyntaxhighlight>
Test:
<pre>$ line <out
Line 272 ⟶ 418:
 
=={{header|Racket}}==
<langsyntaxhighlight Racketlang="racket">#lang racket
 
(define-values (in out) (make-pipe))
Line 295 ⟶ 441:
 
(thread-wait t1)
(thread-wait t2)</langsyntaxhighlight>
 
=={{header|Raku}}==
{{incorrect|Raku| Blocks on the read pipe and not able to empty/update the write pipe according to the task requirement }}
Couldn't figure out how to get around the IO blockages as per the talk page so any help would be appreciated, thanks in advance.
<syntaxhighlight lang="raku" perl6line># 20200923 Added Raku programming solution
 
use NativeCall;
Line 333 ⟶ 479:
}
sleep ½;
}</langsyntaxhighlight>
{{out}}
Terminal 1
Line 363 ⟶ 509:
{{works with|Unix}}
 
<langsyntaxhighlight lang="ruby">require 'socket'
 
# Ruby has no direct access to mkfifo(2). We use a shell script.
Line 423 ⟶ 569:
end
end
end</langsyntaxhighlight>
 
Example run:
Line 441 ⟶ 587:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl"># Make the pipes by calling a subprocess...
exec sh -c {test -p in || mkfifo in || exit 1;test -p out || exec mkfifo out}
 
Line 472 ⟶ 618:
 
# Run the event loop until done
vwait forever</langsyntaxhighlight>
 
=={{header|Wren}}==
{{trans|C}}
{{libheader|pthread}}
An embedded program using a C host as Wren has no built in support for named pipes.
 
As in the case of the C example, we run the 'write' loop on a separate thread and using a separate VM. The 'tally' variable is stored on the C side so it can be shared by both VM's.
 
This works fine on Ubuntu 20.04 and should work on other Linux distros though I can't vouch for anything else.
<syntaxhighlight lang="wren">/* IPC_via_named_pipe.wren */
 
var InputFifo = "in"
var OutputFifo = "out"
 
var O_RDONLY = 0
var O_WRONLY = 1
 
var PIPE_BUF = 4096
 
class Fifo {
foreign static make(path, oflag)
}
 
class File {
foreign static open(path, flags)
 
foreign static write(fd, str, size)
 
foreign static read(fd, size)
 
foreign static close(fd)
}
 
class C {
foreign static usleep(usec)
 
foreign static tally
foreign static tally=(newTally)
}
 
class Loops {
static read() {
while (true) {
var fd = File.open(InputFifo, O_RDONLY)
var len
while ((len = File.read(fd, PIPE_BUF)) > 0) C.tally = C.tally + len
File.close(fd)
}
}
 
static write() {
while (true) {
var fd = File.open(OutputFifo, O_WRONLY)
var ts = C.tally.toString + "\n"
File.write(fd, ts, ts.bytes.count)
File.close(fd)
C.usleep(10000)
}
}
}
 
Fifo.make(InputFifo, 438)
Fifo.make(OutputFifo, 438)</syntaxhighlight>
<br>
We now embed this script in the following C program, build and run from one terminal.
<syntaxhighlight lang="c">/* gcc IPC_via_named_pipe.c -o IPC_via_named_pipe -lpthread -lwren -lm */
 
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>
#include "wren.h"
 
/* C <=> Wren interface functions */
 
size_t tally = 0;
 
void C_make(WrenVM* vm) {
const char *pathname = wrenGetSlotString(vm, 1);
mode_t mode = (mode_t)wrenGetSlotDouble(vm, 2);
int res = mkfifo(pathname, mode);
wrenSetSlotDouble(vm, 0, (double)res);
}
 
void C_open(WrenVM* vm) {
const char *pathname = wrenGetSlotString(vm, 1);
int flags = (int)wrenGetSlotDouble(vm, 2);
int fd = open(pathname, flags);
if (fd < 0) {
perror(NULL);
}
wrenSetSlotDouble(vm, 0, (double)fd);
}
 
void C_write(WrenVM* vm) {
int fd = (int)wrenGetSlotDouble(vm, 1);
const char *str = wrenGetSlotString(vm, 2);
size_t count = (size_t)wrenGetSlotDouble(vm, 3);
ssize_t res = write(fd, (const void *)str, count + 1);
wrenSetSlotDouble(vm, 0, (double)res);
}
 
void C_read(WrenVM* vm) {
int fd = (int)wrenGetSlotDouble(vm, 1);
size_t nbyte = (size_t)wrenGetSlotDouble(vm, 2);
char buf[nbyte];
ssize_t res = read(fd, buf, nbyte);
wrenSetSlotDouble(vm, 0, (double)res);
}
 
void C_close(WrenVM* vm) {
int fd = (int)wrenGetSlotDouble(vm, 1);
int res = close(fd);
wrenSetSlotDouble(vm, 0, (double)res);
}
 
void C_usleep(WrenVM* vm) {
useconds_t usec = (useconds_t)wrenGetSlotDouble(vm, 1);
int res = usleep(usec);
wrenSetSlotDouble(vm, 0, (double)res);
}
 
void C_getTally(WrenVM* vm) {
wrenSetSlotDouble(vm, 0, (double)tally);
}
 
void C_setTally(WrenVM* vm) {
size_t newTally = (size_t)wrenGetSlotDouble(vm, 1);
tally = newTally;
}
 
WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "Fifo") == 0) {
if (isStatic && strcmp(signature, "make(_,_)") == 0) return C_make;
} else if (strcmp(className, "File") == 0) {
if (isStatic && strcmp(signature, "open(_,_)") == 0) return C_open;
if (isStatic && strcmp(signature, "write(_,_,_)") == 0) return C_write;
if (isStatic && strcmp(signature, "read(_,_)") == 0) return C_read;
if (isStatic && strcmp(signature, "close(_)") == 0) return C_close;
} else if (strcmp(className, "C") == 0) {
if (isStatic && strcmp(signature, "usleep(_)") == 0) return C_usleep;
if (isStatic && strcmp(signature, "tally") == 0) return C_getTally;
if (isStatic && strcmp(signature, "tally=(_)") == 0) return C_setTally;
}
}
return NULL;
}
 
static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}
 
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
switch (errorType) {
case WREN_ERROR_COMPILE:
printf("[%s line %d] [Error] %s\n", module, line, msg);
break;
case WREN_ERROR_STACK_TRACE:
printf("[%s line %d] in %s\n", module, line, msg);
break;
case WREN_ERROR_RUNTIME:
printf("[Runtime Error] %s\n", msg);
break;
}
}
 
char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
fread(script, 1, fsize, f);
fclose(f);
script[fsize] = 0;
return script;
}
 
WrenVM *vm, *vm2;
 
void read_loop() {
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "main", "Loops", 0);
WrenHandle *method = wrenMakeCallHandle(vm, "read()");
wrenCall(vm, method);
wrenReleaseHandle(vm, method);
}
 
void* write_loop(void *a) {
wrenEnsureSlots(vm2, 1);
wrenGetVariable(vm2, "main", "Loops", 0);
WrenHandle *method = wrenMakeCallHandle(vm2, "write()");
wrenCall(vm2, method);
wrenReleaseHandle(vm2, method);
}
 
int main(int argc, char **argv) {
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.bindForeignMethodFn = &bindForeignMethod;
vm = wrenNewVM(&config);
vm2 = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "IPC_via_named_pipe.wren";
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
switch (result) {
case WREN_RESULT_COMPILE_ERROR:
printf("Compile Error!\n");
break;
case WREN_RESULT_RUNTIME_ERROR:
printf("Runtime Error!\n");
break;
case WREN_RESULT_SUCCESS:
break;
}
wrenInterpret(vm2, module, script);
pthread_t pid;
pthread_create(&pid, 0, write_loop, 0);
read_loop();
wrenFreeVM(vm);
wrenFreeVM(vm2);
free(script);
return 0;
}</syntaxhighlight>
<br>
{{out}}
Finally we can test that this is working correctly by typing in the following commands from a different terminal. The string lengths returned will, of course, include the final zero byte.
<pre>
$ cat out
0
$ echo test > in
$ cat out
5
$ echo "named pipe" > in
$ cat out
16
</pre>
 
=={{header|zkl}}==
zkl doesn't open pipes but it knows about them (on Unix anyway as they are just a file). So, outside of the program, create two named pipes and read/write to them inside the program.
{{trans|C}}
<langsyntaxhighlight lang="zkl">pipe:=Thread.Pipe(); // NOT a Unix pipe, for inter-thread commication
fcn writeLoop(pipe){ // a thread
out:=File("out","w");
Line 494 ⟶ 889:
}.launch(pipe);
 
while(1){ Atomic.sleep(10000); } // veg out while other talk</langsyntaxhighlight>
{{out}}
Terminal 1:
2,122

edits