Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a file descriptor backed by a simple char array?

I have a function that receives a descriptor (you know, one of those things that open() and socket() spit), reads from it and does something with the data:

int do_something(int fd);

I want to test this function. Preferably, the input data should sit right next to the test assert for the sake of easy debugging. (Therefore, actual file reading should be avoided.) In my mind, the ideal would be something like

unsigned char test_input[] = { 1, 2, 3 };
int fd = char_array_to_fd(test_input);
ck_assert(do_something(fd) == 1234);

(ck_assert is from the Check framework. It's just a typical unit test assert.)

Is there a way to implement char_array_to_fd()? I don't mind if I need to NULL-terminate the array or send the length in.

I imagine that I can open a socket to myself and write on one end so the test function receives the data on the other end. I just don't want to write something awkward and find out that Unix had something less contrived all along. The solution should be any-Unix friendly.

(Basically, I'm asking for a C equivalent of ByteArrayInputStream.)

Alternatively: Should I be thinking in some other way to solve this problem?

like image 473
nkhail hna Avatar asked Sep 02 '25 03:09

nkhail hna


2 Answers

On Linux, you can use memfd_create() to create a memory-backed temporary file:

unsigned char test_input[] = ...;

int fd = memfd_create( "test_input", 0 );

// write test data to the the "file"
write( fd, test_input, sizeof( test_input );

// reset file descriptor to the start of the "file"
lseek( fd, 0, SEEK_SET );

Note that completely lacks error checking.

like image 169
Andrew Henle Avatar answered Sep 05 '25 00:09

Andrew Henle


You can use mkstemp to make a temporary file and write to it or read from it:

int fd = mkstemp("tempXXXXXX");

If you want something more dynamic, you can use socketpair to create a pair of connected sockets.

int pair[2];
socketpair(AF_UNIX, SOCK_STREAM, 0, pair);

You can then fork process or thread to interact with your program under test.

like image 22
Chris Dodd Avatar answered Sep 05 '25 02:09

Chris Dodd