From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8431 invoked from network); 16 Sep 2000 18:54:41 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 16 Sep 2000 18:54:41 -0000 Received: (qmail 29556 invoked by alias); 16 Sep 2000 18:53:41 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 12814 Received: (qmail 29531 invoked from network); 16 Sep 2000 18:53:40 -0000 Date: Sat, 16 Sep 2000 14:53:33 -0400 From: Clint Adams To: zsh-workers@sunsite.auc.dk Subject: PATCH: zasprintf Message-ID: <20000916145333.A29559@dman.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii User-Agent: Mutt/1.1.2i In continuation of the crusade against PATH_MAX, this implements zasprintf. It will break on systems where there is a stdarg or varargs implementation but neither asprintf nor vsnprintf. I'd bet that on such a system there would be a vsprintf(), so the fix would be to write a compatibility function or merely abandon vsnprintf in favor of vsprintf. More important is that it will probably break where there exists varargs but no stdarg, and the compiler is not gcc2. Either gcc needs to be fixed, kludges found for other compilers, or makepro.awk needs some tweaking to handle this special case. zasprintf() is currently only used in one instance to minimize potential breakage. Index: configure.in =================================================================== RCS file: /cvsroot/zsh/zsh/configure.in,v retrieving revision 1.30 diff -u -r1.30 configure.in --- configure.in 2000/09/06 15:50:16 1.30 +++ configure.in 2000/09/16 18:30:01 @@ -451,7 +451,7 @@ 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 @@ initgroups nis_list \ setuid seteuid setreuid setresuid setsid \ memcpy memmove strstr strerror \ + snprintf vsnprintf asprintf \ cap_get_proc \ getrlimit \ setlocale \ Index: Src/compat.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/compat.c,v retrieving revision 1.7 diff -u -r1.7 compat.c --- Src/compat.c 2000/08/14 07:30:28 1.7 +++ Src/compat.c 2000/09/16 18:30:04 @@ -407,6 +407,80 @@ #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 Index: Src/init.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/init.c,v retrieving revision 1.11 diff -u -r1.11 init.c --- Src/init.c 2000/08/08 14:57:03 1.11 +++ Src/init.c 2000/09/16 18:30:07 @@ -1020,18 +1020,22 @@ 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); } /**/ Index: Src/system.h =================================================================== RCS file: /cvsroot/zsh/zsh/Src/system.h,v retrieving revision 1.8 diff -u -r1.8 system.h --- Src/system.h 2000/09/08 12:51:11 1.8 +++ Src/system.h 2000/09/16 18:30:08 @@ -227,6 +227,26 @@ # define zopenmax() ((long) OPEN_MAX) #endif +#if defined (__STDC__) && defined (HAVE_STDARG_H) +# define PREFER_STDARG +# define USE_VARARGS +# include +#else +# ifdef HAVE_VARARGS_H +# define PREFER_VARARGS +# define USE_VARARGS +# include +# 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 #else