FreeBSD execle system call works wrong in code written for Linux. In many Linux sources i see next system call notation like execle("/sbin/shutdown", "shutdown", "-h", shutdown_flag, "+0", "hypervisor initiated shutdown", (char*)NULL, environ); Where second argument used as short "program name". In FreeBSD systems, this argument is not bypassed in call and attached to args list. As a result, when the source is ported to FreeBSD, the system call is not executed correctly. ---- truss output start ---- 946: execve("/sbin/shutdown",[ "shutdown", "-h", "-r", "+0", "hypervisor initiated shutdown" ],0x7fffffffeac0) = 0 (0x0) 946: geteuid() = 0 (0x0) 946: write(2,"shutdown: ",10) = 10 (0xa) 946: write(2,"incompatible switches -c, -h, -k"...,43) = 43 (0x2b) ---- truss output end ---- If we change system call to execle("/sbin/shutdown", "-h", shutdown_flag, "+0", "hypervisor initiated shutdown", (char*)NULL, environ); all is ok. But, may be this an error in args parsing in FreeBSD "shutdown" ?
From the man page, int execle(const char *path, const char *arg, ..., NULL, char *const envp[]); A simple example like execle("/bin/echo", "echo", "test", NULL, environ); works as expected (echoes test).
The issue is that you are specifying both -h and -r which are incompatible in the first example. In the second example, argv[0] is being set to -h and is not being parsed as an argument, allowing -r to work.