IPC via named pipe: Difference between revisions
Added FreeBASIC
(Added Wren) |
(Added FreeBASIC) |
||
(5 intermediate revisions by 2 users not shown) | |||
Line 12:
=={{header|C}}==
{{libheader|pthread}}
<
#include <sys/stat.h>
#include <unistd.h>
Line 102:
return 0;
}</
=={{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}}==
<
import (
Line 177 ⟶ 227:
output.Close()
}
}</
=={{header|Perl}}==
{{trans|Raku}}
<
use strict;
Line 214 ⟶ 264:
}
sleep .5;
}</
{{out}}
Terminal 1
Line 241 ⟶ 291:
=={{header|Phix}}==
<!--<
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\IPC_via_named_pipe.exw
Line 322 ⟶ 372:
<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>
<!--</
{{out}}
After letting it run for about 5s before hitting escape, on separate terminal windows:
Line 337 ⟶ 387:
=={{header|PicoLisp}}==
<
(zero *Cnt) # Initialize byte counter
Line 356 ⟶ 406:
(push '*Bye '(call 'rm "in" "out")) # Remove pipes upon exit
(wait) # (Terminate with Ctrl-C)</
Test:
<pre>$ line <out
Line 368 ⟶ 418:
=={{header|Racket}}==
<
(define-values (in out) (make-pipe))
Line 391 ⟶ 441:
(thread-wait t1)
(thread-wait t2)</
=={{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"
use NativeCall;
Line 429 ⟶ 479:
}
sleep ½;
}</
{{out}}
Terminal 1
Line 459 ⟶ 509:
{{works with|Unix}}
<
# Ruby has no direct access to mkfifo(2). We use a shell script.
Line 519 ⟶ 569:
end
end
end</
Example run:
Line 537 ⟶ 587:
=={{header|Tcl}}==
<
exec sh -c {test -p in || mkfifo in || exit 1;test -p out || exec mkfifo out}
Line 568 ⟶ 618:
# Run the event loop until done
vwait forever</
=={{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.
<
var
var
var O_RDONLY = 0
Line 585 ⟶ 637:
var PIPE_BUF = 4096
class Fifo {
Line 602 ⟶ 652:
}
class C {
foreign static
foreign static tally=(newTally)
}
class Loops {
var
while ((len = File.
}
}
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.
<
#include <stdio.h>
Line 642 ⟶ 692:
#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);
Line 685 ⟶ 736:
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;
}
Line 695 ⟶ 761:
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;
Line 734 ⟶ 804:
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);
}
Line 742 ⟶ 830:
config.errorFn = &errorFn;
config.bindForeignMethodFn = &bindForeignMethod;
vm2 = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
Line 757 ⟶ 846:
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;
}</
<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
Line 776 ⟶ 872:
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}}
<
fcn writeLoop(pipe){ // a thread
out:=File("out","w");
Line 793 ⟶ 889:
}.launch(pipe);
while(1){ Atomic.sleep(10000); } // veg out while other talk</
{{out}}
Terminal 1:
|