diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Src/compat.c | 74 | ||||
-rw-r--r-- | Src/init.c | 8 | ||||
-rw-r--r-- | Src/system.h | 20 | ||||
-rw-r--r-- | configure.in | 3 |
5 files changed, 108 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog index 435540f2e..102dd5888 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2000-09-16 Clint Adams <schizo@debian.org> + + * 12814: configure.in, Src/compat.c, Src/init.c, Src/system.h: + implement zasprintf and use it in lieu of sprintf with a + static buffer in sourcehome(). + 2000-09-15 Bart Schaefer <schaefer@zsh.org> * unposted: Doc/Zsh/contrib.yo: Missing hunk from 12765 (replace diff --git a/Src/compat.c b/Src/compat.c index 8cfb8a3a5..0c7009b5f 100644 --- a/Src/compat.c +++ b/Src/compat.c @@ -407,6 +407,80 @@ zchdir(char *dir) #endif } +#ifndef HAVE_ASPRINTF +/**/ +# ifndef USE_VARARGS +/**/ +mod_export int +zasprintf(char **strp, const char *format, int arg1, int arg2) +{ + char *buf; + + buf = (char *)zalloc(PATH_MAX); + + snprintf(buf, PATH_MAX, format, arg1, arg2); + *strp = buf; + return strlen(buf); +} + +/**/ +# else + +/**/ +# ifdef PREFER_STDARG + +/**/ +mod_export int +zasprintf(char **strp, const char *format, ...) +{ + +/**/ +# else + +/**/ +# if __GNUC__ > 1 +/* Doing this the "right way" will effect a broken compat.epro file. * + * This kludge should work with gcc2 until a better solution is available */ + +/**/ +mod_export int +zasprintf(char **strp, const char *format, __builtin_va_alist_t __builtin_va_alist, __va_ellipsis) +{ + +/**/ +# else +# error varargs prototyping kludge failed +/**/ +# endif + +/**/ +# endif + va_list arg; + + char *buf; + + buf = (char *)zalloc(PATH_MAX); + +# ifdef PREFER_STDARG + va_start(arg, format); +# else + va_start(arg); +# endif + +#ifdef HAVE_VSNPRINTF + vsnprintf(buf, PATH_MAX, format, arg); +#else +#error You have varargs but no vsnprintf +#endif + va_end (arg); + + *strp = buf; + return strlen(buf); +} +/**/ +# endif +#endif + /* * How to print out a 64 bit integer. This isn't needed (1) if longs * are 64 bit, since ordinary %ld will work (2) if we couldn't find a diff --git a/Src/init.c b/Src/init.c index e3e8f734e..0c82e47ef 100644 --- a/Src/init.c +++ b/Src/init.c @@ -1020,18 +1020,22 @@ source(char *s) void sourcehome(char *s) { - char buf[PATH_MAX]; + char *buf; char *h; if (emulation == EMULATE_SH || emulation == EMULATE_KSH || !(h = getsparam("ZDOTDIR"))) h = home; +/* Let source() complain if it's too long */ +#if 0 if (strlen(h) + strlen(s) + 1 >= PATH_MAX) { zerr("path too long: %s", s, 0); return; } - sprintf(buf, "%s/%s", h, s); +#endif + zasprintf(&buf, "%s/%s", h, s); source(buf); + zsfree(buf); } /**/ diff --git a/Src/system.h b/Src/system.h index 93e82a728..fc85efdb4 100644 --- a/Src/system.h +++ b/Src/system.h @@ -227,6 +227,26 @@ struct timezone { # define zopenmax() ((long) OPEN_MAX) #endif +#if defined (__STDC__) && defined (HAVE_STDARG_H) +# define PREFER_STDARG +# define USE_VARARGS +# include <stdarg.h> +#else +# ifdef HAVE_VARARGS_H +# define PREFER_VARARGS +# define USE_VARARGS +# include <varargs.h> +# endif +#endif + +#ifdef HAVE_ASPRINTF +# ifdef __GNUC__ +# define zasprintf(X,F,A...) asprintf(X,F, ## A) +# else +# define zasprintf asprintf +# endif +#endif + #ifdef HAVE_FCNTL_H # include <fcntl.h> #else diff --git a/configure.in b/configure.in index fa268707f..09592640b 100644 --- a/configure.in +++ b/configure.in @@ -451,7 +451,7 @@ AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \ limits.h fcntl.h libc.h sys/utsname.h sys/resource.h \ locale.h errno.h stdlib.h unistd.h sys/capability.h \ utmp.h utmpx.h sys/types.h pwd.h grp.h poll.h sys/mman.h \ - linux/tasks.h netinet/in_systm.h) + linux/tasks.h netinet/in_systm.h stdarg.h varargs.h) if test $dynamic = yes; then AC_CHECK_HEADERS(dlfcn.h) AC_CHECK_HEADERS(dl.h) @@ -860,6 +860,7 @@ AC_CHECK_FUNCS(strftime difftime gettimeofday \ initgroups nis_list \ setuid seteuid setreuid setresuid setsid \ memcpy memmove strstr strerror \ + snprintf vsnprintf asprintf \ cap_get_proc \ getrlimit \ setlocale \ |