Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss
Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Getting the executable's name without using argv[0]

7 views
Skip to first unread message

Alex Vinokur

unread,
Oct 18, 1999, 3:00:00 AM10/18/99
to
Jon Cook <co...@cs.man.ac.uk> wrote
29 Apr 1999
comp.lang.c
Subject: Getting the executable's name without using argv[0]

>
> Is there any way you can get the executable's name without using
> argv[0]?.
>
> Cheers,
> Jon

SunOS 5.6 : getexecname ()

Alex


Sent via Deja.com http://www.deja.com/
Before you buy.

Alex Vinokur

unread,
Oct 18, 1999, 3:00:00 AM10/18/99
to
In article <7uegto$23r$1...@nnrp1.deja.com>,

Alex Vinokur <alexande...@telrad.co.il> wrote:
> Jon Cook <co...@cs.man.ac.uk> wrote
> 29 Apr 1999
> comp.lang.c
> Subject: Getting the executable's name without using argv[0]
>
> >
> > Is there any way you can get the executable's name without using
> > argv[0]?.
> >
> > Cheers,
> > Jon
>
> SunOS 5.6 : getexecname ()

P.S. To get the same result in SunOS 5.5.x
we need to use
- the prpsinfo_t structure,
- proc tools (see man proc(1))
- the ioctl system call

[snip]

Nick Keighley

unread,
Oct 18, 1999, 3:00:00 AM10/18/99
to
In article <7ueno8$79b$1...@nnrp1.deja.com>,

Alex Vinokur <alexande...@telrad.co.il> wrote:
> In article <7uegto$23r$1...@nnrp1.deja.com>,
> Alex Vinokur <alexande...@telrad.co.il> wrote:
> > Jon Cook <co...@cs.man.ac.uk> wrote
> > 29 Apr 1999
> > comp.lang.c
> > Subject: Getting the executable's name without using argv[0]
> >
> > >
> > > Is there any way you can get the executable's name without using
> > > argv[0]?.
> > >
> >
> > SunOS 5.6 : getexecname ()
>
> P.S. To get the same result in SunOS 5.5.x
> we need to use
> - the prpsinfo_t structure,
> - proc tools (see man proc(1))
> - the ioctl system call
>

yes but this is all platform specific magic. This can't be done in
standard C. Even argv[0] can't be relied upon.

--

It isn't a program, it's a 1000 patches flying in
loose formation.

Alex Vinokur

unread,
Oct 20, 1999, 3:00:00 AM10/20/99
to
In article <380B3AB7...@iedu.org>,
Morris Dovey <mrd...@iedu.org> wrote:
> Morris Dovey wrote:
> >
> >
> > Linux: Don't forget to check for errors!

I think checking errors take 80-90% of code, run-time etc.

> >
> > #include <stdio.h>
> > #include <sys/types.h>
> #include <unistd.h>
> >
> > FILE *fp;
> > pid_t pid = getpid();
> > char command[256];
> >
> > sprintf(command,"/proc/%u/cmdline",pid);
> > fp = fopen(command,"r");
> > fgets(command,sizeof(command),fp);
> > fclose(fp);
> > /* Extract what you want from command */
> >
> Oops! Don't forget to include: unistd.h
>
> Morris Dovey
> West Des Moines, Iowa USA
> mailto:mrd...@iedu.org
>

Hi,

===== SunOS 5.5.x, Sun 5.6 ====
Three functions returning information
concerning executable file name have been written:
- get_base_exec_name
- get_argv0_exec_name
- get_all_exec_argvs

The functions are using :


- the prpsinfo_t structure,
- proc tools (see man proc(1))
- the ioctl system call


Alex
==============================

Table#1 : Comparative behavior function
returning exec file name
==================================================
| Function Name | Full | Out | All | Symb |
| | Name | Size | Args | Link |
|=================================================
|getexecname |Table2| Long | No | No | C Library, SunOS 5.6
|------------------------------------------------|
|get_base_exec_name | No | 15 | No | No |
|------------------------------------------------|
|get_argv0_exec_name | No | 79 | No | Yes |
|------------------------------------------------|
|get_all_exec_argvs | Yes | 79 | Yes | Yes |
==================================================


