I am trying to run the stockfish engine as a child process in my code. I want to use fork() and execvp() to do this. I temporarily add the location of the stockfish executable to my PATH by running the command
export PATH="~/Apps/stockfish_15_linux_x64_avx2:$PATH"
And I checked to make sure this is added to PATH by running echo $PATH
. I can also run the stockfish executable from any directory during my current terminal session, so this part seems to be working. What I am having trouble with is running stockfish from another executable using execvp.
I have the following code that reproduces the bug.
#include <iostream>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main(void ) {
const char* argv[] = {"stockfish_15_x64_avx2", "d", NULL};
int pid = fork();
if (pid < 0) {
printf("Failed to fork");
}
else if (pid == 0){
execvp(argv[0], (char* const*)argv);
}
sleep( 1 );
printf("Finished executing the parent process \n"
" -- The child won't get here -- you will only see this once. \n");
return 0;
}
the d
command in stockfish displays a diagram of the current position. This would be the start position in this case. But instead of getting this diagram, the output I get is simply
Finished executing the parent process
-- The child won't get here -- you will only see this once.
Finished executing the parent process
-- The child won't get here -- you will only see this once.
What this tells me is that execvp is not actually taking over the child process. When I change the arguments to a more generic command like argv[] = {"ls", "-a", NULL}
then the code works as expected. Any idea what is going on here?
So I was starting to use waitpid to do some error handling, when I had a hunch that the underscores in the executable name were somehow the problem. And sure enough, when I renamed the executable to 'stockfish15' everything works as intended.
The code now looks like this
#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
int main(void ) {
const char* argv[] = {"stockfish15", "d", NULL};
pid_t pid = fork();
if (pid == -1) {
printf("Failed to fork");
}
else if (pid == 0) {
execvp(argv[0], (char* const*) argv);
}
int status;
waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
printf("child terminated normally\n");
}
else {printf("exevp error\n");}
printf("Finished executing the parent process \n"
" -- The child won't get here -- you will only see this once. \n");
return 0;
}
and the output is
Stockfish 15 by the Stockfish developers (see AUTHORS file)
+---+---+---+---+---+---+---+---+
| r | n | b | q | k | b | n | r | 8
+---+---+---+---+---+---+---+---+
| p | p | p | p | p | p | p | p | 7
+---+---+---+---+---+---+---+---+
| | | | | | | | | 6
+---+---+---+---+---+---+---+---+
| | | | | | | | | 5
+---+---+---+---+---+---+---+---+
| | | | | | | | | 4
+---+---+---+---+---+---+---+---+
| | | | | | | | | 3
+---+---+---+---+---+---+---+---+
| P | P | P | P | P | P | P | P | 2
+---+---+---+---+---+---+---+---+
| R | N | B | Q | K | B | N | R | 1
+---+---+---+---+---+---+---+---+
a b c d e f g h
Fen: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
Key: 8F8F01D4562F59FB
Checkers:
child terminated normally
Finished executing the parent process
-- The child won't get here -- you will only see this once.
Still, I'd like to know the explanation for why this is happening.