tty-dev-number <-> /dev/pts

tty-dev-number <-> /dev/pts

Post by Uwe Wolfra » Fri, 11 Jul 2003 03:37:01



Hi, I'm writing a program under Solaris (sparc) that has to know
from what machine a user is logged on who is starting that program.

Reading /proc/self/psinfo only returns a device number for the
controlling terminal (long int) whereas the functions listed
in getutxent(3C) give me the device name of the logged on user as
listed by who as well as the remote host (if any).
Is there a way to link all those informations:
device number from /proc -> /dev/pts -> utmpx entry -> remote host?
Or is there a shortcut/simple function to achieve this?

Uwe

--
anti-spam: Remove "duMMy." from address above to obtain correct one

 
 
 

tty-dev-number <-> /dev/pts

Post by Richard L. Hamilt » Fri, 11 Jul 2003 06:55:10




Quote:> Hi, I'm writing a program under Solaris (sparc) that has to know
> from what machine a user is logged on who is starting that program.

> Reading /proc/self/psinfo only returns a device number for the
> controlling terminal (long int) whereas the functions listed
> in getutxent(3C) give me the device name of the logged on user as
> listed by who as well as the remote host (if any).
> Is there a way to link all those informations:
> device number from /proc -> /dev/pts -> utmpx entry -> remote host?
> Or is there a shortcut/simple function to achieve this?

Given a file descriptor to a terminal, ttyname(3c) will (usually)
give the name of the terminal, which you can then scan utmpx for.

--


 
 
 

tty-dev-number <-> /dev/pts

Post by Uwe Wolfra » Sun, 13 Jul 2003 03:30:16



> > Reading /proc/self/psinfo only returns a device number for the
> > controlling terminal (long int) whereas the functions listed
> > in getutxent(3C) give me the device name of the logged on user as
> > listed by who as well as the remote host (if any).
> > Is there a way to link all those informations:
> > device number from /proc -> /dev/pts -> utmpx entry -> remote host?
> > Or is there a shortcut/simple function to achieve this?

> Given a file descriptor to a terminal, ttyname(3c) will (usually)
> give the name of the terminal, which you can then scan utmpx for.

Thanks, that works. Since the app doesn't touch the stdin/stdout file
descriptors, a ttyname (0) returns the pts/# that I can feed to
getutxline(3C).

Uwe

--
anti-spam: Remove "duMMy." from address above to obtain correct one

 
 
 

tty-dev-number <-> /dev/pts

Post by Richard L. Hamilt » Sun, 13 Jul 2003 08:34:12





>> > Reading /proc/self/psinfo only returns a device number for the
>> > controlling terminal (long int) whereas the functions listed
>> > in getutxent(3C) give me the device name of the logged on user as
>> > listed by who as well as the remote host (if any).
>> > Is there a way to link all those informations:
>> > device number from /proc -> /dev/pts -> utmpx entry -> remote host?
>> > Or is there a shortcut/simple function to achieve this?

>> Given a file descriptor to a terminal, ttyname(3c) will (usually)
>> give the name of the terminal, which you can then scan utmpx for.

> Thanks, that works. Since the app doesn't touch the stdin/stdout file
> descriptors, a ttyname (0) returns the pts/# that I can feed to
> getutxline(3C).

That's ok if you're sure nobody will ever run it with stdin redirected.

The following code works as best it can to find the name of the
controlling terminal whether stdin/stdout/stderr has been redirected or
not.  First, it gets pr_ttydev, to know that whatever it finds really is
the controlling terminal.  Then, it checks fd 2, 1, 0 until one of them
matches; if one does, it uses ttyname() on that.  If none do, it uses
ftw() to search /dev for something with a st_rdev that matches pr_ttydev.
Warning: the code is _not_ reentrant - that would be a but more work, and
one should typically only need to run it once in a process anyway.
Disclaimer: just wrote it very quickly (20 minutes or so), only minimally
tested.

Test run:

$ gcc -Wall -pedantic -DTEST_MAIN ctermname.c -o ctermname
$ ./ctermname
/dev/pts/6
$ ./ctermname </dev/null 2>&1 |cat    # with all three redirected
/dev/pts/6

code:

#include <stdio.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <procfs.h>
#include <ftw.h>
#include <unistd.h>
#include <string.h>

static dev_t rdev;
static char name_found[MAXPATHLEN+1];

static int searchfunc(const char *name, const struct stat *statp, int type)
{
    if (type!=FTW_F || !S_ISCHR(statp->st_mode) || statp->st_rdev!=rdev)
        return 0;

    strncpy(name_found,name,MAXPATHLEN);
    name_found[MAXPATHLEN]='\0';
    return 1;

Quote:}

const char *ctermname()
{

    struct psinfo p;
    struct stat s;
    int psinfo_fd;
    int errno_save;
    int use_fd;

    if ((psinfo_fd=open("/proc/self/psinfo",O_RDONLY)) == -1)
        return NULL; /* can't obtain controlling terminal device # */

    switch(read(psinfo_fd,&p,sizeof p)) {
    case sizeof p: /* good */
        break;
    case -1:            /* error */
        errno_save=errno;
        close(psinfo_fd);
        errno=errno_save;
        return NULL;
    default:            /* unexpected short read */
        close(psinfo_fd);
        errno=EINVAL;   /* or whatever you think is most appropriate */
        return NULL;
    }

    close(psinfo_fd);

    if (p.pr_ttydev==PRNODEV) {  /* no controlling terminal */
        errno=ENODEV; /* seems like best choice */
        return NULL;
    }

    /* now try to fstat() 2, 1, 0 until one gives something useful; if
       none do, we can fall back to a slower approach */

    if ((fstat(use_fd=2,&s) != -1 && S_ISCHR(s.st_mode) && s.st_rdev==p.pr_ttydev) ||
        (fstat(use_fd=1,&s) != -1 && S_ISCHR(s.st_mode) && s.st_rdev==p.pr_ttydev) ||
        (fstat(use_fd=0,&s) != -1 && S_ISCHR(s.st_mode) && s.st_rdev==p.pr_ttydev)) {
            /* use_fd now corresponds to an fd on the controlling tty */
            return ttyname(use_fd);

Quote:}

    /* if we get this far, none of stdin, stdout, stderr fds matched the
       controlling device, so we have to do it the hard, slow way */

    rdev=p.pr_ttydev; /* what we're searching for */
    name_found[0]='\0';  /* just to be safe, we clear this */

    if (ftw("/dev",searchfunc,7) == 1) {
        return name_found;

Quote:}

    /* still nothing, set errno to something interesting and return NULL */
    errno=ENOENT;
    return NULL;

Quote:}

#ifdef TEST_MAIN

int main(int argc, char **argv)
{
    const char *p;

    if ((p=ctermname())!=NULL) {
        printf("%s\n",p);
        return 0;
    }
    else {
        perror("ctermname() failed");
        return 1;
    }

Quote:}

#endif

--

 
 
 

tty-dev-number <-> /dev/pts

Post by Uwe Wolfra » Mon, 14 Jul 2003 01:42:43



> That's ok if you're sure nobody will ever run it with stdin redirected.

Quite sure since it's an X11-app, but of course, I cannot guarantee it.

Quote:> The following code works as best it can to find the name of the
> controlling terminal whether stdin/stdout/stderr has been redirected or
> not.  First, it gets pr_ttydev, to know that whatever it finds really is
> the controlling terminal.  Then, it checks fd 2, 1, 0 until one of them
> matches; if one does, it uses ttyname() on that.  If none do, it uses
> ftw() to search /dev for something with a st_rdev that matches
> pr_ttydev. Warning: the code is _not_ reentrant - that would be a but
> more work, and one should typically only need to run it once in a
> process anyway. Disclaimer: just wrote it very quickly (20 minutes or
> so), only minimally tested.

Quite a bunch of lines :-)
I'm going to examine it later, thanks a lot for providing the code.
Reentrance is definitely not a requirement.