Table#2 : Specific behavior of getexecname ()
[ C Library, SunOS 5.6 ]
a.out - name of original exec file
s.out - softlink to a.out
===============================
| Called | Out |
| Exec File Name | |
|=============================|
| a.out | a.out |
|-----------------------------|
| ./a.out | a.out | Missing "./"
|-----------------------------|
| /tmp/a.out | /tmp/a.out |
|-----------------------------|
| s.out | a.out | Original name
|-----------------------------|
| ./s.out | a.out | Original name; Missing "./"
|-----------------------------|
| /tmp/s.out | /tmp/a.out | Original name
===============================

//#########################################################
//------------------- C++ code : BEGIN -------------------
//==========================
#include <limits.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/procfs.h>

//==========================
#include <iostream>
#include <strstream>
#include <string>

//#################################################################
//################## DEFINES ######################################
//#################################################################
//----------------------------
#define COUT_LOCATION \
" ### See : " \
<< __FILE__ \
<< ", line#" \
<< __LINE__ \
<< ", in FUNCTION -> " \
<< __PRETTY_FUNCTION__ \
<< " ###"


//----------------------------
#define WARNING_MESSAGE(x) \
cout << "\tWARNING!!! " x \
<< COUT_LOCATION \
<< endl

//----------------------------
#define ERROR_MESSAGE(x) \
cout << "\n\tERROR!!! " x \
<< COUT_LOCATION \
<< endl


//#################################################################
//################## FUNCTIONS DECLARATION ########################
//#################################################################
//==========================================
//= SERVICE FUNCTIONS

bool non_empty_string_is_dec (string line_i);
bool is_dec_string (const string& line_i);

string int_to_dec_string (
int value_i,
int width_i = -1,
char fill_i = '0'
);


int get_total_words (
const string& stringLine_i,
const string& delimiters_i = " \t\n"
);

string get_i_th_Word (
const string& stringLine_i,
int wordNo_i,
const string& delimiters_i = " \t\n"
); // Master Word is Word#1

string get_first_word (
const string& stringLine_i,
const string& delimiters_i = " \t\n"
);

bool get_prpsinfo_t (
string& ret_msg_o,
prpsinfo_t& retval_prpsinfo_t_o,
string& pid_string_o,
int pid_i = getpid ()
);

bool get_base_exec_name (string& exec_name_o, int pid_i);

//==========================================
//= USER FUNCTIONS
string get_base_exec_name (int pid_i = getpid ());

string get_argv0_exec_name (int pid_i = getpid ());

string get_all_exec_argvs (int pid_i = getpid ());

//#################################################################
//################## MAIN PROGRAM #################################
//#################################################################
int main ()
{

//==============================
cout << endl;
cout << "\t: "
<< "const char* getexecname(void) [C Library, SunOS 5.6] :"
<< endl;
cout << getexecname () << endl;
//==============================

//==============================
cout << endl;
cout << get_base_exec_name () << endl;

cout << endl;
cout << get_argv0_exec_name () << endl;

cout << endl;
cout << get_all_exec_argvs () << endl;
//==============================

return 0;
}


//#################################################################
//################## FUNCTIONS DEFINITION #########################
//#################################################################

//##################################################
string int_to_dec_string (int value_i, int width_i, char fill_i)
{
string ret_stringValue;
strstream tmp_strstream;

//=================================
assert (value_i >= INT_MIN); // from <limits.h>
assert (value_i <= INT_MAX); // from <limits.h>
//=================================
if (width_i > 0)
{
tmp_strstream.width (width_i);
tmp_strstream.fill (fill_i);
}
tmp_strstream << dec << value_i;

//=================================
tmp_strstream << ends;
ret_stringValue = tmp_strstream.str();
tmp_strstream.rdbuf()->freeze (0);
//=================================
if (width_i <= 0)
{
assert (is_dec_string (ret_stringValue));
}
//=================================
return ret_stringValue;
} // string int_to_dec_string (int value_i)

