Sadly there is no way to get the full path of the executed file in OpenBSD.
The first argument by convention points to the file name, not to the full path, and you can't be sure the parent process will follow that convention.
The following command, called exe, illustrates this.
#include <stdio.h>
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
#include <sys/wait.h>
int exe( const char * path, const char * fakepath )
{
pid_t pid = vfork( ) ;
if( pid == 0 )
{
/* Child process */
int fd ;
const int TO = getdtablesize( ) ;
for( fd = 0 ; fd <= TO ; fd++ )
{
close( fd );
}
open( "/dev/tty", O_RDONLY ) ;
open( "/dev/tty", O_WRONLY ) ;
open( "/dev/tty", O_WRONLY ) ;
const char *arguments[2] = { fakepath, NULL } ;
execvp( path, (char**)arguments ) ;
perror( "exe" ) ;
exit( 1 ) ;
}
else if( pid > 0 )
{
/* Parent process */
int status = 0 ;
if( waitpid( pid, &status, 0 ) != -1 )
{
if( WIFEXITED( status ) )
{
return WEXITSTATUS( status ) ;
}
else
{
printf( "exe: child process failed\n" ) ;
return 1 ;
}
}
}
perror( "exe" ) ;
return 1 ;
}
int main( int argc, char * argv[] )
{
if( argc != 3 )
{
printf( "Usage: exe program /fake/first/program/argument\n" ) ;
return 1 ;
}
return exe( argv[1], argv[2] ) ;
}
Now you can execute a program passing an arbitraty first argument, like this:
exe program /fake/first/program/argument
An user asked Theo de Raadt to implement what is necessary to be able to get the full path of the executed file in this thread
I guess we could stick 'path' into an auxiliary vector value and have
ld.so do the realpath() call if $ORIGIN is used? It would be that or
have the kernel store the whole path for the life of the process for
obtaining with sysctl(). Right now it only stores the last component
of the (resolved) original path in p_comm.
And he replied:
Quite expensive, for such a small need.