[comp.unix.questions] Login shell?

mukul@hi-csc.UUCP (Mukul Agrawal) (10/04/88)

Is there a way ( /bin/csh , Sun Unix 3.4 ) to find out if the shell
that is running is a login shell or not, just like one can use
"$?prompt" to find out whether or not it is an interactive shell.

Thanks in advance

-- Mukul Agrawal

mukul%orion@hi-csc.honeywell.com
uunet!hi-csc!orion!mukul

chris@mimsy.UUCP (Chris Torek) (10/04/88)

In article <3ed799bc.103e8@hi-csc.UUCP> mukul@hi-csc.UUCP (Mukul Agrawal)
writes:
>Is there a way ( /bin/csh , Sun Unix 3.4 ) to find out if the shell
>that is running is a login shell or not, just like one can use
>"$?prompt" to find out whether or not it is an interactive shell.

This is not completely foolproof, but will usually do the trick.
In your .cshrc:

	if ($?CSHDEPTH) then
		@ depth = $CSHDEPTH + 1
		setenv CSHDEPTH $depth
		unset depth
	else
		setenv CSHDEPTH 1
	endif

For Bourne shell users, in .profile:

	SHDEPTH=`expr ${SHDEPTH-0} + 1`; export SHDEPTH

It should be obvious how to modify this for a simple yes/no test,
although I prefer the more general solution.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

leo@philmds.UUCP (Leo de Wit) (10/05/88)

In article <3ed799bc.103e8@hi-csc.UUCP> mukul@hi-csc.UUCP (Mukul Agrawal) writes:
|Is there a way ( /bin/csh , Sun Unix 3.4 ) to find out if the shell
|that is running is a login shell or not, just like one can use
|"$?prompt" to find out whether or not it is an interactive shell.

Don't know whether there is a standard way; at least the csh seems to
know whether it is a login shell or not - try for instance 'login' in a
not-login shell (probably done by inspecting the parent process id;
even if you exec a login shell by a new shell it is considered a
not-login shell, so this seems also to point to process ids).

If you don't have to use it on a system-wide basis (what I mean is this
solution is reliable as far as the user is reliable) you can solve your
problem with this little trick: put into your ~/.login a line:

set login_shell

As .login is sourced only by the login csh, the presence of this shell
variable can now be tested to find out whether you're dealing with a
login shell.  Something similar can be done for the Bourne shell,
putting this variable in the $HOME/.profile (e.g. login_shell=1 ); in
this case you must not export the variable so that it won't be
inherited into the environment of subsequent shell invocations.

I hope this help -
                    Leo.

davidsen@steinmetz.ge.com (William E. Davidsen Jr) (10/05/88)

  In the same area: ksh has an environment variable "PPID" which holds
the parent PID. It is set at startup and is read only.
-- 
	bill davidsen		(wedu@ge-crd.arpa)
  {uunet | philabs}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me

croes@imec.uucp (Kris Croes) (10/11/88)

In article <3ed799bc.103e8@hi-csc.UUCP> mukul@hi-csc.UUCP (Mukul Agrawal)
writes:
>Is there a way ( /bin/csh , Sun Unix 3.4 ) to find out if the shell
>that is running is a login shell or not, just like one can use
>"$?prompt" to find out whether or not it is an interactive shell.

The following is not exactly an answer to this question (Chris Torek
answered it exactly in article <13851@mimsy.UUCP>), but it is related
and useful too.

A way to detect whether your .cshrc is executed the first time, or whether
it is executed with a "source .cshrc" e.g. after you edited it is:

< 1>  # Test if new csh.
< 2>  set temp = /tmp/prompt$$
< 3>  history 1 > $temp
< 4>  if (-z $temp) then
< 5>    # This is the first time .cshrc is executed
< 6>    alias lpr    `which lpr` \!\* \&
< 7>  else
< 8>    # This is when .cshrc is executed with 'source'
< 9>  endif
<10>  /bin/rm $temp
<11>  unset temp

Why is this usefull? A little example:

When no precautions are taken, on some machines the `which ...` on line 6 would
return "alias: /usr/local/lpr !* &" when you source your .cshrc.
From then on, you need paper and a pencil to make listings. 8-)

Hopefully someone can use it...

Kris Croes.
-- 
--------
K. CROES - IMEC - Leuven - Belgium   ..!prlb2!imec!croes

The Demon King sends a "rm -r /" to your shell.

maart@cs.vu.nl (Maarten Litmaath) (10/15/88)

