If you need unrelated processes to be able to exchange data you can do this using FIFOs, often referred to as named pipes. A named pipe is a special type of file (everything is a file in linux!) that exists as a name in the file system but behaves like unnamed pipes. Once created data can be passed through it, i.e. to pass data to your application or read data from it.
Creating A Named Pipe / FIFO For Receiving Input
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define OUR_INPUT_FIFO_NAME "/tmp/my_fifo"
int our_input_fifo_filestream = -1;
//--------------------------------------
//----- CREATE A FIFO / NAMED PIPE -----
//--------------------------------------
int result;
printf("Making FIFO...\n");
result = mkfifo(OUR_INPUT_FIFO_NAME, 0777); //(This will fail if the fifo already exists in the system from the app previously running, this is fine)
if (result == 0)
{
//FIFO CREATED
printf("New FIFO created: %s\n", OUR_INPUT_FIFO_NAME);
}
printf("Process %d opening FIFO %s\n", getpid(), OUR_INPUT_FIFO_NAME);
our_input_fifo_filestream = open(OUR_INPUT_FIFO_NAME, (O_RDONLY | O_NONBLOCK));
//Possible flags:
// O_RDONLY - Open for reading only.
// O_WRONLY - Open for writing only.
// O_NDELAY / O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status
// if there is no input immediately available (instead of blocking). Likewise, write requests can also return
// immediately with a failure status if the output can't be written immediately.
if (our_input_fifo_filestream != -1)
printf("Opened FIFO: %i\n", our_input_fifo_filestream);
Note that although this code asks for a mode of 0777, it will be altered by the user mask (umask) setting just as in normal file creation.
A program may not open a FIFO for reading and writing with the mode O_RDWR. Use seperate pipes if you want to read and write.
Checking For Received Bytes
//---------------------------------------------
//----- CHECK FIFO FOR ANY RECEIVED BYTES -----
//---------------------------------------------
// Read up to 255 characters from the port if they are there
if (our_input_fifo_filestream != -1)
{
unsigned char rx_buffer[256];
int rx_length = read(our_input_fifo_filestream, (void*)rx_buffer, 255); //Filestream, buffer to store in, number of bytes to read (max)
if (rx_length < 0)
{
//An error occured (this can happen)
//printf("FIFO Read error\n");
}
else if (rx_length == 0)
{
//No data waiting
}
else
{
//Bytes received
rx_buffer[rx_length] = '\0';
printf("FIFO %i bytes read : %s\n", rx_length, rx_buffer);
}
}
Closing The FIFO
//----- CLOSE THE FIFO -----
(void)close(our_input_fifo_filestream);
Close FIFO From Command Line
This can be needed when debugging. Normally you don't have to close a fifo to be able to use it again but it is possible to sometimes cause a fifo to not work properly when used again ( maybe by not having emptied it before your application closes?), but using this will kill it completely ready for the next time your app is run to re-create it.
sudo rm /tmp/my_fifo
Sending data to your applications FIFO
Sending from a command prompt
echo "ABCD" > /tmp/my_fifo
Sending from C++
char buffer[] = "ABCD";
write(our_input_fifo_filestream, (void*)buffer, strlen(buffer));
Sending bytes from a PHP web page
<?php
system("sudo sh -c 'echo \"ABCD\" > tmp/my_fifo'");
?>
PHP Web page Access
See our PHP web page example here
Using pipes between main application and child threads
See this example here.
Other Methods Of Passing Data Between Processes
See Shared Memory here.
10 years ago
When I tried the php method stated above within my php program,
I get an error: “sudo: no tty present and no askpass program specified”.
What syntax do I need to avoid this error?
Thanks in advance.
Pingback: Web Interfaces « Raspberry Pi Projects