Back to index

glibc  2.9
stpncpy_chk.c
Go to the documentation of this file.
00001 /* Copyright (C) 1993,1995,1996,1997,2002,2005 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 /* This is almost copied from strncpy.c, written by Torbjorn Granlund.  */
00020 
00021 #include <string.h>
00022 
00023 
00024 /* Copy no more than N characters of SRC to DEST, returning the address of
00025    the terminating '\0' in DEST, if any, or else DEST + N.  */
00026 char *
00027 __stpncpy_chk (char *dest, const char *src, size_t n, size_t destlen)
00028 {
00029   char c;
00030   char *s = dest;
00031 
00032   if (__builtin_expect (destlen < n, 0))
00033     __chk_fail ();
00034 
00035   if (n >= 4)
00036     {
00037       size_t n4 = n >> 2;
00038 
00039       for (;;)
00040        {
00041          c = *src++;
00042          *dest++ = c;
00043          if (c == '\0')
00044            break;
00045          c = *src++;
00046          *dest++ = c;
00047          if (c == '\0')
00048            break;
00049          c = *src++;
00050          *dest++ = c;
00051          if (c == '\0')
00052            break;
00053          c = *src++;
00054          *dest++ = c;
00055          if (c == '\0')
00056            break;
00057          if (--n4 == 0)
00058            goto last_chars;
00059        }
00060       n -= dest - s;
00061       goto zero_fill;
00062     }
00063 
00064  last_chars:
00065   n &= 3;
00066   if (n == 0)
00067     return dest;
00068 
00069   for (;;)
00070     {
00071       c = *src++;
00072       --n;
00073       *dest++ = c;
00074       if (c == '\0')
00075        break;
00076       if (n == 0)
00077        return dest;
00078     }
00079 
00080  zero_fill:
00081   while (n-- > 0)
00082     dest[n] = '\0';
00083 
00084   return dest - 1;
00085 }