(linenum→info "unix/slp.c:2238")

glibc/2.7/login/login.c

    1: /* Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
    2:    This file is part of the GNU C Library.
    3:    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
    4: 
    5:    The GNU C Library is free software; you can redistribute it and/or
    6:    modify it under the terms of the GNU Lesser General Public
    7:    License as published by the Free Software Foundation; either
    8:    version 2.1 of the License, or (at your option) any later version.
    9: 
   10:    The GNU C Library is distributed in the hope that it will be useful,
   11:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13:    Lesser General Public License for more details.
   14: 
   15:    You should have received a copy of the GNU Lesser General Public
   16:    License along with the GNU C Library; if not, write to the Free
   17:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   18:    02111-1307 USA.  */
   19: 
   20: #include <assert.h>
   21: #include <errno.h>
   22: #include <limits.h>
   23: #include <string.h>
   24: #include <unistd.h>
   25: #include <stdlib.h>
   26: #include <utmp.h>
   27: 
   28: 
   29: /* Return the result of ttyname in the buffer pointed to by TTY, which should
   30:    be of length BUF_LEN.  If it is too long to fit in this buffer, a
   31:    sufficiently long buffer is allocated using malloc, and returned in TTY.
   32:    0 is returned upon success, -1 otherwise.  */
   33: static int
   34: tty_name (int fd, char **tty, size_t buf_len)
   35: {
   36:   int rv;                       /* Return value.  0 = success.  */
   37:   char *buf = *tty;             /* Buffer for ttyname, initially the user's. */
   38: 
   39:   for (;;)
   40:     {
   41:       char *new_buf;
   42: 
   43:       if (buf_len)
   44:         {
   45:           rv = ttyname_r (fd, buf, buf_len);
   46: 
   47:           if (rv != 0 || memchr (buf, '\0', buf_len))
   48:             /* We either got an error, or we succeeded and the
   49:                returned name fit in the buffer.  */
   50:             break;
   51: 
   52:           /* Try again with a longer buffer.  */
   53:           buf_len += buf_len;  /* Double it */
   54:         }
   55:       else
   56:         /* No initial buffer; start out by mallocing one.  */
   57:         buf_len = 128;         /* First time guess.  */
   58: 
   59:       if (buf != *tty)
   60:         /* We've already malloced another buffer at least once.  */
   61:         new_buf = realloc (buf, buf_len);
   62:       else
   63:         new_buf = malloc (buf_len);
   64:       if (! new_buf)
   65:         {
   66:           rv = -1;
   67:           __set_errno (ENOMEM);
   68:           break;
   69:         }
   70:       buf = new_buf;
   71:     }
   72: 
   73:   if (rv == 0)
   74:     *tty = buf;         /* Return buffer to the user.  */
   75:   else if (buf != *tty)
   76:     free (buf);         /* Free what we malloced when returning an error.  */
   77: 
   78:   return rv;
   79: }
   80: ^L
   81: void
   82: login (const struct utmp *ut)
   83: {
   84: #ifdef PATH_MAX
   85:   char _tty[PATH_MAX + UT_LINESIZE];
   86: #else
   87:   char _tty[512 + UT_LINESIZE];
   88: #endif
   89:   char *tty = _tty;
   90:   int found_tty;
   91:   const char *ttyp;
   92:   struct utmp copy = *ut;
   93: 
   94:   /* Fill in those fields we supply.  */
   95: #if _HAVE_UT_TYPE - 0
   96:   copy.ut_type = USER_PROCESS;
   97: #endif
   98: #if _HAVE_UT_PID - 0
   99:   copy.ut_pid = getpid ();
  100: #endif
  101: 
  102:   /* Seek tty.  */
  103:   found_tty = tty_name (STDIN_FILENO, &tty, sizeof (_tty));
  104:   if (found_tty < 0)
  105:     found_tty = tty_name (STDOUT_FILENO, &tty, sizeof (_tty));
  106:   if (found_tty < 0)
  107:     found_tty = tty_name (STDERR_FILENO, &tty, sizeof (_tty));
  108: 
  109:   if (found_tty >= 0)
  110:     {
  111:       /* We only want to insert the name of the tty without path.
  112:          But take care of name like /dev/pts/3.  */
  113:       if (strncmp (tty, "/dev/", 5) == 0)
  114:         ttyp = tty + 5;                /* Skip the "/dev/".  */
  115:       else
  116:         ttyp = basename (tty);
  117: 
  118:       /* Position to record for this tty.  */
  119:       strncpy (copy.ut_line, ttyp, UT_LINESIZE);
  120: 
  121:       /* Tell that we want to use the UTMP file.  */
  122:       if (utmpname (_PATH_UTMP) == 0)
  123:         {
  124:           /* Open UTMP file.  */
  125:           setutent ();
  126: 
  127:           /* Write the entry.  */
  128:           pututline (&copy);
  129: 
  130:           /* Close UTMP file.  */
  131:           endutent ();
  132:         }
  133: 
  134:       if (tty != _tty)
  135:         free (tty);            /* Free buffer malloced by tty_name.  */
  136:     }
  137:   else
  138:     /* We provide a default value so that the output does not contain
  139:        an random bytes in this field.  */
  140:     strncpy (copy.ut_line, "???", UT_LINESIZE);
  141: 
  142:   /* Update the WTMP file.  Here we have to add a new entry.  */
  143:   updwtmp (_PATH_WTMP, &copy);
  144: }
Syntax (Markdown)