e2dc0e1235492fc929b214c2f51b9d7bec86ef68
[samba.git] / source3 / lib / slprintf.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    snprintf replacement
5    Copyright (C) Andrew Tridgell 1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26 int vslprintf(char *str, int n, char *format, va_list ap)
27 {
28 #ifdef HAVE_VSNPRINTF
29         int ret = vsnprintf(str, n, format, ap);
30         if (ret >= 0) str[ret] = 0;
31         return ret;
32 #else
33         static char *buf;
34         static int len;
35         static int pagesize;
36         int ret;
37
38         if (!len || !buf || (len-pagesize) < n) {
39                 pagesize = getpagesize();
40                 len = (2+(n/pagesize))*pagesize;
41                 /* note: we don't free the old memory (if any) as we don't 
42                    want a malloc lib to reuse the memory as it will
43                    have the wrong permissions */
44                 buf = memalign(pagesize, len);
45                 if (buf) {
46                         if (mprotect(buf+(len-pagesize), pagesize, PROT_READ) != 0) {
47                                 exit(1);
48                                 return -1;
49                         }
50                 }
51         }
52
53         if (!buf) {
54                 exit(1);
55         }
56
57         ret = vsprintf(str, format, ap);
58         /* we will have got a seg fault here if we overflowed the buffer */
59         return ret;
60 #endif
61 }
62
63 #ifdef __STDC__
64 int slprintf(char *str, int n, char *format, ...)
65 {
66 #else
67  int slprintf(va_alist)
68 va_dcl
69 {
70         char *str, *format;
71         int n;
72 #endif
73         va_list ap;  
74         int ret;
75
76 #ifdef __STDC__
77         va_start(ap, format);
78 #else
79         va_start(ap);
80         str = va_arg(ap,char *);
81         n = va_arg(ap,int);
82         format = va_arg(ap,char *);
83 #endif
84
85         ret = vslprintf(str,n,format,ap);
86         va_end(ap);
87         return ret;
88 }