Uwe

--
anti-spam: Remove "duMMy." from address above to obtain correct one

 
 
 

tty-dev-number <-> /dev/pts

Post by Casper H.S. Di » Mon, 25 Aug 2003 19:39:33



>Hi, I'm writing a program under Solaris (sparc) that has to know
>from what machine a user is logged on who is starting that program.
>Reading /proc/self/psinfo only returns a device number for the
>controlling terminal (long int) whereas the functions listed
>in getutxent(3C) give me the device name of the logged on user as
>listed by who as well as the remote host (if any).
>Is there a way to link all those informations:
>device number from /proc -> /dev/pts -> utmpx entry -> remote host?
>Or is there a shortcut/simple function to achieve this?

There's no short cut except in those circumstances where you've switched
on BSM auditing; it records the origin of the user in his audit
data.

Casper
--
Expressed in this posting are my opinions.  They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.

 
 
 

tty-dev-number <-> /dev/pts

Post by Richard L. Hamilt » Tue, 26 Aug 2003 23:51:31





>>Hi, I'm writing a program under Solaris (sparc) that has to know
>>from what machine a user is logged on who is starting that program.

>>Reading /proc/self/psinfo only returns a device number for the
>>controlling terminal (long int) whereas the functions listed
>>in getutxent(3C) give me the device name of the logged on user as
>>listed by who as well as the remote host (if any).
>>Is there a way to link all those informations:
>>device number from /proc -> /dev/pts -> utmpx entry -> remote host?
>>Or is there a shortcut/simple function to achieve this?

> There's no short cut except in those circumstances where you've switched
> on BSM auditing; it records the origin of the user in his audit
> data.

I think I posted some code awhile back that would give the name of the
controlling terminal, even if there were no file descriptors open on it.
But in case someone missed it, here it is again.  Given the name, one could
indeed get the utmpx entry.  Of course that only works for a program that
has a controlling terminal at the time it is started; if one should arrange
to start a program in a deferred manner (nohup'd shell script with long
sleep at the top, maybe) such that there is no longer a controlling
terminal when it starts, then this wouldn't do any good and audit logs
would probably be the only hope of getting an answer.

======================= cut here =======================
#include <stdio.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <procfs.h>
#include <ftw.h>
#include <unistd.h>
#include <string.h>

static dev_t rdev;
static char name_found[MAXPATHLEN+1];

static int searchfunc(const char *name, const struct stat *statp, int type)
{
    if (type!=FTW_F || !S_ISCHR(statp->st_mode) || statp->st_rdev!=rdev)
        return 0;

    strncpy(name_found,name,MAXPATHLEN);
    name_found[MAXPATHLEN]='\0';
    return 1;

Quote:}

const char *ctermname()
{

    struct psinfo p;
    struct stat s;
    int psinfo_fd;
    int errno_save;
    int use_fd;

    if ((psinfo_fd=open("/proc/self/psinfo",O_RDONLY)) == -1)
        return NULL; /* can't obtain controlling terminal device # */

    switch(read(psinfo_fd,&p,sizeof p)) {
    case sizeof p: /* good */
        break;
    case -1:            /* error */
        errno_save=errno;
        close(psinfo_fd);
        errno=errno_save;
        return NULL;
    default:            /* unexpected short read */
        close(psinfo_fd);
        errno=EINVAL;   /* or whatever you think is most appropriate */
        return NULL;
    }

    close(psinfo_fd);

    if (p.pr_ttydev==PRNODEV) {  /* no controlling terminal */
        errno=ENODEV; /* seems like best choice */
        return NULL;
    }

    /* now try to fstat() 2, 1, 0 until one gives something useful; if
       none do, we can fall back to a slower approach */

    if ((fstat(use_fd=2,&s) != -1 && S_ISCHR(s.st_mode) && s.st_rdev==p.pr_ttydev) ||
        (fstat(use_fd=1,&s) != -1 && S_ISCHR(s.st_mode) && s.st_rdev==p.pr_ttydev) ||
        (fstat(use_fd=0,&s) != -1 && S_ISCHR(s.st_mode) && s.st_rdev==p.pr_ttydev)) {
            /* use_fd now corresponds to an fd on the controlling tty */
            return ttyname(use_fd);

Quote:}

    /* if we get this far, none of stdin, stdout, stderr fds matched the
       controlling device, so we have to do it the hard, slow way */

    rdev=p.pr_ttydev; /* what we're searching for */
    name_found[0]='\0';  /* just to be safe, we clear this */

    if (ftw("/dev",searchfunc,7) == 1) {
        return name_found;

Quote:}

    /* still nothing, set errno to something interesting and return NULL */
    errno=ENOENT;
    return NULL;

Quote:}