In article <511@imec.UUCP> croes@imec.UUCP (Kris Croes) writes:
\A way to detect whether your .cshrc is executed the first time, or whether
\it is executed with a "source .cshrc" e.g. after you edited it is:
\
\< 1>  # Test if new csh.
\< 2>  set temp = /tmp/prompt$$
\< 3>  history 1 > $temp
\< 4>  if (-z $temp) then
\< 5>    # This is the first time .cshrc is executed
\< 6>    alias lpr    `which lpr` \!\* \&
\< 7>  else
\< 8>    # This is when .cshrc is executed with 'source'
\< 9>  endif
\<10>  /bin/rm $temp
\<11>  unset temp

The above can be done much easier, without the temp file:

------------------------------cut here------------------------------
if ($?history) then
	echo You sourced .cshrc!
else
	echo This is the first time!
	set history=1			# or more :-)
endif
------------------------------cut here------------------------------

\The Demon King sends a "rm -r /" to your shell.

A "/bin/rm -rf $HOME" is more effective, in general :-)
-- 
Hippic sport:                         |Maarten Litmaath @ Free U Amsterdam:
             a contradiction in terms.|maart@cs.vu.nl, mcvax!botter!maart

thomas@uplog.se (Thomas Hameenaho) (10/17/88)

One way of deciding wether or not the current shell is the login shell
is the fact that the name of the login shell is prependended with a '-'.
If for instance I run tcsh as my login shell it will be exec:ed with
-tcsh as argv[0].

Just take the output from ps -x (or -f if on system V) grep for pid $$
and check if the command name begins with a '-'. If that is the case the
shell is the login shell.

-- 
Real life:	Thomas Hameenaho		Email:	thomas@uplog.{se,uucp}
Snail mail:	TeleLOGIC Uppsala AB		Phone:	+46 18 189406
		Box 1218			Fax:	+46 18 132039
		S - 751 42 Uppsala, Sweden

leo@philmds.UUCP (Leo de Wit) (10/23/88)

In article <314@uplog.se> thomas@uplog.UUCP (Thomas Hameenaho) writes:
|One way of deciding wether or not the current shell is the login shell
|is the fact that the name of the login shell is prependended with a '-'.
|If for instance I run tcsh as my login shell it will be exec:ed with
|-tcsh as argv[0].
|
|Just take the output from ps -x (or -f if on system V) grep for pid $$
|and check if the command name begins with a '-'. If that is the case the
|shell is the login shell.

Two problems: 
1) When I execl("/bin/sh","-sh",(char *)0); from within a C program I
also have a shell whose name starts with '-' (it will consequently try
to read a .profile file in the current directory, have you ever tried
that?). This is not a login shell (unless the C program is called login
8-).
2) When I exec a shell in my .profile file (for instance if I want my
own shell instead of /bin/sh or /bin/csh and don't want to bother my
system manager), this shell doesn't start with '-'. You could argue
about it, but I would like to consider this a login shell (the other
'login shell' has in fact also little to do with login, except for the
fact that it is exec'ed from login, but then, this one is too).

           Leo.

dik@cwi.nl (Dik T. Winter) (10/23/88)

In article <842@philmds.UUCP> leo@philmds.UUCP (Leo de Wit) writes:
 > 2) When I exec a shell in my .profile file (for instance if I want my
 > own shell instead of /bin/sh or /bin/csh and don't want to bother my
 > system manager), this shell doesn't start with '-'.

But why not?  This is just what I have done for a long time: in my bin:
	ln -s $HOME/bin/my_shell -my_shell
and at the start of my .profile:
	case $SHELL in
	*my_shell)	;;
	*)	SHELL=$HOME/bin/my_shell
		PATH=$HOME/bin exec -my_shell
	esac
Works like a charm.  My shell will even do .profile.
-- 
dik t. winter, cwi, amsterdam, nederland
INTERNET   : dik@cwi.nl
BITNET/EARN: dik@mcvax

leo@philmds.UUCP (Leo de Wit) (10/23/88)

In article <7677@boring.cwi.nl> dik@cwi.nl (Dik T. Winter) writes:
|In article <842@philmds.UUCP> leo@philmds.UUCP (Leo de Wit) writes:
| > 2) When I exec a shell in my .profile file (for instance if I want my
| > own shell instead of /bin/sh or /bin/csh and don't want to bother my
| > system manager), this shell doesn't start with '-'.
|
|But why not?  This is just what I have done for a long time: in my bin:
|	ln -s $HOME/bin/my_shell -my_shell
|and at the start of my .profile:
|	case $SHELL in
|	*my_shell)	;;
|	*)	SHELL=$HOME/bin/my_shell
|		PATH=$HOME/bin exec -my_shell
|	esac
|Works like a charm.  My shell will even do .profile.

I used that trick myself; not from a .profile but to get a .profile read.
But as far as I know, symbolic links are a BSD feature; when you have to
use a hard link, it may not be possible (different filesystem); even cp
fails if the original shell wasn't readable.

                                             Leo.

