Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

4 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