[Freeciv-Dev] patch: provide snprintf
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
This patch provides (v)snprintf functions to freeciv for platforms
where these functions are missing. The implementation is by
Theo de Raadt, via gnome-libs/support. I haven't really tested
it beyond checking that it complies and runs (including if I edit
config.h; systems I have access to already have these functions).
For minimal testing, this patch replaces vsprintf with vsnprintf
in freelog().
Incidently, I think I am right in saying that these functions do
not guarantee null-termination if the printf would have written
more than n chars. So should probably either null-terminate
explicitly or if using a static array, use (n-1).
I've made configure check individually for both snprintf and
vsnprintf, which may be overkill (if have one have both?) but
shouldn't hurt...
I have not yet tackled also providing (v)asprintf (a malloc-ing
version). That would be possible in a similar fashion, but lets
do this one step at a time...
A select-based usleep() replacement should be similar and easy.
Regards,
-- David
diff -N -u -r --exclude-from exclude freeciv-cvs/common/Makefile.am
fc-adv/common/Makefile.am
--- freeciv-cvs/common/Makefile.am Mon May 10 18:28:30 1999
+++ fc-adv/common/Makefile.am Sat May 29 18:17:17 1999
@@ -35,7 +35,10 @@
shared.h \
spaceship.c \
spaceship.h \
+ support.h \
tech.c \
tech.h \
unit.c \
- unit.h
+ unit.h \
+ vsnprintf.c
+
diff -N -u -r --exclude-from exclude freeciv-cvs/common/Makefile.in
fc-adv/common/Makefile.in
--- freeciv-cvs/common/Makefile.in Mon May 10 18:28:30 1999
+++ fc-adv/common/Makefile.in Sat May 29 18:18:49 1999
@@ -115,10 +115,12 @@
shared.h \
spaceship.c \
spaceship.h \
+ support.h \
tech.c \
tech.h \
unit.c \
- unit.h
+ unit.h \
+ vsnprintf.c
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
@@ -136,7 +138,7 @@
libcivcommon_a_LIBADD =
libcivcommon_a_OBJECTS = capability.o city.o diptreaty.o game.o \
genlist.o log.o map.o packets.o player.o mem.o registry.o sbuffer.o \
-shared.o spaceship.o tech.o unit.o
+shared.o spaceship.o tech.o unit.o vsnprintf.o
AR = ar
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
@@ -151,7 +153,8 @@
DEP_FILES = .deps/capability.P .deps/city.P .deps/diptreaty.P \
.deps/game.P .deps/genlist.P .deps/log.P .deps/map.P .deps/mem.P \
.deps/packets.P .deps/player.P .deps/registry.P .deps/sbuffer.P \
-.deps/shared.P .deps/spaceship.P .deps/tech.P .deps/unit.P
+.deps/shared.P .deps/spaceship.P .deps/tech.P .deps/unit.P \
+.deps/vsnprintf.P
SOURCES = $(libcivcommon_a_SOURCES)
OBJECTS = $(libcivcommon_a_OBJECTS)
diff -N -u -r --exclude-from exclude freeciv-cvs/common/log.c
fc-adv/common/log.c
--- freeciv-cvs/common/log.c Tue Apr 27 22:13:07 1999
+++ fc-adv/common/log.c Sat May 29 18:21:37 1999
@@ -14,7 +14,8 @@
#include <stdarg.h>
#include <string.h>
-#include <log.h>
+#include "log.h"
+#include "support.h" /* vsnprintf */
int log_level;
char *log_filename;
@@ -87,7 +88,7 @@
else fs=stderr;
va_start(args, message);
- vsprintf(bufbuf[whichbuf], message, args);
+ vsnprintf(bufbuf[whichbuf], 511, message, args);
va_end(args);
if(level==prev_level && 0==strncmp(bufbuf[0],bufbuf[1],511)){
Binary files freeciv-cvs/common/stzPLKop and fc-adv/common/stzPLKop differ
diff -N -u -r --exclude-from exclude freeciv-cvs/common/support.h
fc-adv/common/support.h
--- freeciv-cvs/common/support.h Thu Jan 1 10:00:00 1970
+++ fc-adv/common/support.h Sat May 29 18:37:33 1999
@@ -0,0 +1,49 @@
+/**********************************************************************
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+***********************************************************************/
+#ifndef FC__SUPPORT_H
+#define FC__SUPPORT_H
+
+/* This "support" module is intended for functions which may be
+ in libc, for which we provide implementations for systems where
+ they are missing. This file "support.h" provides prototypes
+ for such functions. Note that function bodies may be provided
+ in files other than "support.c", because they typically come
+ from outside Freeciv, so this is easier for noting copyrights,
+ keeping them up-to-date, etc. (--dwp)
+*/
+
+/* Need to know what functions they system already provides: */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stddef.h> /* size_t */
+
+#ifndef HAVE_VSNPRINTF
+#include <stdarg.h>
+#endif
+
+/* snprintf() and vsnprintf(), bodies in vsnprintf.c:
+ Like sprintf() and vsprintf(), but write at most n characters.
+ Note these do not guarantee null-termination if the maximum
+ number of chars get written! (?)
+*/
+#ifndef HAVE_VSNPRINTF
+int vsnprintf(char *str, size_t n, const char *format, va_list ap );
+#endif
+#ifndef HAVE_SNPRINTF
+int snprintf(char *str, size_t n, const char *format, ... );
+#endif
+
+#endif /* FC__SUPPORT_H */
+
diff -N -u -r --exclude-from exclude freeciv-cvs/common/vsnprintf.c
fc-adv/common/vsnprintf.c
--- freeciv-cvs/common/vsnprintf.c Thu Jan 1 10:00:00 1970
+++ fc-adv/common/vsnprintf.c Sat May 29 18:49:13 1999
@@ -0,0 +1,209 @@
+/*
+ * Revision 12: http://theos.com/~deraadt/snprintf.c
+ *
+ * Copyright (c) 1997 Theo de Raadt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Freeciv:
+ This version taken from gnome-libs-1.0.9/support/vsnprintf.c
+ Relevant entries from gnome-libs-1.0.9/support/ChangeLog:
+
+1998-05-19 Martin Baulig <martin@xxxxxxxxxxxxxxxxx>
+
+ * vsnprintf.c (vsnprintf): Changed declaration of this
+ function on systems defining __STDC__ to avoid clash
+ with prototype in system header file.
+
+ * vsnprintf.c (snprintf): Moved toward the end of the
+ file, so that the compiler sees correct declaration for
+ vsnprintf().
+
+1998-03-11 Raja R Harinath <harinath@xxxxxxxxxx>
+
+ * vsnprintf.c: Actually fill it in. It is from
+ <URL:http://theos.com/~deraadt/snprintf.c>, with one small fix to
+ actually make it compile.
+
+ Changes for Freeciv: use HAVE_CONFIG_ symbols from config.h
+ for conditional compilation.
+ Added unistd.h, string.h
+ static var "caught" was unused.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if (!defined(HAVE_VSNPRINTF)) || (!defined(HAVE_SNPRINTF))
+/* else don't compile anything */
+
+#ifdef HAVE_VSNPRINTF
+
+/* Only protos needed by snprintf in terms of vsnprintf: */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#include <stdlib.h>
+#else
+#include <varargs.h>
+#endif
+
+#else
+
+/* Everything for vsnprintf: */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#include <stdlib.h>
+#else
+#include <varargs.h>
+#endif
+#include <setjmp.h>
+#include <unistd.h> /* getpagesize() */
+#include <string.h> /* strncpy() */
+
+#ifndef roundup
+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
+#endif
+
+static int pgsize;
+static char *curobj;
+/* static int caught; */
+static sigjmp_buf bail;
+
+#define EXTRABYTES 2 /* XXX: why 2? you don't want to know */
+
+static char *
+msetup(str, n)
+ char *str;
+ size_t n;
+{
+ char *e;
+
+ if (n == 0)
+ return NULL;
+ if (pgsize == 0)
+ pgsize = getpagesize();
+ curobj = (char *)malloc(n + EXTRABYTES + pgsize * 2);
+ if (curobj == NULL)
+ return NULL;
+ e = curobj + n + EXTRABYTES;
+ e = (char *)roundup((unsigned long)e, pgsize);
+ if (mprotect(e, pgsize, PROT_NONE) == -1) {
+ free(curobj);
+ curobj = NULL;
+ return NULL;
+ }
+ e = e - n - EXTRABYTES;
+ *e = '\0';
+ return (e);
+}
+
+static void
+mcatch()
+{
+ siglongjmp(bail, 1);
+}
+
+static void
+mcleanup(str, n, p)
+ char *str;
+ size_t n;
+ char *p;
+{
+ strncpy(str, p, n-1);
+ str[n-1] = '\0';
+ if (mprotect((caddr_t)(p + n + EXTRABYTES), pgsize,
+ PROT_READ|PROT_WRITE|PROT_EXEC) == -1)
+ mprotect((caddr_t)(p + n + EXTRABYTES), pgsize,
+ PROT_READ|PROT_WRITE);
+ free(curobj);
+}
+
+int
+#if __STDC__
+vsnprintf(char *str, size_t n, char const *fmt, va_list ap)
+#else
+vsnprintf(str, n, fmt, ap)
+ char *str;
+ size_t n;
+ char *fmt;
+ char *ap;
+#endif
+{
+ struct sigaction osa, nsa;
+ char *p;
+ int ret = n + 1; /* if we bail, indicated we overflowed */
+
+ memset(&nsa, 0, sizeof nsa);
+ nsa.sa_handler = mcatch;
+ sigemptyset(&nsa.sa_mask);
+
+ p = msetup(str, n);
+ if (p == NULL) {
+ *str = '\0';
+ return 0;
+ }
+ if (sigsetjmp(bail, 1) == 0) {
+ if (sigaction(SIGSEGV, &nsa, &osa) == -1) {
+ mcleanup(str, n, p);
+ return (0);
+ }
+ ret = vsprintf(p, fmt, ap);
+ }
+ mcleanup(str, n, p);
+ (void) sigaction(SIGSEGV, &osa, NULL);
+ return (ret);
+}
+#endif /* !HAVE_VSNPRINTF */
+
+#ifndef HAVE_SNPRINTF
+int
+#if __STDC__
+snprintf(char *str, size_t n, char const *fmt, ...)
+#else
+snprintf(str, n, fmt, va_alist)
+ char *str;
+ size_t n;
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+
+ return (vsnprintf(str, n, fmt, ap));
+ va_end(ap);
+}
+#endif /* HAVE_SNPRINTF */
+
+#endif /* (!defined(HAVE_VSNPRINTF)) || (!defined(HAVE_SNPRINTF)) */
diff -N -u -r --exclude-from exclude freeciv-cvs/config.h.in fc-adv/config.h.in
--- freeciv-cvs/config.h.in Sun Mar 14 11:23:59 1999
+++ fc-adv/config.h.in Sat May 29 18:18:57 1999
@@ -52,11 +52,17 @@
/* Define if you have the select function. */
#undef HAVE_SELECT
+/* Define if you have the snprintf function. */
+#undef HAVE_SNPRINTF
+
/* Define if you have the strerror function. */
#undef HAVE_STRERROR
/* Define if you have the strstr function. */
#undef HAVE_STRSTR
+
+/* Define if you have the vsnprintf function. */
+#undef HAVE_VSNPRINTF
/* Define if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
diff -N -u -r --exclude-from exclude freeciv-cvs/configure fc-adv/configure
--- freeciv-cvs/configure Sat May 22 14:39:35 1999
+++ fc-adv/configure Sat May 29 18:18:59 1999
@@ -3780,7 +3780,7 @@
fi
-for ac_func in gethostname select strerror strstr
+for ac_func in gethostname select strerror strstr snprintf vsnprintf
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3787: checking for $ac_func" >&5
diff -N -u -r --exclude-from exclude freeciv-cvs/configure.in
fc-adv/configure.in
--- freeciv-cvs/configure.in Sat May 22 14:39:35 1999
+++ fc-adv/configure.in Sat May 29 18:17:43 1999
@@ -234,7 +234,7 @@
dnl Checks for library functions.
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
-AC_CHECK_FUNCS(gethostname select strerror strstr)
+AC_CHECK_FUNCS(gethostname select strerror strstr snprintf vsnprintf)
dnl autoscan also recommends gettimeofday in AC_CHECK_FUNCS, but in the code
dnl that is already protected by ifdef CHRONO, and is for selective
- [Freeciv-Dev] patch: provide snprintf,
David Pfitzner <=
|
|