5

I would like to know if it is possible that an utility yields binary data (i.e. graphical images) and outputs them through IO console, while another application, instructed about the nature of those data and informed of the number of the incoming bytes, is able to read it from IO console.

P5music
  • 3,197
  • 2
  • 32
  • 81

5 Answers5

3

Yes, it is possible. While it's true that often stdin/stdout are meant to be text there are many programs that are designed to get binary input or write binary output from standard I/O channels.

The only thing you should pay attention is that normally stdout/stdin are opened in text mode under Windows, so you should switch them to binary mode to avoid character translation.

To set binary mode on stdin/stdout on Windows you need to use the _setmode call:

#include <stdio.h>
#include <fcntl.h>
#include <io.h>

int main( void )
{
   int result;

   // Set "stdin" to have binary mode:
   result = _setmode( _fileno( stdin ), _O_BINARY );
   if( result == -1 )
      perror( "Cannot set mode" );
   else
      printf( "'stdin' successfully changed to binary mode\n" );
}

Note also to pay attention to file buffering. Often programs will flush the buffer on newlines ONLY when the output is to an interactive console and not when it's another process. So if you need synchronizaton remember to call fflush after writing a message because otherwise the other process will not be able to get the data.

6502
  • 112,025
  • 15
  • 165
  • 265
  • Why are some people here talking about Base64 encoding? Is Dervall right I do not need it if the data are not displayed? (Data in fact are not) – P5music Mar 04 '12 at 11:13
  • @P5music: ask them. Like I said there are many programs that can pipe in or out binary data (e.g. you can use `ffmpeg` to decode a movie and write the output as raw YUV frames so that another program can process the video or in Linux if you want to do a raw data zipped backup of a disk unit you can just use `dd -if=/dev/whatever | gz > backup.dd.gz` and it works perfectly). On windows there is this annoying thing of text/binary mode, but it can be solved. Of course throwing binary data at a terminal is going to be horrible, but if output is to another process then everything is ok... – 6502 Mar 04 '12 at 11:24
  • Please could you tell me the printf instruction to send the data (I know the number of bytes and the pointer) to the console from the C application? – P5music Mar 05 '12 at 18:15
  • @P5music: just use `fwrite(pointer, 1, number_of_bytes, stdout);` and follow that with `fflush(stdout);` to ensure that the receiving process will be able to access all data. – 6502 Mar 05 '12 at 18:20
  • thank you! Excuse me, if you know also C# could you take a look to my other question here ? http://stackoverflow.com/questions/9566211/pass-binary-data-from-c-to-c-sharp-through-the-console – P5music Mar 05 '12 at 18:42
0

You can use traditional socket or lighter named pipe for this kind of thing.

Coren
  • 5,517
  • 1
  • 21
  • 34
0

You could Base 64-Encode/Decode the data. This will avoid the need to send pure "bits" over the standard input/output stream.

Moo-Juice
  • 38,257
  • 10
  • 78
  • 128
0

If the process is to be hosted within another process that will capture your stdout from the process that writes binary data then there is no need to encode it. In that case you can write the raw binary data to the output and be done with it. This is for example how the image writing dot tool from graphviz works, it doesn't encode it's input by default. These kinds of tools are also pretty easy to pipe to a file by the use of > in the command shell.

Only if the output from the data is going to be seen on the console are you going to need to encode it. It's not a very good idea to print the contents of say an image file.

Dervall
  • 5,736
  • 3
  • 25
  • 48
  • Could I go through security issues with this method you describe? – P5music Mar 04 '12 at 11:08
  • I'm not the worlds best security guy, but in my mind writing to stdout is pretty much the same regardless of what you actually write. As long as you don't print this to the actual console. Not that much will happen if you do, it will just print a bunch of funky characters and the speaker sometimes beeps a lot due to the bell character. If the stdout never reaches the actual printed console amd instead is captured by another process then it's just a binary stream like any other with the same security characteristics as say an open file stream. – Dervall Mar 04 '12 at 11:14
-1

You can do it if you choose an appropriate encoding, as the console is a text stream. Use for example Base64 encoding for your binary data and it will work fine. Another alternative is the "Quoted-printable" format. You end up of course with more bytes than the original binary data, but IMHO the only way to do it safely using the console.

jdehaan
  • 19,700
  • 6
  • 57
  • 97