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

Ask a Question related to Sun Solaris, Design and Development.

  1. #1

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

    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
    Uwe Wolfram Guest

  2. Similar Questions and Discussions

    1. int Number to text Number Function / UDF ?
      Is there a function that converts e.g. 3 to Three? Probably not but I just thought I'd ask.
    2. Number to hex ?
      Looking at a few scripts, too disguise ID numbers or make them random, there appears to be a conversion to an alphanumeric number. e.g....
    3. sort from the smallest number to the highest number
      Hi Just say I want to sort the row by using the fifth column data as reference from the smallest the largest number, if using sort, It will give...
    4. sh: bad number
      Hi, I compiled a simple program with perl. But I ran into some problems. sh: campusUnderAttack.out: bad number I try to execute a program and...
    5. Number formatting?
      Any convenient ways (without rolling my own) of formatting numbers to include thousands separators, e.g. 1199123 printed as "1,199,123" --...
  3. #2

    Default Re: tty-dev-number <-> /dev/pts

    Richard L. Hamilton wrote:
    > > 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
    Uwe Wolfram Guest

  4. #3

    Default Re: tty-dev-number <-> /dev/pts

    In article <20030711203016.37dba3ac.u.wolfram@dummy.freenet.d e>,
    Uwe Wolfram <u.wolfram@duMMy.freenet.de> writes:
    > Richard L. Hamilton wrote:
    >> > 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;
    }

    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);
    }

    /* 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;
    }

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

    #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;
    }
    }
    #endif


    --
    mailto:rlhamil@mindwarp.smart.net [url]http://www.smart.net/~rlhamil[/url]
    Richard L. Hamilton Guest

  5. #4

    Default Re: tty-dev-number <-> /dev/pts

    Richard L. Hamilton wrote:
    > 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.
    > 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
    Uwe Wolfram Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139