Back to index

glibc  2.9
obprintf_chk.c
Go to the documentation of this file.
00001 /* Print output of stream to given obstack.
00002    Copyright (C) 1996,1997,1999,2000,2001,2002,2003,2004,2005,2006,2008
00003        Free Software Foundation, Inc.
00004    This file is part of the GNU C Library.
00005    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
00006 
00007    The GNU C Library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public
00009    License as published by the Free Software Foundation; either
00010    version 2.1 of the License, or (at your option) any later version.
00011 
00012    The GNU C Library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Lesser General Public License for more details.
00016 
00017    You should have received a copy of the GNU Lesser General Public
00018    License along with the GNU C Library; if not, write to the Free
00019    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00020    02111-1307 USA.  */
00021 
00022 
00023 #include <stdlib.h>
00024 #include <libioP.h>
00025 #include "../libio/strfile.h"
00026 #include <assert.h>
00027 #include <string.h>
00028 #include <errno.h>
00029 #include <obstack.h>
00030 #include <stdarg.h>
00031 #include <stdio_ext.h>
00032 
00033 
00034 struct _IO_obstack_file
00035 {
00036   struct _IO_FILE_plus file;
00037   struct obstack *obstack;
00038 };
00039 
00040 extern const struct _IO_jump_t _IO_obstack_jumps attribute_hidden;
00041 
00042 int
00043 __obstack_vprintf_chk (struct obstack *obstack, int flags, const char *format,
00044                      va_list args)
00045 {
00046   struct obstack_FILE
00047     {
00048       struct _IO_obstack_file ofile;
00049     } new_f;
00050   int result;
00051   int size;
00052   int room;
00053 
00054 #ifdef _IO_MTSAFE_IO
00055   new_f.ofile.file.file._lock = NULL;
00056 #endif
00057 
00058   _IO_no_init (&new_f.ofile.file.file, _IO_USER_LOCK, -1, NULL, NULL);
00059   _IO_JUMPS (&new_f.ofile.file) = &_IO_obstack_jumps;
00060   room = obstack_room (obstack);
00061   size = obstack_object_size (obstack) + room;
00062   if (size == 0)
00063     {
00064       /* We have to handle the allocation a bit different since the
00065         `_IO_str_init_static' function would handle a size of zero
00066         different from what we expect.  */
00067 
00068       /* Get more memory.  */
00069       obstack_make_room (obstack, 64);
00070 
00071       /* Recompute how much room we have.  */
00072       room = obstack_room (obstack);
00073       size = room;
00074 
00075       assert (size != 0);
00076     }
00077 
00078   _IO_str_init_static_internal ((struct _IO_strfile_ *) &new_f.ofile,
00079                             obstack_base (obstack),
00080                             size, obstack_next_free (obstack));
00081   /* Now allocate the rest of the current chunk.  */
00082   assert (size == (new_f.ofile.file.file._IO_write_end
00083                  - new_f.ofile.file.file._IO_write_base));
00084   assert (new_f.ofile.file.file._IO_write_ptr
00085          == (new_f.ofile.file.file._IO_write_base
00086              + obstack_object_size (obstack)));
00087   obstack_blank_fast (obstack, room);
00088 
00089   new_f.ofile.obstack = obstack;
00090 
00091   /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n
00092      can only come from read-only format strings.  */
00093   if (flags > 0)
00094     new_f.ofile.file.file._flags2 |= _IO_FLAGS2_FORTIFY;
00095 
00096   result = INTUSE(_IO_vfprintf) (&new_f.ofile.file.file, format, args);
00097 
00098   /* Shrink the buffer to the space we really currently need.  */
00099   obstack_blank_fast (obstack, (new_f.ofile.file.file._IO_write_ptr
00100                             - new_f.ofile.file.file._IO_write_end));
00101 
00102   return result;
00103 }
00104 libc_hidden_def (__obstack_vprintf_chk)
00105 
00106 
00107 int
00108 __obstack_printf_chk (struct obstack *obstack, int flags, const char *format,
00109                     ...)
00110 {
00111   int result;
00112   va_list ap;
00113   va_start (ap, format);
00114   result = __obstack_vprintf_chk (obstack, flags, format, ap);
00115   va_end (ap);
00116   return result;
00117 }