Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!ames!decwrl!sdd.hp.com!uakari.primate.wisc.edu!zaphod.mps.ohio-state.edu!tut.cis.ohio-state.edu!att!dptg!mtune!jrw From: jrw@mtune.ATT.COM (Jim Webb) Newsgroups: comp.unix.questions Subject: Re: Get process name w/o using argv[0] in C function? Summary: put pride aside and use a global Message-ID: <707@mtune.ATT.COM> Date: 2 Aug 90 15:08:32 GMT References: <9220003@hpldsla.sid.hp.com> Organization: AT&T BL Middletown/Lincroft NJ USA Lines: 86 In article <9220003@hpldsla.sid.hp.com>, manoj@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!"