Topic
  • No replies
SystemAdmin
SystemAdmin
196 Posts

Pinned topic Getting pathname of executable in C/C++ program on xlC AIX

‏2010-11-03T07:27:59Z |
Hi,

Is there any way to get pathname of executable in C/C++ program on xlC AIX - not via argv[0]?

Something like getexecname() on Solaris.

http://docs.sun.com/app/docs/doc/816-5168/6mbb3hrb1
Updated on 2010-11-09T05:42:09Z at 2010-11-09T05:42:09Z by SystemAdmin
  • SystemAdmin
    SystemAdmin
    196 Posts

    Re: Getting pathname of executable in C/C++ program on xlC AIX

    ‏2010-11-04T17:24:45Z  
    I don't know of any such API, but I do have two suggestions. The first is probably the simplest: using a global variable and setting it yourself. Something like:
    
    
    
    static 
    
    const 
    
    char *_arg0ptr=
    "<empty>"; 
    
    const 
    
    char * myGetExecName() 
    { 
    
    return _arg0ptr;
    }   
    
    int main(
    
    int argc,
    
    char *argv[])
    { _arg0ptr = argv[0]; ...
    


    Another, more expensive way is to read the /proc/<pid>/psinfo file. See the AIX /proc manual page

    
    #include <stdio.h> #include <fcntl.h> #include <sys/procfs.h>   
    
    int main(
    
    int argc,
    
    char *argv[])
    { 
    
    char           fileName[50]; 
    
    int            fileId; struct psinfo  info;   sprintf( fileName, 
    "/proc/%d/psinfo", (unsigned 
    
    int) getpid() );   
    
    if ((fileId = open( fileName, O_RDONLY, 0555 )) < 0) perror( 
    "open psinfo" ); 
    
    if ( read( fileId, & info, sizeof(info) ) < 0 ) perror( 
    "read psinfo" ); close( fileId );   printf(
    "exec name:%s\n",info.pr_fname);   
    
    return 0; 
    }
    
  • SystemAdmin
    SystemAdmin
    196 Posts

    Re: Getting pathname of executable in C/C++ program on xlC AIX

    ‏2010-11-04T17:27:44Z  
    I don't know of any such API, but I do have two suggestions. The first is probably the simplest: using a global variable and setting it yourself. Something like:
    <pre class="jive-pre"> static const char *_arg0ptr= "<empty>"; const char * myGetExecName() { return _arg0ptr; } int main( int argc, char *argv[]) { _arg0ptr = argv[0]; ... </pre>

    Another, more expensive way is to read the /proc/<pid>/psinfo file. See the AIX /proc manual page

    <pre class="jive-pre"> #include <stdio.h> #include <fcntl.h> #include <sys/procfs.h> int main( int argc, char *argv[]) { char fileName[50]; int fileId; struct psinfo info; sprintf( fileName, "/proc/%d/psinfo", (unsigned int) getpid() ); if ((fileId = open( fileName, O_RDONLY, 0555 )) < 0) perror( "open psinfo" ); if ( read( fileId, & info, sizeof(info) ) < 0 ) perror( "read psinfo" ); close( fileId ); printf( "exec name:%s\n",info.pr_fname); return 0; } </pre>
    Note, using the psinfo file will only get your the executable name, not the full absolute name. For that, you'd have to query the PATH environment variable and then for each path, search for the exec name. However, argv[0] isn't guaranteed to have the full path name anyways, so I think you would have to do that if you always want the full path name.
  • SystemAdmin
    SystemAdmin
    196 Posts

    Re: Getting pathname of executable in C/C++ program on xlC AIX

    ‏2010-11-08T11:23:13Z  
    // ==============================
    // AIX
    //
    // File getexename.cpp
    //
    // Tested on:
    // ...........................
    // AIX 1 6 000497A2D900
    // ...........................
    // IBM XL C/C++ for AIX, V10.1
    // Version: 10.01.0000.0000
    // ===============================

    #include <cassert>

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <sstream>

    #include <unistd.h>
    #include <sys/procfs.h>
    #include <fcntl.h>

    int main(int argc, char** argv)
    {
    struct stat statData;
    struct psinfo psinfoData;

    std::ostringstream oss;

    oss << "/proc/" << getpid() << "/psinfo";
    assert(stat(oss.str().c_str(), &statData) == 0);

    const int fd = open(oss.str().c_str(), O_RDONLY);
    assert (fd >= 0);

    ssize_t readNum = read(fd, &psinfoData, sizeof(psinfoData));
    assert (readNum >= 0);

    close (fd);

    //
    // Thanks to Guy Shattah which detected
    // that psinfoData.pr_argv is not char**, but char***
    char*** pArgv = reinterpret_cast<char***>(psinfoData.pr_argv);

    const std::string exeName (pArgv[0][0]);

    std::cout << "exeName = " << exeName << std::endl;

    return 0;
    }
  • SystemAdmin
    SystemAdmin
    196 Posts

    Re: Getting pathname of executable in C/C++ program on xlC AIX

    ‏2010-11-09T05:42:09Z  
    // ==============================
    // AIX
    //
    // File getexename.cpp
    //
    // Tested on:
    // ...........................
    // AIX 1 6 000497A2D900
    // ...........................
    // IBM XL C/C++ for AIX, V10.1
    // Version: 10.01.0000.0000
    // ===============================

    #include <cassert>

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <sstream>

    #include <unistd.h>
    #include <sys/procfs.h>
    #include <fcntl.h>

    int main(int argc, char** argv)
    {
    struct stat statData;
    struct psinfo psinfoData;

    std::ostringstream oss;

    oss << "/proc/" << getpid() << "/psinfo";
    assert(stat(oss.str().c_str(), &statData) == 0);

    const int fd = open(oss.str().c_str(), O_RDONLY);
    assert (fd >= 0);

    ssize_t readNum = read(fd, &psinfoData, sizeof(psinfoData));
    assert (readNum >= 0);

    close (fd);

    //
    // Thanks to Guy Shattah which detected
    // that psinfoData.pr_argv is not char**, but char***
    char*** pArgv = reinterpret_cast<char***>(psinfoData.pr_argv);

    const std::string exeName (pArgv[0][0]);

    std::cout << "exeName = " << exeName << std::endl;

    return 0;
    }
    Another program

    // ==============================
    // AIX
    //
    // File getexename2.cpp
    //
    // Tested on:
    // ...........................
    // AIX 1 6 000497A2D900
    // ...........................
    // IBM XL C/C++ for AIX, V10.1
    // Version: 10.01.0000.0000
    // ===============================

    #include <cassert>

    #include <iostream>
    #include <string>

    #include <procinfo.h>

    extern "C"
    {
    int getargs(struct procentry64*, int, char*, int);
    }
    int main(int argc, char** argv)
    {

    struct procentry64 processInfo;
    const pid_t thisPid = getpid();
    pid_t retPid = pid_t();

    char argsBuffer1024;
    memset (argsBuffer, 0, sizeof(argsBuffer));

    while (getprocs64(&processInfo, sizeof (processInfo), 0, 0, &retPid, 1) > 0)
    {
    if (static_cast<pid_t>(processInfo.pi_pid) != thisPid)
    {
    continue;
    }

    int retValue = getargs (&processInfo, sizeof(processInfo), &argsBuffer[0], sizeof(argsBuffer));
    assert (retValue == 0);

    break;
    }

    const std::string exeName = argsBuffer;
    assert (exeName.size() < sizeof(argsBuffer));

    std::cout << "exeName = " << exeName << std::endl;

    return 0;
    }