I'm trying to communicate between NodeJS and C program using named pipes in linux. My server program has written in NodeJS:
'use strict';
const net = require('net');
const pipename = '/tmp/pipe1';
const fs = require('fs');
let server = net.createServer(function(socket){
console.log('A new connection');
socket.on('data',function(data){
console.log(data.toString());
});
socket.on('end',function(){
console.log('Closed connection');
});
});
server.on('error',console.log);
fs.unlink(pipename,function(){
server.listen(pipename);
})
//Test unix-socket server:
setInterval(function(){
var stream = net.connect(pipename);
stream.on('error',console.log);
stream.write('hello');
stream.end();
},2000);
However, when I want to open the pipe inside C even after the NodeJS server has already started, I get error:
const char* pipename = "/tmp/pipe1";
int hPipe = open(pipename, O_WRONLY); //Error: No such device or address
When I try to do echo 'Hello World!' > /tmp/pipe1
,I get bash: /tmp/pipe1: No such device or address
. But ls -l /tmp
yields:
srwxr-xr-x 1 root root 0 Sep 16 03:20 pipe1
How can I solve this issue?
CodePudding user response:
The /tmp/pipe1
is not a pipe file. It's a socket file. That's what the leading s
means in srwxr-xr-x
.
And Bash's redirection like >
does not support socket files. You need to use socket API to open the file.
With strace (e.g. strace bash -c 'echo > /tmp/sockfile'
) we can see:
...
openat(AT_FDCWD, "/tmp/sockfile", O_WRONLY|O_CREAT|O_TRUNC, 0666) = -1 ENXIO (No such device or address)
...
So the error code is ENXIO
whose corresponding error message is No such device or address
. Bash is just calling standard C API (like strerror) to print the error.
Exampe code for client side:
int
sock_connect(char * sockpath)
{
int sock_fd;
struct sockaddr_un srv_addr = { 0 };
sock_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (sock_fd < 0) {
return -1;
}
srv_addr.sun_family = AF_LOCAL;
snprintf(srv_addr.sun_path, sizeof(srv_addr.sun_path), "%s", sockpath);
if (connect(sock_fd, (struct sockaddr *) & srv_addr, sizeof(srv_addr) ) < 0) {
return -1;
}
return sock_fd;
}