Blame sysdeps/unix/getlogin_r.c

Packit Service 82fcde
/* Reentrant function to return the current login name.  Unix version.
Packit Service 82fcde
   Copyright (C) 1991-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <unistd.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <limits.h>
Packit Service 82fcde
#include <fcntl.h>
Packit Service 82fcde
Packit Service 82fcde
#include <utmp.h>
Packit Service 82fcde
#include "../login/utmp-private.h"
Packit Service 82fcde
Packit Service 82fcde
/* Return at most NAME_LEN characters of the login name of the user in NAME.
Packit Service 82fcde
   If it cannot be determined or some other error occurred, return the error
Packit Service 82fcde
   code.  Otherwise return 0.  */
Packit Service 82fcde
Packit Service 82fcde
#ifdef STATIC
Packit Service 82fcde
STATIC
Packit Service 82fcde
#endif
Packit Service 82fcde
int
Packit Service 82fcde
__getlogin_r (char *name, size_t name_len)
Packit Service 82fcde
{
Packit Service 82fcde
  char tty_pathname[2 + 2 * NAME_MAX];
Packit Service 82fcde
  char *real_tty_path = tty_pathname;
Packit Service 82fcde
  int result;
Packit Service 82fcde
  struct utmp *ut, line, buffer;
Packit Service 82fcde
Packit Service 82fcde
  /* Get name of tty connected to fd 0.  Return if not a tty or
Packit Service 82fcde
     if fd 0 isn't open.  Note that a lot of documentation says that
Packit Service 82fcde
     getlogin() is based on the controlling terminal---what they
Packit Service 82fcde
     really mean is "the terminal connected to standard input".  The
Packit Service 82fcde
     getlogin() implementation of DEC Unix, SunOS, Solaris, HP-UX all
Packit Service 82fcde
     return NULL if fd 0 has been closed, so this is the compatible
Packit Service 82fcde
     thing to do.  Note that ttyname(open("/dev/tty")) on those
Packit Service 82fcde
     systems returns /dev/tty, so that is not a possible solution for
Packit Service 82fcde
     getlogin().  */
Packit Service 82fcde
Packit Service 82fcde
  result = __ttyname_r (0, real_tty_path, sizeof (tty_pathname));
Packit Service 82fcde
Packit Service 82fcde
  if (result != 0)
Packit Service 82fcde
    return result;
Packit Service 82fcde
Packit Service 82fcde
  real_tty_path += 5;		/* Remove "/dev/".  */
Packit Service 82fcde
  strncpy (line.ut_line, real_tty_path, sizeof line.ut_line);
Packit Service 82fcde
Packit Service 82fcde
  /* We don't use the normal entry points __setutent et al, because we
Packit Service 82fcde
     want setutent + getutline_r + endutent all to happen with the lock
Packit Service 82fcde
     held so that our search is thread-safe.  */
Packit Service 82fcde
Packit Service 82fcde
  __libc_lock_lock (__libc_utmp_lock);
Packit Service 1c5418
  (*__libc_utmp_jump_table->setutent) ();
Packit Service 1c5418
  result = (*__libc_utmp_jump_table->getutline_r) (&line, &buffer, &ut);
Packit Service 82fcde
  if (result < 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (errno == ESRCH)
Packit Service 82fcde
	/* The caller expects ENOENT if nothing is found.  */
Packit Service 82fcde
	result = ENOENT;
Packit Service 82fcde
      else
Packit Service 82fcde
	result = errno;
Packit Service 82fcde
    }
Packit Service 1c5418
  (*__libc_utmp_jump_table->endutent) ();
Packit Service 1c5418
  __libc_utmp_jump_table = &__libc_utmp_unknown_functions;
Packit Service 82fcde
  __libc_lock_unlock (__libc_utmp_lock);
Packit Service 82fcde
Packit Service 82fcde
  if (result == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      size_t needed = __strnlen (ut->ut_user, UT_NAMESIZE) + 1;
Packit Service 82fcde
Packit Service 82fcde
      if (needed > name_len)
Packit Service 82fcde
	{
Packit Service 82fcde
	  __set_errno (ERANGE);
Packit Service 82fcde
	  result = ERANGE;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  memcpy (name, ut->ut_user, needed - 1);
Packit Service 82fcde
	  name[needed - 1] = 0;
Packit Service 82fcde
	  result = 0;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
#ifndef STATIC
Packit Service 82fcde
libc_hidden_def (__getlogin_r)
Packit Service 82fcde
weak_alias (__getlogin_r, getlogin_r)
Packit Service 82fcde
libc_hidden_weak (getlogin_r)
Packit Service 82fcde
#endif