ron@ron.rutgers.edu (Ron Natalie) (10/23/88)

> Just take the output from ps -x (or -f if on system V) grep for pid $$
> and check if the command name begins with a '-'. If that is the case the
> shell is the login shell.

How about just comparing $0.

ag@elgar.UUCP (Keith Gabryelski) (10/24/88)

In article <842@philmds.UUCP> leo@philmds.UUCP (Leo de Wit) writes:
>1) When I execl("/bin/sh","-sh",(char *)0); from within a C program I
>also have a shell whose name starts with '-'

Yes, so... Don't do it.

>2) When I exec a shell in my .profile file (for instance if I want my
>own shell instead of /bin/sh or /bin/csh and don't want to bother my
>system manager), this shell doesn't start with '-'.

Bother your system manager or ``execl("/bin/sh","-sh",(char *)0); from
within a C program'' in .profile.

Pax, Keith
-- 
ag@elgar.CTS.COM         Keith Gabryelski          ...!{ucsd, jack}!elgar!ag

leo@philmds.UUCP (Leo de Wit) (10/25/88)

In article <11@elgar.UUCP> ag@elgar.UUCP (Keith Gabryelski) writes:
|In article <842@philmds.UUCP> leo@philmds.UUCP (Leo de Wit) writes:
|>1) When I execl("/bin/sh","-sh",(char *)0); from within a C program I
|>also have a shell whose name starts with '-'
|
|Yes, so... Don't do it.

But the '-' option is what I might desperately need, e.g. the C program
is a gate program and I want a .profile to be read when the sh starts.
(yes, I really use this).
A solution for determining the login shell should not say: Ah, but you
mustn't do this, and you mustn't do that or else it fails. It would be
a poor solution otherwise.

|>2) When I exec a shell in my .profile file (for instance if I want my
|>own shell instead of /bin/sh or /bin/csh and don't want to bother my
|>system manager), this shell doesn't start with '-'.
|
|Bother your system manager or ``execl("/bin/sh","-sh",(char *)0); from
|within a C program'' in .profile.

The first thing, ok (if my system manager feels like conforming to
another whim of mine, that is 8-); about the second one, you mean of
course:

execl("/usr/leo/bin/myshell","-sh",(char *)0); from .profile (/bin/sh
I don't need to start thus).

Three remarks:
a) you have to start a separate C program just to accomplish $0 == -sh,
this doesn't sound nice.
b) this new shell you start will read .profile *again*; you will have
to make provisions it doesn't start that C program again
(over and over ...).
c) you still have to fire up a ps to determine whether it's a login
shell, or look at $0. Both methods are fooled by programs whose names
start with '-' (not that there will be that many...). Think for instance
of the symbolic link someone else used to get the '-' in front of the
shell's name; if you by any chance start that shell from your current
shell, it will appear to be a 'login shell'.

          Leo.

schaefer@ogccse.ogc.edu (Barton E. Schaefer) (10/25/88)

I've been watching this discussion with only moderate interest, but
the most recent couple of postings seem to have come full circle,
i.e., the argument has now become "but I can't look for a `-' in ps
because I might start a not-login shell whose name begins with `-'."
So I thought I'd throw in a semi-new suggestion.

I have no experience with SysV, so somebody else will have to tell
me if this does not work there.  But on BSD, why not:
    1) Use "ps xl" (produces the PARENT pid as well as the pid)
    2) Grep for the pid
    3) Check the parent pid; if `1', then you have a login shell

This will never identify a not-login shell as a login shell, but it
will fail to identify rlogin shells (whose ppid is that of the rlogin
daemon).  Even that could be worked around if you use "ps axl" and
save the output in a file; once you have the ppid, grep for that, and
check the name of the parent process to see if it is "rlogind".

Anybody see any problems with this?  I suppose technically that a
shell started with "exec" from a login shell is not exactly a login
shell, but you'd probably want it to behave like one, so this test
should be OK.
-- 
Bart Schaefer		"You've heard of Load/Store architectures?  Well, the
			 80286 is a L-l-l-load/S-s-s-store architecture."
CSNET   (Has not changed)	schaefer@cse.ogc.edu
UUCP    (Should work now)	...{sun,tektronix,verdix}!ogccse!schaefer

davidsen@steinmetz.ge.com (William E. Davidsen Jr) (10/26/88)

In article <314@uplog.se> thomas@uplog.UUCP (Thomas Hameenaho) writes:
| One way of deciding wether or not the current shell is the login shell
| is the fact that the name of the login shell is prependended with a '-'.
| If for instance I run tcsh as my login shell it will be exec:ed with
| -tcsh as argv[0].

  Only in a trusted environment. I can change the strings in the exec
