Blame stdio-common/perror.c

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 <stdio.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <unistd.h>
Packit Service 82fcde
#include <wchar.h>
Packit Service 82fcde
#include "libioP.h"
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
perror_internal (FILE *fp, const char *s, int errnum)
Packit Service 82fcde
{
Packit Service 82fcde
  char buf[1024];
Packit Service 82fcde
  const char *colon;
Packit Service 82fcde
  const char *errstring;
Packit Service 82fcde
Packit Service 82fcde
  if (s == NULL || *s == '\0')
Packit Service 82fcde
    s = colon = "";
Packit Service 82fcde
  else
Packit Service 82fcde
    colon = ": ";
Packit Service 82fcde
Packit Service 82fcde
  errstring = __strerror_r (errnum, buf, sizeof buf);
Packit Service 82fcde
Packit Service 82fcde
  (void) __fxprintf (fp, "%s%s%s\n", s, colon, errstring);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Print a line on stderr consisting of the text in S, a colon, a space,
Packit Service 82fcde
   a message describing the meaning of the contents of `errno' and a newline.
Packit Service 82fcde
   If S is NULL or "", the colon and space are omitted.  */
Packit Service 82fcde
void
Packit Service 82fcde
perror (const char *s)
Packit Service 82fcde
{
Packit Service 82fcde
  int errnum = errno;
Packit Service 82fcde
  FILE *fp;
Packit Service 82fcde
  int fd = -1;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
  /* The standard says that 'perror' must not change the orientation
Packit Service 82fcde
     of the stream.  What is supposed to happen when the stream isn't
Packit Service 82fcde
     oriented yet?  In this case we'll create a new stream which is
Packit Service 82fcde
     using the same underlying file descriptor.  */
Packit Service 82fcde
  if (__builtin_expect (_IO_fwide (stderr, 0) != 0, 1)
Packit Service 82fcde
      || (fd = __fileno (stderr)) == -1
Packit Service 82fcde
      || (fd = __dup (fd)) == -1
Packit Service 82fcde
      || (fp = fdopen (fd, "w+")) == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (__glibc_unlikely (fd != -1))
Packit Service 82fcde
	__close (fd);
Packit Service 82fcde
Packit Service 82fcde
      /* Use standard error as is.  */
Packit Service 82fcde
      perror_internal (stderr, s, errnum);
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      /* We don't have to do any special hacks regarding the file
Packit Service 82fcde
	 position.  Since the stderr stream wasn't used so far we just
Packit Service 82fcde
	 write to the descriptor.  */
Packit Service 82fcde
      perror_internal (fp, s, errnum);
Packit Service 82fcde
Packit Service 82fcde
      if (_IO_ferror_unlocked (fp))
Packit Service 82fcde
	stderr->_flags |= _IO_ERR_SEEN;
Packit Service 82fcde
Packit Service 82fcde
      /* Close the stream.  */
Packit Service 82fcde
      fclose (fp);
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
libc_hidden_def (perror)