views:

63

answers:

2

Hi, i am using a named pipe for IPC on a Debian system. I will be sending some data as a set of strings from a bash script to a background running process written in C code.

The data i want to send is four strings eg accountid, firstname,surname, description. Currently i am sending the data as a char array separated by spaces from my bash script.

echo "accountid firstname surname description" >$pipe

In the background process i read the pipe data like this into char array 'datain'

res = read(pipe_fd, datain, BUFFER_SIZE);

then i am just iterating over the array looking for spaces

eg

char* p = datain;

char accountid[80];
char firstname[80];

// extract the accountid
while(p!='')
{
    accountid = p;
    ++p;
}

++p;

while(p!='')
{
    firstname = p;
    ++p;
}

etc....

This method seems a bit crude however my programming skills are not that good so i was wondering if there was a better strategy for transferring this set of data over a named pipe in Linux.

Thanks

+2  A: 
  • A pipe (named or not) is a stream of bytes. If you were using the same language on both sides, there might be a better way of sending structured data. In your situation, a manual encoding and decoding, like you're doing, is by far the easiest solution.

  • Don't use spaces to separate fields that may contain spaces, such as people's names. Use :, like /etc/passwd.

  • In C, read is hard to use, because you have to decide on a buffer size in advance and you have to call it in a loop because it may return less than the buffer size on a whim. The functions from stdio.h (that operate on a FILE* rather than a file descriptor) are easier to use but still require work to handle long lines. If you don't care about portability outside Linux, use getline:

    FILE *pipe = fdopen(fd, "r");
    char *line = NULL;
    size_t line_length;
    getline(&line, &line_length, pipe);
    

Then use strchr to locate the :s in the line. (Don't be tempted to use strtok, it's only suitable for whitespace-separated fields that can't be empty.)

Gilles
Yeah, using ':' instead of space as a separator is a much better idea, though the main issue is that your separator character should not appear in your data.
Omnifarious
You could also use `strtok()` to parse out the fields.
caf
@caf: No, `strtok` would treat `::` as a single separator (i.e., you can't have an empty field). This is almost never desirable except when the separators are whitespace.
Gilles
A: 

Since it's 2010, you might want to encode your data in JSON or XML, both of which are readily available as libraries for C and almost any other language.

ammoQ
Whee, lets add megabytes of parsing libraries, complicated interfaces and the inability to easily produce the required data from a shell script in order to move into the future!
Omnifarious
It's not at all difficult to produce JSON data from a shell script. Consuming might be a bit harder, though. BTW, cJSON.o is exactly 40032 bytes on my machine and the interface is not at all complicated.
ammoQ