'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 |