'Linux script executing from C++ code with execv fails

I've a very basic Linux script (/home/scripts/script.sh):

#!/bin/bash
echo 'a' | /bin/netcat -vv 10.10.10.1 3333
echo "done" > /tmp/result

When I try to run it from the shell, it works fine. So script is good (also, done is written into /tmp/result file):

# /home/scripts/script.sh
10.10.10.1: inverse host lookup failed: Unknown host
(UNKNOWN) [10.10.10.1] 3333 (?) open
AABBCCDDEEF
 sent 2, rcvd 13
#

However when I'm trying to run it from C++ code in a foreground daemon:

const char **argv = new const char* [3];
argv[0] = "/home/scripts/script.sh";
argv[1] = "/home/scripts/script.sh";
argv[2] = NULL;
execv(argv[0], const_cast<char**>(&argv[1]));

For a short time it works good (for 3-5mins). After that short period the script running fails, nc's return code is 1, and this is the output:

10.10.10.1: inverse host lookup failed: Unknown host
(UNKNOWN) [10.10.10.1] 3333 (?) open
Preposterous fd value 17
 sent 0, rcvd 0

Why is that fd value is preposterous? My daemon opens some files during the first 3-5 min, maybe netcat is not able to deal with larger numbers as fd?

How shall I overcome on this issue?



Solution 1:[1]

This problem was caused by netcat.

First I did not realized the importance of this message:

Preposterous fd value 17

This is actually a very important error message of netcat because it was not designed to work with higher fds than 16 by default which is totally acceptable for a simple scripting.

However in multi-threaded environments when netcat gets called, there can be more than 16 fds already used.

This is message from 2007 which updates 16 to 1024 as a bugfix.

Netcat's official webpage is https://nc110.sourceforge.io, and the current version is 1.10, which still defines FD_SETSIZE as 16.

The solution was to grab the code, patch it and build it.

Solution 2:[2]

Just a quick answer: In debian I solved this problem installing netcat-openbsd. The default netcat refers to netcat-traditional which still has this bug.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Daniel
Solution 2 Davide Cervella