//##################################################
int get_total_words (
const string& parsed_line_i,
const string& delimiters_i
)
{
string str_tail = parsed_line_i;
unsigned int found_index;
string current_word_string;
int words_counter = 0;


//=======================================================
//=======================================================
while (!str_tail.empty ())
{
//###########################
//###########################
found_index = str_tail.find_first_of (delimiters_i);

//=============================================
//=============================================
if (found_index == 0)
{
str_tail = str_tail.substr (found_index + 1);
continue;
}

//===============================================
//===============================================
words_counter++;
//==============================

//###########################
//###########################
current_word_string = "";
if (found_index == string::npos)
{
current_word_string = str_tail;
str_tail = "";
} // if (found_index == string::npos)
else
{
current_word_string = str_tail.substr (0,
found_index);
str_tail = str_tail.substr (found_index + 1);
}

} // while (!str_tail.empty ())

//=======================
return words_counter;
} // int get_total_words

//##################################################
string get_i_th_Word (
const string& parsed_line_i,
int wordNo_i,
const string& delimiters_i
)
{
string str_tail = parsed_line_i;
unsigned int found_index;
string current_word_string;
int words_counter = 0;
string ret_stringValue;


assert (wordNo_i >= 1);
assert (wordNo_i <= get_total_words (parsed_line_i,
delimiters_i));

//=======================================================
//=======================================================
while (!str_tail.empty ())
{
//###########################
//###########################
found_index = str_tail.find_first_of (delimiters_i);

//=============================================
//=============================================
if (found_index == 0)
{
str_tail = str_tail.substr (found_index + 1);
continue;
}

//===============================================
//===============================================
words_counter++;

//###########################
//###########################
current_word_string = "";
if (found_index == string::npos)
{
current_word_string = str_tail;
str_tail = "";
} // if (found_index == string::npos)
else
{
current_word_string = str_tail.substr (0,
found_index);
str_tail = str_tail.substr (found_index + 1);
}

// ################################
if (words_counter == wordNo_i)
{
ret_stringValue = current_word_string;
break;
}
//==============================
} // while (!str_tail.empty ())

//=======================
assert (!ret_stringValue.empty ());
return ret_stringValue;
} // string get_i_th_Word

//#########################################################
string get_first_word (
const string& stringLine_i,
const string& delimiters_i
)
{
return get_i_th_Word (stringLine_i, 1 /* Word#1 */,
delimiters_i);

} // string get_first_word (...)

//#########################################################
bool is_dec_string (const string& line_i)
{
return ((line_i.empty ()) ? false : non_empty_string_is_dec
(line_i));
} // bool is_dec_string (...)


//#########################################################
bool non_empty_string_is_dec (string line_i)
{
//====================
if (line_i.empty ())
{
return true; // i.e. there aren't non-digits
}

//====================
if (line_i[0] == '-')
{
line_i = line_i.substr (1);
}

//====================
return ((isdigit (line_i[0]) == 0) ? false :
non_empty_string_is_dec (line_i.substr (1)));
} // bool non_empty_string_is_dec (...)


//###################################
bool get_prpsinfo_t (
string& ret_msg_o,
prpsinfo_t& retval_prpsinfo_t_o,
string& pid_string_o,
int pid_i
)
{
bool ret_boolValue = true;
string lwpName = "/proc/" + int_to_dec_string (pid_i);
int fd = open (lwpName.c_str (), O_RDONLY);

//==============================
ret_msg_o = string ();
pid_string_o = "processID-" + int_to_dec_string (pid_i);
//==============================
if (fd == -1)
{
ret_boolValue = false;
//------------------------
ret_msg_o = "Cannot open lwpFileName of this process -
<"
+ lwpName
+ "> : "
+ strerror (errno);
//------------------------
return ret_boolValue;
}

//==============================
if (ioctl (fd, PIOCPSINFO, &retval_prpsinfo_t_o) < 0)
{
ret_boolValue = false;
//------------------------
ret_msg_o = "Cannot execute ioctl function for lwpFile -
<"
+ lwpName
+ "> : "
+ strerror (errno);
//------------------------
return ret_boolValue;
}

//==============================
switch (close (fd))
{
case 0 :
// Success
break;

case -1 :
ret_boolValue = false;
//------------------------
ret_msg_o = "Cannot close lwpFileName of this
process - <"
+ lwpName
+ "> : "
+ strerror (errno);
//------------------------
break;

default :
assert (0);
} // switch (close (fd))

//==========================
return ret_boolValue;
//##############################3

} // prpsinfo_t get_prpsinfo_t (


