Get process name w/o using argv[0] in C function?

Jim Webb jrw at mtune.ATT.COM
Fri Aug 3 01:08:32 AEST 1990


In article <9220003 at hpldsla.sid.hp.com>, manoj at hpldsla.sid.hp.com (Manoj Joshi) writes:
> Is there a way to get the name of a process anywhere inside the source?
> By name, I mean argv[0]. As an alternative, I can pass argv[0] as an
> extra parameter from main() to every function in the program, but I 
> think it is inefficient. Also, I do not think I want to use a global
> and initialize it to argv[0] in body of main(), because I do not use
> globals!

What's wrong with using a global?  You'd be amazed what the routine that
puts together main(argc,argv) in the first place does if the use of a
global frightens you :-)

> I know that getpid() and getppid() get me the process id and parent's
> process id. From this I can scan thru the proc table in proc.h, and
> get the process name as a string. But this may be non-portable C.

In System V at least, the name of the process is not stored in the process
table, but rather in the process's user block.  Finding the user block can
be quite machine specific.

If you _really really really_ don't want to use a global, you have two
options, in order of diminishing appeal:

1) run the ps command inside a pipe and read the result:

	char psbuf[64];
	char command[15];
	FILE *ps;
	
	/* I'm sure this could be done better in perl :-) */
	sprintf(psbuf,"ps -p%d|awk '{/PID/ {next} { print $4 }'",getpid());
	ps=popen(psbuf,"r");
	fgets(command,15,ps);
	pclose(ps);
	command[strlen(command)-1]=NULL; /* chop off the \n */


2) do what the ps command does yourself:

get your process id via getpid().

#ifdef i386:

run the sysi86(RDUBLK) system call to get the user block for your
process and use u.u_comm.

#ifdef u3b2:

run the sys3b(RDUBLK) system call to get the user block for your process
and use u.u_comm.

#ifdef anyotherSysVbox:

do a name search on /unix and get the addresses of the process (_proc) and
variable (_v) tables, or, checking the dates of /unix and /etc/ps_data and
using the addresses in the latter if it exists and is newer than /unix
(gain wizard points if you use this approach, which is mucho faster than
running nlist)

open /dev/kmem and seek to _v and get the size of the process table from
v.v_proc (gain some wizard points if you use v.ve_proc later on)

seek to _proc and then read thru this structure v.v_proc times (or until
you reach v.ve_proc) comparing proc.p_pid with your process id.  if you
don't find it, well, them's the breaks :-)

when found, figure out how to find the user block for this process.  hints
are to look thru the process's page table to find where it thinks the ublock
is (it is _virtually_ the same for each process).

seek to that location and read in the ublock and use u.u_comm.

obviously, this all must be done as a user that has read permissions
on /dev/kmem.....normally group sys will suffice.

-----

Note that these solutions are really wastes of time (especially after
you throw in error checking) since the information desired is already
available in the process.

Later,

-- 
Jim Webb                "Out of Phase -- Get Help"               att!mtune!jrw
                  "I'm bored with this....Let's Dance!"



More information about the Comp.unix.questions mailing list