[comp.unix.internals] How to know your current shell from C code

mikel@cadence.cadence.com (09/11/90)

        Recently I had a UNIX question.  I have a c program and
I want to know which shell(sh,csh,ksh) is my parent.  Is there
any way to do this?  Environment variable is not acceptable.

josef@nixpbe.UUCP (Moellers) (09/12/90)

In <1990Sep11.164436.9592@cadence.com> mikel@cadence.cadence.com writes:


>        Recently I had a UNIX question.  I have a c program and
>I want to know which shell(sh,csh,ksh) is my parent.  Is there
>any way to do this?  Environment variable is not acceptable.

Quick'n'dirty:

	# include	<stdio.h>
	...
	FILE *ps;
	char line[80], *shell;
	int ppid, pspid;
	...
	ppid = getppid()
	ps = popen("ps", "r");
	fgets(line, 80, ps);	/* skip "PID TTY TIME COMMAND" */
	shell = (char *) 0;
	while (fgets(line, 80, ps) != NULL)
	{
		pspid = atoi(line);
		if (pspid == ppid)
		{
			shell = line+22;
			break;
		}
	}
	shell[strlen(shell)-1] = '\0';
	if (shell == (char *) 0)
		printf("Huh??");
	else
		printf("Your friendly neighbourhood shell is \"%s\"\n", shell);

--
| Josef Moellers		|	c/o Nixdorf Computer AG	|
|  USA: mollers.pad@nixbur.uucp	|	Abt. PXD-S14		|
| !USA: mollers.pad@nixpbe.uucp	|	Heinz-Nixdorf-Ring	|
| Phone: (+49) 5251 104662	|	D-4790 Paderborn	|

Chuck.Phillips@FtCollins.NCR.COM (Chuck.Phillips) (09/13/90)

>>>>> On 11 Sep 90 16:44:36 GMT, mikel@cadence.cadence.com said:
mikel> Recently I had a UNIX question.  I have a c program and I want to
mikel> know which shell(sh,csh,ksh) is my parent.  Is there any way to do
mikel> this?  Environment variable is not acceptable.

There is always the kludge of calling getppid() for your parent's process
ID, then examining the output of "ps" (given appropriate arguments) to find
out what fired off your program.  Note: If your C program has a shell
script wrapper, _that_ is what you'll find, not the shell the user used.  I
_assume_ this is what you care about and not the user's shell, otherwise
the SHELL environment variable probably would be a better approach.

Even less portably, your program can run as SUID root or SGID kmem and wade
through /dev/(k)mem for information.

	Have fun,

Chuck Phillips  MS440
NCR Microelectronics 			Chuck.Phillips%FtCollins.NCR.com
2001 Danfield Ct.
Ft. Collins, CO.  80525   		uunet!ncrlnk!ncr-mpd!bach!chuckp
--
Chuck Phillips  MS440
NCR Microelectronics 			Chuck.Phillips%FtCollins.NCR.com
2001 Danfield Ct.
Ft. Collins, CO.  80525   		uunet!ncrlnk!ncr-mpd!bach!chuckp

jrw@mtune.ATT.COM (Jim Webb) (09/18/90)

In article <josef.653134656@peun11>, josef@nixpbe.UUCP (Moellers) writes:
> In <1990Sep11.164436.9592@cadence.com> mikel@cadence.cadence.com writes:
> 
> 
> >        Recently I had a UNIX question.  I have a c program and
> >I want to know which shell(sh,csh,ksh) is my parent.  Is there
> >any way to do this?  Environment variable is not acceptable.
> 
> Quick'n'dirty:
>       ...
> 	ppid = getppid()
> 	ps = popen("ps", "r");

Since you know the parent's pid, why don't you pass it on the the
ps command?  Ergo:

	char psbuf[20];
	sprintf(psbuf,"/bin/ps -p%d",getppid());
	ps = popen(psbuf, "r");

> 	fgets(line, 80, ps);	/* skip "PID TTY TIME COMMAND" */
> 	shell = (char *) 0;

Doing this, you don't need to "grep" thru the output to find
the process as you do here:

> 	while (fgets(line, 80, ps) != NULL)
> 	{
> 		pspid = atoi(line);
> 		if (pspid == ppid)
> 		{
> 			shell = line+22;  <--------------------------+
> 			break;                                       |
> 		}                                                    |
> 	}                                                            |
                                                                     |
> 	shell[strlen(shell)-1] = '\0';                               |
                                                                     |
You really ought to do the above line AFTER making sure that some    |
was assigned to it :-)  Like right here instead ---------------------+
Granted, in this case all it would probably do is write a \0 into
line[79], but it still is a bad practice to get into, especially
since you test for errors later on here:

> 	if (shell == (char *) 0)
> 		printf("Huh??");
> 	else
> 		printf("Your friendly neighbourhood shell is \"%s\"\n", shell);

Another thing you might want to clobber out is the - at the begining of
login shells (eg -sh):

	if (*shell == '-') shell++;

ps
I just hope this isn't going into a set[u|g]id program, popen()'s are
quite scary in that case.....

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