//###################################
bool get_base_exec_name (string& exec_name_o, int pid_i)
{
prpsinfo_t this_prpsinfo_t;
string pid_string;
string ret_msg;
bool ret_boolValue = get_prpsinfo_t (ret_msg,
this_prpsinfo_t, pid_string, pid_i);

//=========================
if (ret_boolValue)
{
exec_name_o = this_prpsinfo_t.pr_fname;
}
else
{
exec_name_o = "CannotGetExecNameOf" + pid_string;
ERROR_MESSAGE (<< ret_msg);
}
//=========================
return ret_boolValue;

} // bool get_base_exec_name


//###################################
string get_base_exec_name (int pid_i)
{
cout << "\t: " << __PRETTY_FUNCTION__ << " :" << endl;
//======================
string ret_stringValue;
bool result = get_base_exec_name (ret_stringValue, pid_i);
assert (result);
//======================
return ret_stringValue;
} // bool get_base_exec_name


//###################################
bool get_argv0_exec_name (string& exec_name_o, int pid_i)
{
prpsinfo_t this_prpsinfo_t;
string pid_string;
string ret_msg;
string all_args;
bool ret_boolValue = get_prpsinfo_t (ret_msg,
this_prpsinfo_t, pid_string, pid_i);

//=========================
if (ret_boolValue)
{
all_args = this_prpsinfo_t.pr_psargs;
exec_name_o = get_first_word (all_args);
exec_name_o = exec_name_o.substr (exec_name_o.rfind
('/') + 1);
if (all_args.size () >= (PRARGSZ - 1))
{
WARNING_MESSAGE (<< "Output Line Limited by
PRARGSZ = "
<< PRARGSZ
);
exec_name_o = exec_name_o +
"___...too_long_exec_file_name...";
}
}
else
{
exec_name_o = pid_string;
ERROR_MESSAGE (<< ret_msg);
}
//=========================
return ret_boolValue;

} // bool get_argv0_exec_name


//###################################
string get_argv0_exec_name (int pid_i)
{
cout << "\t: " << __PRETTY_FUNCTION__ << " :" << endl;
//======================
string ret_stringValue;
bool result = get_argv0_exec_name (ret_stringValue, pid_i);
assert (result);
//======================
return ret_stringValue;
} // bool get_argv0_exec_name


//###################################
bool get_all_exec_argvs (string& all_exec_argvs_o, int pid_i)
{
prpsinfo_t this_prpsinfo_t;
string pid_string;
string ret_msg;
bool ret_boolValue = get_prpsinfo_t (ret_msg,
this_prpsinfo_t, pid_string, pid_i);

//=========================
if (ret_boolValue)
{
all_exec_argvs_o = this_prpsinfo_t.pr_psargs;
if (all_exec_argvs_o.size () >= (PRARGSZ - 1))
{
WARNING_MESSAGE (<< "Output Line Limited by
PRARGSZ = "
<< PRARGSZ
);
all_exec_argvs_o = all_exec_argvs_o +
"___...too_long_command_line...";
}
}
else
{
all_exec_argvs_o = "CannotGetCommandLine_of_" +
pid_string;
ERROR_MESSAGE (<< ret_msg);
}
//=========================
return ret_boolValue;

} // bool get_all_exec_argvs


//###################################
string get_all_exec_argvs (int pid_i)
{
cout << "\t: " << __PRETTY_FUNCTION__ << " :" << endl;
//======================
string ret_stringValue;
bool result = get_all_exec_argvs (ret_stringValue, pid_i);
assert (result);
//======================
return ret_stringValue;
} // bool get_all_exec_argvs


//------------------- C++ code : END ----------------------