call so that the first argument is not the same as the program name. A
better way is to check the PPID if your system has a known PID for init.
Other than that you're on your own, but remember if you want to run
something like "ps" to use the full pathname, at least.

  Most of the techniques mentioned are highly useful in a well behaved
environment in which you are trying to avoid initialization or some
such, but less reliable in the case where someone may be tricking your
program into thinking it's a login shell.
-- 
	bill davidsen		(wedu@ge-crd.arpa)
  {uunet | philabs}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me

ggs@ulysses.homer.nj.att.com (Griff Smith) (11/01/88)

In article <25721@bu-cs.BU.EDU>, madd@bu-cs.BU.EDU (Jim Frost) writes:
> In article <314@uplog.se> thomas@uplog.UUCP (Thomas Hameenaho) writes:
| |One way of deciding wether or not the current shell is the login shell
| |is the fact that the name of the login shell is prependended with a '-'.
| ...
> That's not really a good indicator.   Instead what I'd do is build the
> process tree (you can use the output from ps or, better, sps if you
> can't build it from the actual process table).  Find the first entry in
> the tree for the terminal you want.  This will work on any unix
> system, while the naming convention may not.
| ...
> jim frost
> madd@bu-it.bu.edu

Still not quite right.  I usually use an AT&T 630 terminal on a 4.3BSD
system.  The login shell for the terminal is not the same as the shell
for the current window, and each window has a separate pty connected to
it.  The kludge I use also involves reading the output of ps (ugh): I
scan back through the process tree until I find a parent with a
different uid.  The child of that process is almost always the login
shell.  For my purposes, this also does the right thing for `su'.
I'd rather have someone support the concept of a session id so we could
avoid this sillyness.
-- 
Griff Smith	AT&T (Bell Laboratories), Murray Hill
Phone:		1-201-582-7736
UUCP:		{most AT&T sites}!ulysses!ggs
Internet:	ggs@ulysses.att.com

logan@vsedev.VSE.COM (James Logan III) (11/03/88)

In article <10791@ulysses.homer.nj.att.com> ggs@ulysses.homer.nj.att.com (Griff Smith) writes:
>In article <25721@bu-cs.BU.EDU>, madd@bu-cs.BU.EDU (Jim Frost) writes:
>> In article <314@uplog.se> thomas@uplog.UUCP (Thomas Hameenaho) writes:
>| |One way of deciding wether or not the current shell is the login shell
>| |is the fact that the name of the login shell is prependended with a '-'.
>| ...
>> That's not really a good indicator.   Instead what I'd do is build the
>> process tree (you can use the output from ps or, better, sps if you
>> can't build it from the actual process table).  Find the first entry in
>> the tree for the terminal you want.  This will work on any unix
>> system, while the naming convention may not.
>| ...
>> jim frost
>> madd@bu-it.bu.edu
>
>Still not quite right.  I usually use an AT&T 630 terminal on a 4.3BSD
>system.  The login shell for the terminal is not the same as the shell
>for the current window, and each window has a separate pty connected to
>it.  The kludge I use also involves reading the output of ps (ugh): I
>scan back through the process tree until I find a parent with a
>different uid.  The child of that process is almost always the login
>shell.  For my purposes, this also does the right thing for `su'.
>I'd rather have someone support the concept of a session id so we could
>avoid this sillyness.

What is the purpose?  If you just want to find out what if the current
shell is indeed the shell spawned by init(1M) (via getty(1M), login(1)),
then just write a simple C program like this:
--------
#include <stdio.h>

main()
{
	if (getppid() == getpgrp())
		exit(0);
	exit(1);
}
-------

Call it something like "is_top" and use it like this in sh(1) or ksh(1):
-------
if is_top; then
	echo "Yes, this is the login shell.";
else
	echo "No, this is not the login shell.";
fi;
-------
Or just put printf(3C) statements in the C program itself...

Unless you have a program that explicitly resets the process group ID,
it will be the PID of the login shell (which would be the parent PID
when this C program is running).

Another more accurate way to do this is to use getutline(3C) to
get a utmp structure for your current tty (which won't work with
a multiplexed terminal using sxt's...) and check the parent PID
against utmp.ut_pid.  Let me know if you need more details.

		I hope this is what you're looking for...

				-Jim

maart@cs.vu.nl (Maarten Litmaath) (11/04/88)

In article <1217@vsedev.VSE.COM> logan@vsedev.VSE.COM (James Logan III) writes:
\... If you just want to find out what if the current
\shell is indeed the shell spawned by init(1M) (via getty(1M), login(1)),
\then just write a simple C program like this:
\--------
\#include <stdio.h>
\
\main()
\{
\	if (getppid() == getpgrp())
\		exit(0);
\	exit(1);
\}

1)
	Why #include <stdio.h>?
2)
	This scheme won't work for rsh/rlogin.
