(root)/
glibc-2.38/
stdio-common/
fxprintf.c
       1  /* Copyright (C) 2005-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <stdarg.h>
      19  #include <stdio.h>
      20  #include <stdlib.h>
      21  #include <string.h>
      22  #include <wchar.h>
      23  #include <libioP.h>
      24  
      25  static int
      26  locked_vfxprintf (FILE *fp, const char *fmt, va_list ap,
      27  		  unsigned int mode_flags)
      28  {
      29    if (_IO_fwide (fp, 0) <= 0)
      30      return __vfprintf_internal (fp, fmt, ap, mode_flags);
      31  
      32    /* We must convert the narrow format string to a wide one.
      33       Each byte can produce at most one wide character.  */
      34    wchar_t *wfmt;
      35    mbstate_t mbstate;
      36    int res;
      37    int used_malloc = 0;
      38    size_t len = strlen (fmt) + 1;
      39  
      40    if (__glibc_unlikely (len > SIZE_MAX / sizeof (wchar_t)))
      41      {
      42        __set_errno (EOVERFLOW);
      43        return -1;
      44      }
      45    if (__libc_use_alloca (len * sizeof (wchar_t)))
      46      wfmt = alloca (len * sizeof (wchar_t));
      47    else if ((wfmt = malloc (len * sizeof (wchar_t))) == NULL)
      48      return -1;
      49    else
      50      used_malloc = 1;
      51  
      52    memset (&mbstate, 0, sizeof mbstate);
      53    res = __mbsrtowcs (wfmt, &fmt, len, &mbstate);
      54  
      55    if (res != -1)
      56      res = __vfwprintf_internal (fp, wfmt, ap, mode_flags);
      57  
      58    if (used_malloc)
      59      free (wfmt);
      60  
      61    return res;
      62  }
      63  
      64  int
      65  __vfxprintf (FILE *fp, const char *fmt, va_list ap,
      66  	     unsigned int mode_flags)
      67  {
      68    if (fp == NULL)
      69      fp = stderr;
      70    _IO_flockfile (fp);
      71    int res = locked_vfxprintf (fp, fmt, ap, mode_flags);
      72    _IO_funlockfile (fp);
      73    return res;
      74  }
      75  
      76  int
      77  __fxprintf (FILE *fp, const char *fmt, ...)
      78  {
      79    va_list ap;
      80    va_start (ap, fmt);
      81    int res = __vfxprintf (fp, fmt, ap, 0);
      82    va_end (ap);
      83    return res;
      84  }
      85  
      86  int
      87  __fxprintf_nocancel (FILE *fp, const char *fmt, ...)
      88  {
      89    if (fp == NULL)
      90      fp = stderr;
      91  
      92    va_list ap;
      93    va_start (ap, fmt);
      94    _IO_flockfile (fp);
      95    int save_flags2 = fp->_flags2;
      96    fp->_flags2 |= _IO_FLAGS2_NOTCANCEL;
      97  
      98    int res = locked_vfxprintf (fp, fmt, ap, 0);
      99  
     100    fp->_flags2 = save_flags2;
     101    _IO_funlockfile (fp);
     102    va_end (ap);
     103    return res;
     104  }