#ifdef TEST_MAIN

int main(int argc, char **argv)
{
    const char *p;

    if ((p=ctermname())!=NULL) {
        printf("%s\n",p);
        return 0;
    }
    else {
        perror("ctermname() failed");
        return 1;
    }

Quote:}

#endif
======================= cut here =======================

--

 
 
 

1. >/dev/msglog 2<>/dev/msglog </dev/console

In inittab, some entry is entitled with ">/dev/msglog 2<>/dev/msglog
</dev/console",  what is that used for? Why need it followed by the
standard entry?

Such as
Example--Default inittab File
The following example shows an annotated default inittab file:
 1 ap::sysinit:/sbin/autopush -f /etc/iu.ap
 2 ap::sysinit:/sbin/soconfig -f /etc/sock2path
 3 fs::sysinit:/sbin/rcS sysinit   >/dev/msglog 2<>/dev/msglog
</dev/console
 4 is:3:initdefault:
 5 p3:s1234:powerfail:/usr/sbin/shutdown -y -i5 -g0 >/dev/msglog
2<>/dev/...
 6 sS:s:wait:/sbin/rcS              >/dev/msglog 2<>/dev/msglog
</dev/console
 7 s0:0:wait:/sbin/rc0              >/dev/msglog 2<>/dev/msglog
</dev/console
 8 s1:1:respawn:/sbin/rc1           >/dev/msglog 2<>/dev/msglog
</dev/console
 9 s2:23:wait:/sbin/rc2             >/dev/msglog 2<>/dev/msglog
</dev/console
 10 s3:3:wait:/sbin/rc3             >/dev/msglog 2<>/dev/msglog
</dev/console
 11 s5:5:wait:/sbin/rc5             >/dev/msglog 2<>/dev/msglog
</dev/console
 12 s6:6:wait:/sbin/rc6             >/dev/msglog 2<>/dev/msglog
</dev/console
 13 fw:0:wait:/sbin/uadmin 2 0      >/dev/msglog 2<>/dev/msglog
</dev/console
 14 of:5:wait:/sbin/uadmin 2 6      >/dev/msglog 2<>/dev/msglog
</dev/console
 15 rb:6:wait:/sbin/uadmin 2 1      >/dev/msglog 2<>/dev/msglog
</dev/console
 16 sc:234:respawn:/usr/lib/saf/sac -t 300
 17 co:234:respawn:/usr/lib/saf/ttymon -g -h -p "`uname -n` console
login: "
    -T terminal-type -d /dev/console -l console -m ldterm,ttcompat  

in
http://docs.sun.com/db/doc/805-7228/6j6q7uepg?a=view

2. BAD TRAP type=9

3. multiple X-Servers?

4. diff between /dev/tty and /dev/pts

5. Automatic banner inserting in user pages

6. Wrong permissions for /dev/pts/0 and /dev/pts/1

7. catching background tasks id - QUESTION

8. Warning: dev (pts(136,0)) tty->count(5) != #fd's(4) in tty_open

9. <><><> MOUNTING EXTENDED PARTITION <><><>

10. Wanted: <><><> Unix Specialist <><><>

11. LILO help <><><><><><>

12. HELP: 2>&1 > /dev/null != 2>&- > /dev/null ???