-- 
George Bush:                          |Maarten Litmaath @ VU Amsterdam:
             Capt. Slip of the Tongue |maart@cs.vu.nl, mcvax!botter!maart

ggs@ulysses.homer.nj.att.com (Griff Smith) (11/05/88)

In article <1217@vsedev.VSE.COM>, logan@vsedev.VSE.COM (James Logan III) writes:
> In article <10791@ulysses.homer.nj.att.com> ggs@ulysses.homer.nj.att.com (Griff Smith) writes:

[sorry, I've lost track of who owns the following fragment]

> >> ...This will work on any unix system, while the naming convention may not.

[this one's mine]

> >Still not quite right.  I usually use an AT&T 630 terminal on a 4.3BSD
> >system.  ... The kludge I use involves reading the output of ps ...

[Logan's reply]

> What is the purpose?  If you just want to find out what if the current
> shell is indeed the shell spawned by init(1M) (via getty(1M), login(1)),
> then just write a simple C program like this:

[deleted programs that get the process group id]

> Unless you have a program that explicitly resets the process group ID,

I do.  It's called ksh.  The reset is needed to support job control.

> it will be the PID of the login shell (which would be the parent PID
> when this C program is running).
> Another more accurate way to do this is to use getutline(3C) to
> get a utmp structure for your current tty (which won't work with
> a multiplexed terminal using sxt's...) and check the parent PID
> against utmp.ut_pid.  Let me know if you need more details.

man getutline
No manual entry for getutline.

This agrees with my original point: this will not work on all UNIX
systems!  The notion of a session id is not well-defined.  I don't like
the `scan ps output' solution either; it's ugly and non-portable.  I
want a way to identify a process that usually [exists]/[doesn't exist] if a
person is [logged in]/[not logged in] to a terminal.  With windows and
job control shells this is a mess.
-- 
Griff Smith	AT&T (Bell Laboratories), Murray Hill
Phone:		1-201-582-7736
UUCP:		{most AT&T sites}!ulysses!ggs
Internet:	ggs@ulysses.att.com

logan@vsedev.VSE.COM (James Logan III) (11/08/88)

In article <10808@ulysses.homer.nj.att.com> ggs@ulysses.homer.nj.att.com
(Griff Smith) writes:
>
>In article <1217@vsedev.VSE.COM>, logan@vsedev.VSE.COM (James Logan III)
>writes:
>> Unless you have a program that explicitly resets the process group ID,
>
>I do.  It's called ksh.  The reset is needed to support job control.

My apologies.  I use ksh and it does not reset the process group ID.
I guess you'll have to use the getutline(3C) entry that I mentioned.
(I know, I know -- you can't pull it up with man(1).  Read on.)

>> Another more accurate way to do this is to use getutline(3C) to
>> get a utmp structure for your current tty (which won't work with
>> a multiplexed terminal using sxt's...) and check the parent PID
>> against utmp.ut_pid.  Let me know if you need more details.
>
>man getutline
>No manual entry for getutline.

You're right, you wouldn't find it that way unless you looked in
the manual under "getut".  I figured you would see that
"getutline" was listed under "getut", but since you didn't look
in the manual you wouldn't have seen it.

(That is one BIG reason I try not to use man(1).  I can't pull up
some library calls because they are listed under other calls that
I can never think of unless I see the manual's index.)

>this will not work on all UNIX systems!

You WILL find this call on ALL System V machines that conform to
the SVID.  If your machine doesn't have it, then look up utmp(4)
and write a 10-line function that will read in the structure
declared there and in /usr/include/utmp.h.  I'm pretty sure that
even BSD machines have this.  Even with job control, your utmp
entry's ut_pid WILL be that of your ksh!    

>The notion of a session id is not well-defined.

I agree.  There are all sorts of problems when the device you are
using for I/O is not the device you logged in under.  A program
that looks at the idle time of a terminal and logs you off when
the last atime or mtime of your tty is over a certain limit will
log you off in such a situation, even if you're in the middle of
typing.  That is a pain when I want to use the sxt devices.

			-Jim

-- 
Jim Logan		logan@vsedev.vse.com
(703) 892-0002		uucp:	..!uunet!vsedev!logan
			inet:	logan%vsedev.vse.com@uunet.uu.net

logan@vsedev.VSE.COM (James Logan III) (11/08/88)

In article <1623@solo10.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
>In article <1217@vsedev.VSE.COM> logan@vsedev.VSE.COM (James Logan III) writes:
>\... If you just want to find out what if the current
>\shell is indeed the shell spawned by init(1M) (via getty(1M), login(1)),
>\then just write a simple C program like this:
>\--------
>\#include <stdio.h>
>\
>\main()
>\{
>\	if (getppid() == getpgrp())
>\		exit(0);
>\	exit(1);
>\}
>
>1)
>	Why #include <stdio.h>?

It's not necessary, I just always need it when I don't already have it,
so it's just a habit, I guess.  It doesn't hurt anything and it will only
take a fraction of a second longer to compile it.  In addition, if he
adds an fprintf(), the program won't compile without it since the
type "FILE" will be undefined.

I wouldn't suggest #including every header file you might ever need,
but this one is so often used, why not?

>2)
>	This scheme won't work for rsh/rlogin.

It works just fine for rlogin, thank you.  I just tested it on my
system.  

Since you don't have a true session with rsh it will indicate
correctly that the program running is not your login shell.  

			-Jim
-- 
Jim Logan		logan@vsedev.vse.com
(703) 892-0002		uucp:	..!uunet!vsedev!logan
			inet:	logan%vsedev.vse.com@uunet.uu.net

ggs@ulysses.homer.nj.att.com (Griff Smith) (11/09/88)

In article <1229@vsedev.VSE.COM>, logan@vsedev.VSE.COM (James Logan III) writes:
> My apologies.  I use ksh and it does not reset the process group ID.

Right, your system doesn't have job control.  Wait until Vr4.

> I guess you'll have to use the getutline(3C) entry that I mentioned.
> (I know, I know -- you can't pull it up with man(1).  Read on.)

This is getting strange.  Your responses seem appropriate for
a sheltered member of AT&T who hasn't been allowed near `the
wrong choice'; and I'm the one from AT&T.  One more time: BSD
does not have getutline!  When I read your suggestion, my first
step was to try "nm /lib/libc.a | egrep getu"; the response was

getuid.o:
00000008 T _getuid
getusershell.o:
00000000 T _getusershell

I then tried the same thing on our System V 3B2/600 sitting back in the corner
doing nothing.  The pertinent output was:

Symbols from /lib/libc.a[getut.o]:
getut.c             |        | file |                  |      |     |
getutent            |       0|extern|        *struct( )|   238|     |.text
getutid             |     238|extern|        *struct( )|   155|     |.text
getutline           |     394|extern|        *struct( )|    87|     |.text
getusa              |    1442|static|               ( )|   154|     |.text

I used

> >man getutline
> >No manual entry for getutline.

as a convenient summary that `there ain't no such animal' on the
machine I use.

> >this will not work on all UNIX systems!
> 
> You WILL find this call on ALL System V machines that conform to
> the SVID.

I didn't say it was a System V machine that conforms to the SVID!
I said it was a UNIX system.

> If your machine doesn't have it, then look up utmp(4)
> and write a 10-line function that will read in the structure
> declared there and in /usr/include/utmp.h.  I'm pretty sure that
> even BSD machines have this.  Even with job control, your utmp
> entry's ut_pid WILL be that of your ksh!    

The utmp definition in /usr/include/utmp.h on my 4.3BSD tahoe system is:

struct utmp {
	char	ut_line[8];		/* tty name */
	char	ut_name[8];		/* user id */
	char	ut_host[16];		/* host name, if remote */
	long	ut_time;		/* time on */
};

I don't see an entry for ut_pid!  I do see one on my System V machine.

Our local copy of "who" does manage to separate the real tty and the
associated windows:

ggs      tty11   Nov  8 08:51	(windows: ttyp[234] )

Note, however, that I still don't have the pid of the shell connected
to tty11.

I repeat my point: genetic drift has made it dangerous to state that
X works on all UNIX systems.  Perhaps things will get better when
Xenix, System V, Sun release whatever and 4.3BSD get all mushed together
into System V Release 4.

> -- 
> Jim Logan		logan@vsedev.vse.com
> (703) 892-0002		uucp:	..!uunet!vsedev!logan
> 			inet:	logan%vsedev.vse.com@uunet.uu.net
-- 
Griff Smith	AT&T (Bell Laboratories), Murray Hill
Phone:		1-201-582-7736
UUCP:		{most AT&T sites}!ulysses!ggs
Internet:	ggs@ulysses.att.com

maart@cs.vu.nl (Maarten Litmaath) (11/09/88)

In article <1230@vsedev.VSE.COM> logan@vsedev.VSE.COM (James Logan III) writes:
\In article <1623@solo10.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
\>In article <1217@vsedev.VSE.COM> logan@vsedev.VSE.COM (James Logan III) writes:
\>\... If you just want to find out what if the current
\>\shell is indeed the shell spawned by init(1M) (via getty(1M), login(1)),
\>\then just write a simple C program like this:
\>\--------
\>\#include <stdio.h>
\>\
\>\main()
\>\{
\>\	if (getppid() == getpgrp())
\>\		exit(0);
\>\	exit(1);
\>\}
\...
\>2)
\>	This scheme won't work for rsh/rlogin.
\
\It works just fine for rlogin, thank you.  I just tested it on my
\system.  
\
\Since you don't have a true session with rsh it will indicate
\correctly that the program running is not your login shell.  

When I do an rsh, I want my environment set too on the remote machine,
thank you. Effectively it IS a loginshell (rLOGIN, see?).
Are you suggesting every setenv, stty, etc. should get placed in .cshrc?
-- 
George Bush:                          |Maarten Litmaath @ VU Amsterdam:
             Capt. Slip of the Tongue |maart@cs.vu.nl, mcvax!botter!maart

guy@auspex.UUCP (Guy Harris) (11/09/88)

>You WILL find this call on ALL System V machines that conform to
>the SVID.  If your machine doesn't have it, then look up utmp(4)
>and write a 10-line function that will read in the structure
>declared there and in /usr/include/utmp.h.  I'm pretty sure that
>even BSD machines have this.  Even with job control, your utmp
>entry's ut_pid WILL be that of your ksh!    

BSD systems, just like the AT&T V7 systems from which they are
descended, do not have a "ut_pid" in their "utmp" entries.

thomas@uplog.se (Thomas Hameenaho) (11/10/88)

In article <1829@ogccse.ogc.edu> schaefer@ogccse.UUCP (Barton E. Schaefer) writes:
>I have no experience with SysV, so somebody else will have to tell
>me if this does not work there.  But on BSD, why not:
>    1) Use "ps xl" (produces the PARENT pid as well as the pid)
>    2) Grep for the pid
>    3) Check the parent pid; if `1', then you have a login shell
>

This is not completely fool-proof either. If you have shell that isn't the
login shell and you manage to kill the parent of this shell without killing
the shell itself this shell winds up having a PPID of 1.

-- 
Real life:	Thomas Hameenaho		Email:	thomas@uplog.{se,uucp}
Snail mail:	TeleLOGIC Uppsala AB		Phone:	+46 18 189406
		Box 1218			Fax:	+46 18 132039
		S - 751 42 Uppsala, Sweden

thomas@uplog.se (Thomas Hameenaho) (11/11/88)

In article <Oct.23.09.32.38.1988.11774@ron.rutgers.edu> ron@ron.rutgers.edu (Ron Natalie) writes:
>How about just comparing $0.


Script started on Fri Nov 11 08:59:45 1988
41@uplog> echo $0
No file for $0.
42@uplog> sh
$ echo $0
sh

-- 
Real life:	Thomas Hameenaho		Email:	thomas@uplog.{se,uucp}
Snail mail:	TeleLOGIC Uppsala AB		Phone:	+46 18 189406
		Box 1218			Fax:	+46 18 132039
		S - 751 42 Uppsala, Sweden

jc@minya.UUCP (John Chambers) (11/17/88)

In article <331@uplog.se>, thomas@uplog.se (Thomas Hameenaho) writes:
> In article <1829@ogccse.ogc.edu> schaefer@ogccse.UUCP (Barton E. Schaefer) writes:
> >I have no experience with SysV, so somebody else will have to tell
> >me if this does not work there.  But on BSD, why not:
> >    1) Use "ps xl" (produces the PARENT pid as well as the pid)
> >    2) Grep for the pid
> >    3) Check the parent pid; if `1', then you have a login shell
> >
> 
> This is not completely fool-proof either. If you have shell that isn't the
> login shell and you manage to kill the parent of this shell without killing
> the shell itself this shell winds up having a PPID of 1.
> 
Another case where it won't work:  Some time ago, I posted an alternate
login daemon to comp.unix.sources called "uutty", named to imply that it
understands uucp and with a "-L" option creates uucp lockfiles during a
login session to warn uucp away from the port.  (It also does things like
allowing use of the port in both directions, as it backs off silently when
a uucp lockfile appears).  In order for this to work, it has to stay in
the background during a session, else there is no way for it to know to
remove the lockfile when you log out.  So your login shell ends up having
uutty as its parent.

I've noticed that quite a few other people are talking seriously about
writing their own login daemon.  (Go ahead; it's fun. :-)  Some of them
will end up doing something similar.  So checking for (ppid==1) will be
even less useful in the future than it is now.

-- 
John Chambers <{adelie,ima,maynard,mit-eddie}!minya!{jc,root}> (617/484-6393)

[Any errors in the above are due to failures in the logic of the keyboard,
not in the fingers that did the typing.]

sridhar@usceast.UUCP (M. A. Sridhar) (12/08/89)

Is there any way to determine, within a shell script (csh), whether the script 
is being executed by the login shell? I know that one can use the fact that
$prompt is set to detect an interactive shell, but I don't know how to test
whether it's the login shell.

Thanks in advance.
					- Sridhar

-- 
M. A. Sridhar                  | 
Department of Computer Science | ncr-sd!ncrcae ! usceast!sridhar (USENET)
University of South Carolina   | sridhar@cs.scarolina.edu (CSNET)
Columbia, SC 29208             | (803) 777-2427 (Ma Bell)      

khera@macbeth.cs.duke.edu (Vick Khera) (12/10/89)

In article <2975@usceast.UUCP> sridhar@usceast.uucp.UUCP (M. A. Sridhar) writes:
>Is there any way to determine, within a shell script (csh), whether the script 
>is being executed by the login shell? I know that one can use the fact that
>$prompt is set to detect an interactive shell, but I don't know how to test
>whether it's the login shell.

the trick i use is to check for the existence of a particular environment
variable (such as NAME) that i set in my .login file, since it is run after
the .cshrc file is.  if this variable is set, then most likely the shell is
not a login shell, otherwise i assume it is.

							v.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Vick Khera                              Department of Computer Science
ARPA:   khera@cs.duke.edu               Duke University
UUCP:   ..!{mcnc,decvax}!duke!khera     Durham, NC 27706

jdpeek@rodan.acs.syr.edu (Jerry Peek) (12/10/89)

In article <2975@usceast.UUCP> sridhar@usceast.uucp.UUCP (M. A. Sridhar) writes:
> Is there any way to determine, within a shell script (csh), whether the script
> is being executed by the login shell? I know that one can use the fact that
> $prompt is set to detect an interactive shell, but I don't know how to test
> whether it's the login shell.

This is a good excuse to post a nice set of code that I got from someone
(and hacked up myself).  It fixes your prompt so that it looks like this
in a top-level (login) shell:
	hostname%
On the first-level subshell, it looks like:
	(1) hostname%
and so on.

You could adapt this code for your needs.  You may want to think about
whether you want the following shells to be considered "login shells":
	- a shell started by the "su username" command
	- a shell started in a window by a windowing system like SunView
Also, if run your shell script with "csh -f", it won't read .cshrc --
so, the CSHLEVEL envariable won't be incremented -- that might or might
not be what you want.

This stuff could be cleaned up some.  I set it up to handle those
two special cases I mentioned above.  I'm not sure there's any one
"perfect" set of code for all situations.

Let's *NOT* start another round of "prompt wars", please!!

--Jerry Peek; Syracuse University Academic Computing Services; Syracuse, NY
  jdpeek@rodan.acs.syr.edu, JDPEEK@SUNRISE.BITNET        +1 315 443-3995

-------------- cut here; code below goes in .cshrc ---------------------
setenv HOST "`hostname | sed 's/\..*//'`"	# STRIP OFF DOMAIN STUFF

# SET SHELL LEVEL (DEPTH OF NESTED SHELLS).
# IF WE'VE ALREADY SET $CSHLEVEL ENVARIABLE BELOW AND THE $cshlevel SHELL
# VARIABLE IS NOT SET (THAT IS, WE'VE JUST STARTED A SUB-SHELL), INCREMENT
# $CSHLEVEL AND SET $cshlevel.
if ($?CSHLEVEL && (! $?cshlevel) ) then
	set cshlevel = $CSHLEVEL
	@ cshlevel++	# WE CAN'T DO "@ CSHLEVEL++", SO DO $cshlevel FIRST
	setenv CSHLEVEL $cshlevel
endif

# FOR PROMPTS WHEN WE EXECUTE res: SHOW DEPTH OF SHELL LAYER.
# $cshlevel IS SHELL VARIABLE, $CSHLEVEL IS COPY OF IT IN ENVIRONMENT.
# IF $CSHLEVEL UNSET, THEN THIS IS A REAL LOGIN (WE'RE NOT DOING source .cshrc):
if (! $?CSHLEVEL) then
	set cshlevel = 0
	setenv CSHLEVEL 0
endif

alias s_p 'set prompt = "${HOST}% "'
s_p

# IF THIS ISN'T A LEVEL-0 (TOP-LEVEL) SHELL, ADD LEVEL TO START OF $prompt.
# [DO IN TWO LINES BECAUSE USING if ($?cshlevel && $cshlevel != 0) GAVE
# THE ERROR cshlevel: undefined variable.  HOW GET SHORT-CIRCUIT EVALUATION??]
if ( $?cshlevel ) then
	if ($cshlevel != 0) then
		alias s_p 'set prompt="($cshlevel) $prompt"'
		s_p
	endif
endif