>
> 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.
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]
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.
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
//---------------------------------------------------------
//#########################################################