18

I am trying to send an integer with pipe in a POSIX system but write() function is working for sending string or character data. Is there any way to send integer with a pipe?

Regards

Rafe Kettler
  • 75,757
  • 21
  • 156
  • 151
erogol
  • 13,156
  • 33
  • 101
  • 155

4 Answers4

36

The safe way is to use snprintf and strtol.

But if you know both processes were created using the same version of compiler (for example, they're the same executable which forked), you can take advantage of the fact that anything in C can be read or written as an array of char:

int n = something();
write(pipe_w, &n, sizeof(n));

int n;
read(pipe_r, &n, sizeof(n));
aschepler
  • 70,891
  • 9
  • 107
  • 161
  • Every pointer can be casted to a *char. But I'm not sure if the opposite is correct without violating the strict aliasing rules? – Lars Noschinski Mar 08 '11 at 19:14
  • 1
    @cebewee: Not sure exactly what your question is. `(short*)(char*) &n` will violate strict aliasing when dereferenced. But `short first_two_bytes; memcpy(&first_two_bytes, &n, sizeof(first_two_bytes));` does not violate strict aliasing. – aschepler Mar 08 '11 at 19:20
  • 1
    @cebewee - It's not char *, it's void *. And every pointer can be a void *. Though you might still be right. This might violate the strict aliasing rules and the value of `n` in the second case might not change. – Omnifarious Mar 08 '11 at 19:21
  • 1
    Functions like `write` and `read` which deal with the data in a `void*` will typically have to cast the pointer to `char*` or `unsigned char*`. (Insert "or `const` ..." as appropriate.) But `char` and `unsigned char` lvalues are forbidden from strict-aliasing optimizations for this reason. – aschepler Mar 08 '11 at 19:28
  • You are right. I was confusing writing to an int through a char* (which is allowed) with accessing a char through an int* (which violates strict aliasing). – Lars Noschinski Mar 08 '11 at 19:31
  • @aschepler I am a complete beginner, and I have a question. I compiled my code and it says, pipe_w & pipe_r are not declared, I tried using **pipe pipe_r,pipe_w;** but it didn't work. Kindly lemme know, what I am doing wrong here, Thank You :) – Ahsan Mar 17 '17 at 14:18
2

Either send a string containing the ASCII representation of integer e.g., 12345679, or send four bytes containing the binary representation of int, e.g., 0x00, 0xbc, 0x61, 0x4f.

In the first case, you will use a function such as atoi() to get the integer back.

mouviciel
  • 66,855
  • 13
  • 106
  • 140
0

Below one works fine for writing to pipe and reading from pipe as:

stop_daemon =123;
res = write(cli_pipe_fd_wr, &stop_daemon, sizeof(stop_daemon));
....
res = read(pipe_fd_rd, buffer, sizeof(int));
memcpy(&stop_daemon,buffer,sizeof(int));
printf("CLI process read from res:%d status:%d\n", res, stop_daemon);

output:

CLI process read from res:4 status:123
elias
  • 849
  • 13
  • 28
0

Aschelpler's answer is right, but if this is something that can grow later I recommend you use some kind of simple protocol library like Google's Protocol Buffers or just JSON or XML with some basic schema.

alecco
  • 2,914
  • 1
  • 28
  • 37