//#########################################################
//------------------- Running Results : BEGIN -------------

% cd /tmp % ln -s a.out s.out % cp a.out
l123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456
789h123456789j123456789

//====================================
% ./a.out xxx yyy zzz

: const char* getexecname(void) [C Library, SunOS 5.6] :
a.out

: class string get_base_exec_name(int = getpid()()) :
a.out

: class string get_argv0_exec_name(int = getpid()()) :
a.out

: class string get_all_exec_argvs(int = getpid()()) :
./a.out xxx yyy zzz


//====================================
% ./s.out xxx yyy zzz

: const char* getexecname(void) [C Library, SunOS 5.6] :
a.out

: class string get_base_exec_name(int = getpid()()) :
a.out

: class string get_argv0_exec_name(int = getpid()()) :
s.out

: class string get_all_exec_argvs(int = getpid()()) :
./s.out xxx yyy zzz

//==================================== %
./l123456789a123456789b123456789c123456789d123456789e123456789f123456789g1234
56789h123456789j123456789 xxx yyy zzz

: const char* getexecname(void) [C Library, SunOS 5.6] :
l123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456
789h123456789j123456789

: class string get_base_exec_name(int = getpid()()) :
l123456789a1234

: class string get_argv0_exec_name(int = getpid()()) : WARNING!!! Output
Line Limited by PRARGSZ = 80 ### See : this_execname.C, line#444, in
FUNCTION -> bool get_argv0_exec_name(class string &, int) ###
l123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456
___...too_long_exec_file_name...

: class string get_all_exec_argvs(int = getpid()()) : WARNING!!! Output
Line Limited by PRARGSZ = 80 ### See : this_execname.C, line#488, in
FUNCTION -> bool get_all_exec_argvs(class string &, int) ###
./l123456789a123456789b123456789c123456789d123456789e123456789f123456789g1234
56___...too_long_command_line...

//====================================
% /tmp/a.out xxx yyy zzz

: const char* getexecname(void) [C Library, SunOS 5.6] :
/tmp/a.out

: class string get_base_exec_name(int = getpid()()) :
a.out

: class string get_argv0_exec_name(int = getpid()()) :
a.out

: class string get_all_exec_argvs(int = getpid()()) :
/tmp/a.out xxx yyy zzz

//====================================
% /tmp/s.out xxx yyy zzz

: const char* getexecname(void) [C Library, SunOS 5.6] :
/tmp/a.out

: class string get_base_exec_name(int = getpid()()) :
a.out

: class string get_argv0_exec_name(int = getpid()()) :
s.out

: class string get_all_exec_argvs(int = getpid()()) :
/tmp/s.out xxx yyy zzz

//==================================== %
/tmp/l123456789a123456789b123456789c123456789d123456789e123456789f123456789g1
23456789h123456789j123456789 xxx yyy zzz

: const char* getexecname(void) [C Library, SunOS 5.6] :
/tmp/l123456789a123456789b123456789c123456789d123456789e123456789f123456789g1
23456789h123456789j123456789

: class string get_base_exec_name(int = getpid()()) :
l123456789a1234

: class string get_argv0_exec_name(int = getpid()()) : WARNING!!! Output
Line Limited by PRARGSZ = 80 ### See : this_execname.C, line#444, in
FUNCTION -> bool get_argv0_exec_name(class string &, int) ###
l123456789a123456789b123456789c123456789d123456789e123456789f123456789g123___
...too_long_exec_file_name...

: class string get_all_exec_argvs(int = getpid()()) : WARNING!!! Output
Line Limited by PRARGSZ = 80 ### See : this_execname.C, line#488, in
FUNCTION -> bool get_all_exec_argvs(class string &, int) ###
/tmp/l123456789a123456789b123456789c123456789d123456789e123456789f123456789g1
23___...too_long_command_line...

//------------------- Running Results : END ---------------

//#########################################################
//------------------- Environment -------------------------

g++ -v : gcc version egcs-2.91.57 19980901
(egcs-1.1 release)

uname -sr : SunOS 5.6

//---------------------------------------------------------

//#########################################################

0 new messages