Portability patches
Hi,
I've been working on a new build system (yeah, I know, *another* one) that aims to be highly portable to various POSIX systems and light on dependencies (in the spirit of autotools, though substantially less insane). Pure POSIX sh turned out to be robust enough for my project, but the various UNIX systems I've ported it to lack anything with dash's raw speed. Naturally, I just ported dash to them as well.
Patch stack incoming. I expect some of these might need further explanation or revision before being accepted.
Regards,
Brian Koropoff
PATCH 1/3 Port to Solaris
- Solaris lacks paths.h and the various _PATH_* #defines. Check for them in configure.ac and fall back on the usual suspects when they are missing.
- Older Solaris lacks isblank(), and versions that have it use a macro. Check for the declaration in configure.ac and fall back on a naive version when missing.
- Older Solaris does not support %jd (intmax_t) in format strings, but it does support %lld (long long), which is the same size on all architectures it supports. Do a configure check for the sizes of both and prefer %lld when it is safe to do so.
- Older Solaris lacks stdint.h, but inttypes.h provides the same types and works on all platforms I've tried dash on, so just use it instead.
- Older Solaris doesn't like it when vsnprintf() is passed a NULL buffer (in violation of the POSIX spec, of course). Pass a 1-byte dummy buffer instead.
- Solaris lacks tempfile and mktemp programs. Fall back on a "good-enough" custom function in mkbuiltins.
--- configure.ac | 36 +++++++++++++++++++++++++++++++++++- src/arith_yacc.c | 1 - src/bltin/test.c | 2 +- src/cd.c | 4 ++++ src/exec.c | 5 +++++ src/expand.c | 4 ++-- src/expand.h | 2 +- src/histedit.c | 5 +++++ src/jobs.c | 5 +++++ src/jobs.h | 2 +- src/miscbltin.c | 4 ++-- src/mkbuiltins | 15 +++++++++++++++ src/mystring.c | 2 +- src/mystring.h | 2 +- src/output.c | 14 ++++++++++++++ src/system.c | 8 ++++++++ src/system.h | 5 +++++ src/var.c | 7 ++++++- src/var.h | 2 +- 19 files changed, 112 insertions(+), 13 deletions(-)
configure.ac +35 -1
@@ -43,7 +43,41 @@ AC_ARG_ENABLE(glob, AS_HELP_STRING(--enable-glob, [Use glob(3) from libc])) dnl Checks for libraries. dnl Checks for header files. -AC_CHECK_HEADERS(alloca.h) +AC_CHECK_HEADERS(alloca.h paths.h) + +dnl Check for declarations +AC_CHECK_DECL([_PATH_BSHELL],,AC_DEFINE_UNQUOTED([_PATH_BSHELL], "/bin/sh", [Define to system shell path]),[ +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif +]) +AC_CHECK_DECL([_PATH_DEVNULL],,AC_DEFINE_UNQUOTED([_PATH_DEVNULL], "/dev/null", [Define to devnull device node path]),[ +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif +]) +AC_CHECK_DECL([_PATH_TTY],,AC_DEFINE_UNQUOTED([_PATH_TTY], "/dev/tty", [Define to tty device node path]),[ +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif +]) + +dnl Some systems lack isblank +AC_CHECK_DECLS([isblank],,,[#include <ctype.h>]) + +dnl Check for types and sizes +AC_CHECK_SIZEOF([intmax_t]) +AC_CHECK_SIZEOF([long long int]) + +dnl Conservatively use %lld format string rather than %jd where possible +AC_MSG_CHECKING([format string for intmax_t]) +if test "x$ac_cv_sizeof_intmax_t" = "x$ac_cv_sizeof_long_long_int"; then + intmax_fstr="%lld" +else + intmax_fstr="%jd" +fi +AC_MSG_RESULT($intmax_fstr) +AC_DEFINE_UNQUOTED([INTMAX_FSTR], "$intmax_fstr", [Define to printf format string for intmax_t]) dnl Checks for library functions. AC_CHECK_FUNCS(bsearch faccessat getpwnam getrlimit imaxdiv isalpha killpg \
src/arith_yacc.c +0 -1
@@ -33,7 +33,6 @@*/ #include <inttypes.h> -#include <stdint.h> #include <stdlib.h> #include "arith_yacc.h" #include "expand.h"
src/bltin/test.c +1 -1
@@ -12,7 +12,7 @@#include <sys/types.h> #include <fcntl.h> -#include <stdint.h> +#include <inttypes.h> #include <stdlib.h> #include <string.h> #include <unistd.h>
src/cd.c +4 -0
@@ -32,11 +32,15 @@* SUCH DAMAGE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <limits.h> /* * The cd and pwd commands.
src/exec.c +5 -0
@@ -32,12 +32,17 @@* SUCH DAMAGE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> +#ifdef HAVE_PATHS_H #include <paths.h> +#endif /* * When commands are first encountered, they are entered in a hash table.
src/expand.c +2 -2
@@ -42,7 +42,7 @@#endif #include <stdlib.h> #include <stdio.h> -#include <stdint.h> +#include <inttypes.h> #include <limits.h> #include <string.h> #include <fnmatch.h>
@@ -1695,7 +1695,7 @@ cvtnum(intmax_t num)int len =max_int_length (sizeof (num)); expdest =makestrspace (len, expdest); - len =fmtstr (expdest, len,"%jd" , num); + len =fmtstr (expdest, len,INTMAX_FSTR , num);STADJUST (len, expdest);return len; }
src/expand.h +1 -1
@@ -34,7 +34,7 @@* @(#)expand.h 8.2 (Berkeley) 5/4/95 */ -#include <stdint.h> +#include <inttypes.h> struct strlist {struct strlist *next;
src/histedit.c +5 -0
@@ -32,8 +32,13 @@* SUCH DAMAGE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include <sys/param.h> +#ifdef HAVE_PATHS_H #include <paths.h> +#endif #include <stdio.h> #include <stdlib.h> #include <unistd.h>
src/jobs.c +5 -0
@@ -32,11 +32,16 @@* SUCH DAMAGE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include <fcntl.h> #include <signal.h> #include <unistd.h> #include <stdlib.h> +#ifdef HAVE_PATHS_H #include <paths.h> +#endif #include <sys/types.h> #include <sys/param.h> #ifdef BSD
src/jobs.h +1 -1
@@ -34,7 +34,7 @@* @(#)jobs.h 8.2 (Berkeley) 5/4/95 */ -#include <stdint.h> +#include <inttypes.h> #include <sys/types.h> /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
src/miscbltin.c +2 -2
@@ -44,7 +44,7 @@#include <unistd.h> #include <stdlib.h> #include <ctype.h> -#include <stdint.h> +#include <inttypes.h> #include "shell.h" #include "options.h"
@@ -396,7 +396,7 @@ static void printlim(enum limtype how, const struct rlimit *limit,out1fmt ("unlimited\n" ); else { val /= l->factor; -out1fmt ("%jd\n" , (intmax_t ) val); +out1fmt (INTMAX_FSTR "\n" , (intmax_t ) val); } }
src/mkbuiltins +15 -0
@@ -40,6 +40,21 @@ if ! type tempfile > /dev/null 2>&1; then tempfile="mktemp ${TMPDIR:-/tmp}/builtin.XXXXXX" fi +if ! type mktemp > /dev/null 2>&1; then + _my_tempfile() + { + index=0 + while test -f "${TMPDIR:-/tmp}/builtin.$$.$index"; do + index=`expr $index + 1` + done + + touch "${TMPDIR:-/tmp}/builtin.$$.$index" + echo "${TMPDIR:-/tmp}/builtin.$$.$index" + } + + tempfile="_my_tempfile" +fi + trap 'rm -f $temp $temp2' EXIT temp=$($tempfile) temp2=$($tempfile)
src/mystring.c +1 -1
@@ -46,7 +46,7 @@#include <errno.h> #include <inttypes.h> #include <limits.h> -#include <stdint.h> +#include <inttypes.h> #include <stdlib.h> #include "shell.h" #include "syntax.h"
src/mystring.h +1 -1
@@ -34,7 +34,7 @@* @(#)mystring.h 8.2 (Berkeley) 5/4/95 */ -#include <stdint.h> +#include <inttypes.h> #include <string.h> extern const char snlfmt[];
src/output.c +14 -0
@@ -378,6 +378,20 @@ xvsnprintf(char *outbuf, size_t length, const char *fmt, va_list ap) {int ret; +#ifdef __sun +/* +* vsnprintf() on older versions of Solaris returns -1 when +* passed a length of 0. To avoid this, use a dummy +* 1-character buffer instead. +*/ +char dummy[1 ]; + +if (length ==0 ) { + outbuf = dummy; + length =sizeof (dummy); + } +#endif +INTOFF ; ret =vsnprintf (outbuf, length, fmt, ap);INTON ;
src/system.c +8 -0
@@ -170,9 +170,11 @@ int isupper(int c) { } +#if HAVE_DECL_ISBLANK int isblank (int c) {return _isblank (c); } +#endif int isgraph (int c) {
@@ -189,3 +191,9 @@ int isxdigit(int c) { return _isxdigit(c); }#endif + +#if !HAVE_DECL_ISBLANK +int isblank (int c) { +return c ==' ' || c =='\t' ; +} +#endif
src/system.h +5 -0
@@ -26,6 +26,7 @@* SUCH DAMAGE. */ +#include "config.h" #include <limits.h> #include <signal.h> #include <sys/types.h>
@@ -98,6 +99,10 @@ static inline int killpg(pid_t pid, int signal)long sysconf (int ) __attribute__((__noreturn__));#endif +#if !HAVE_DECL_ISBLANK +int isblank (int c); +#endif +/* * A trick to suppress uninitialized variable warning without generating any * code
src/var.c +6 -1
@@ -32,9 +32,14 @@* SUCH DAMAGE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include <unistd.h> #include <stdlib.h> +#ifdef HAVE_PATHS_H #include <paths.h> +#endif /* * Shell variables.
@@ -223,7 +228,7 @@ intmax_t setvarint(const char *name, intmax_t val, int flags)int len =max_int_length (sizeof (val));char buf[len]; -fmtstr (buf, len,"%jd" , val); +fmtstr (buf, len,INTMAX_FSTR , val);setvar (name, buf, flags);return val; }
src/var.h +1 -1
@@ -34,7 +34,7 @@* @(#)var.h 8.2 (Berkeley) 5/4/95 */ -#include <stdint.h> +#include <inttypes.h> /* * Shell variables.
Signature · 1 line
1.7.1
Re: [PATCH 1/3] Port to Solaris
Quoted 5 lines · Brian Koropoff
- Older Solaris does not support %jd (
intmax_t) in format strings, but it does support %lld (long long), which is the same size on all architectures it supports. Do a configure check for the sizes of both and prefer %lld when it is safe to do so.
Pedantically, that's a regression for systems that do support %jd, and I expect compilers to warn about it. If %jd is available, it must be used for intmax_t, and not %lld, because that is for long long, not intmax_t.
What you can do is use PRIdMAX from <inttypes.h>, normally defined as "jd". You can then define this to "lld" or "jd" if it is not defined. I think this makes the code uglier (just like your change), but oh well.
Quoted 3 lines
- Older Solaris lacks
stdint.h, butinttypes.hprovides the same types and works on all platforms I've tried dash on, so just use it instead.
<inttypes.h> is defined to be a superset of <stdint.h>, so that is ok. It is also needed for the PRIdMAX suggestion above.
src/arith_yacc.c line 38
Quoted 13 lines
[...]
src/arith_yacc.c +0
-1@@ -33,7 +33,6 @@*/ #include <inttypes.h> -#include <stdint.h> #include <stdlib.h> #include "arith_yacc.h" #include "expand.h"
This is useful regardless as the <stdint.h> is redundant. The <inttypes.h> is already needed here because of imaxdiv().
By the way, I wonder what the advantage of imaxdiv() above separate % and / is. Compilers can detect the matching between a % b and a / b and do it in one operation, and any use of imaxdiv() trips gcc's -Waggregate-return.
Signature · 1 line
Jilles Tjoelker
Re: [PATCH 1/3] Port to Solaris
Quoted 4 lines · Jilles Tjoelker
What you can do is use PRIdMAX from <
inttypes.h>, normally defined as "jd". You can then define this to "lld" or "jd" if it is not defined. I think this makes the code uglier (just like your change), but oh well.
I agree. Brian, please update your patch accordingly.
Thanks!
Quoted 4 lines
By the way, I wonder what the advantage of
imaxdiv()above separate % and / is. Compilers can detect the matching between a % b and a / b and do it in one operation, and any use ofimaxdiv()trips gcc's -Waggregate-return.
It used to generate smaller code with gcc. If gcc now knows how to optimise it properly then I guess we can remove imaxdiv.
I just checked and gcc 4.4.5 still generates two divisions without imaxdiv. On the other hand gcc doesn't even inline imaxdiv.
Cheers,
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH 1/3] Port to Solaris
I'll send an updated and rebased patch shortly. Once we've agreed about what to do with _LARGEFILE64_SOURCE in the HP-UX patch, I'll send a new version of that as well.
-- Brian
Quoted 22 lines · Herbert Xu
Quoted 4 lines · Jilles Tjoelker
What you can do is use PRIdMAX from <
inttypes.h>, normally defined as "jd". You can then define this to "lld" or "jd" if it is not defined. I think this makes the code uglier (just like your change), but oh well.I agree. Brian, please update your patch accordingly.
Thanks!
Quoted 4 lines
By the way, I wonder what the advantage of
imaxdiv()above separate % and / is. Compilers can detect the matching between a % b and a / b and do it in one operation, and any use ofimaxdiv()trips gcc's -Waggregate-return.It used to generate smaller code with gcc. If gcc now knows how to optimise it properly then I guess we can remove imaxdiv.
I just checked and gcc 4.4.5 still generates two divisions without imaxdiv. On the other hand gcc doesn't even inline imaxdiv.
Cheers,
PATCH 1/1 Port to Solaris
- Solaris lacks paths.h and the various _PATH_* #defines. Check for them in configure.ac and fall back on the usual suspects when they are missing.
- Older Solaris lacks isblank(), and versions that have it use a macro. Check for the declaration in configure.ac and fall back on a naive version when missing.
- Older Solaris does not support %jd (intmax_t) in format strings, but it does support the PRIdMAX macro from inttypes.h. Do a configure check for PRIdMAX and use it in the code. If it doesn't exist, define it to "lld" when sizeof(long long) equals sizeof(intmax_t) as this is more likely to work on older systems. Otherwise, use "jd" and hope for the best.
- Older Solaris lacks stdint.h, but inttypes.h provides the same types and works on all platforms I've tried dash on, so just use it instead.
- Older Solaris doesn't like it when vsnprintf() is passed a NULL buffer (in violation of the POSIX spec, of course). Pass a 1-byte dummy buffer instead.
- Solaris lacks tempfile and mktemp programs. Fall back on a "good-enough" custom function in mkbuiltins.
--- configure.ac | 41 ++++++++++++++++++++++++++++++++++++++++- src/arith_yacc.c | 1 - src/bltin/test.c | 2 +- src/cd.c | 4 ++++ src/exec.c | 5 +++++ src/expand.c | 4 ++-- src/expand.h | 2 +- src/histedit.c | 5 +++++ src/jobs.c | 5 +++++ src/jobs.h | 2 +- src/miscbltin.c | 4 ++-- src/mkbuiltins | 15 +++++++++++++++ src/mystring.c | 2 +- src/mystring.h | 2 +- src/output.c | 14 ++++++++++++++ src/system.c | 8 ++++++++ src/system.h | 5 +++++ src/var.c | 7 ++++++- src/var.h | 2 +- 19 files changed, 117 insertions(+), 13 deletions(-)
configure.ac +40 -1
@@ -43,7 +43,46 @@ AC_ARG_ENABLE(glob, AS_HELP_STRING(--enable-glob, [Use glob(3) from libc])) dnl Checks for libraries. dnl Checks for header files. -AC_CHECK_HEADERS(alloca.h) +AC_CHECK_HEADERS(alloca.h paths.h) + +dnl Check for declarations +AC_CHECK_DECL([_PATH_BSHELL],,AC_DEFINE_UNQUOTED([_PATH_BSHELL], "/bin/sh", [Define to system shell path]),[ +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif +]) +AC_CHECK_DECL([_PATH_DEVNULL],,AC_DEFINE_UNQUOTED([_PATH_DEVNULL], "/dev/null", [Define to devnull device node path]),[ +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif +]) +AC_CHECK_DECL([_PATH_TTY],,AC_DEFINE_UNQUOTED([_PATH_TTY], "/dev/tty", [Define to tty device node path]),[ +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif +]) + +dnl Some systems lack isblank +AC_CHECK_DECLS([isblank],,,[#include <ctype.h>]) + +dnl Check for sizes of types +AC_CHECK_SIZEOF([intmax_t]) +AC_CHECK_SIZEOF([long long int]) + +dnl Select a fallback format string for intmax_t in case we don't find PRIdMAX +if test "x$ac_cv_sizeof_intmax_t" = "x$ac_cv_sizeof_long_long_int"; then + intmax_fstr="lld" +else + intmax_fstr="jd" +fi + +dnl Check for PRIdMAX and define it to a fallback if not found +AC_CHECK_DECL([PRIdMAX],, + [AC_DEFINE_UNQUOTED([PRIdMAX], "$intmax_fstr", + [Define to printf format string for intmax_t])], + [ +#include <inttypes.h> +]) dnl Checks for library functions. AC_CHECK_FUNCS(bsearch faccessat getpwnam getrlimit imaxdiv isalpha killpg \
src/arith_yacc.c +0 -1
@@ -33,7 +33,6 @@*/ #include <inttypes.h> -#include <stdint.h> #include <stdlib.h> #include "arith_yacc.h" #include "expand.h"
src/bltin/test.c +1 -1
@@ -12,7 +12,7 @@#include <sys/types.h> #include <fcntl.h> -#include <stdint.h> +#include <inttypes.h> #include <stdlib.h> #include <string.h> #include <unistd.h>
src/cd.c +4 -0
@@ -32,11 +32,15 @@* SUCH DAMAGE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <limits.h> /* * The cd and pwd commands.
src/exec.c +5 -0
@@ -32,12 +32,17 @@* SUCH DAMAGE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> +#ifdef HAVE_PATHS_H #include <paths.h> +#endif /* * When commands are first encountered, they are entered in a hash table.
src/expand.c +2 -2
@@ -42,7 +42,7 @@#endif #include <stdlib.h> #include <stdio.h> -#include <stdint.h> +#include <inttypes.h> #include <limits.h> #include <string.h> #include <fnmatch.h>
@@ -1691,7 +1691,7 @@ cvtnum(intmax_t num)int len =max_int_length (sizeof (num)); expdest =makestrspace (len, expdest); - len =fmtstr (expdest, len,"%jd" , num); + len =fmtstr (expdest, len,"%" PRIdMAX, num);STADJUST (len, expdest);return len; }
src/expand.h +1 -1
@@ -34,7 +34,7 @@* @(#)expand.h 8.2 (Berkeley) 5/4/95 */ -#include <stdint.h> +#include <inttypes.h> struct strlist {struct strlist *next;
src/histedit.c +5 -0
@@ -32,8 +32,13 @@* SUCH DAMAGE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include <sys/param.h> +#ifdef HAVE_PATHS_H #include <paths.h> +#endif #include <stdio.h> #include <stdlib.h> #include <unistd.h>
src/jobs.c +5 -0
@@ -32,11 +32,16 @@* SUCH DAMAGE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include <fcntl.h> #include <signal.h> #include <unistd.h> #include <stdlib.h> +#ifdef HAVE_PATHS_H #include <paths.h> +#endif #include <sys/types.h> #include <sys/param.h> #ifdef BSD
src/jobs.h +1 -1
@@ -34,7 +34,7 @@* @(#)jobs.h 8.2 (Berkeley) 5/4/95 */ -#include <stdint.h> +#include <inttypes.h> #include <sys/types.h> /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
src/miscbltin.c +2 -2
@@ -44,7 +44,7 @@#include <unistd.h> #include <stdlib.h> #include <ctype.h> -#include <stdint.h> +#include <inttypes.h> #include "shell.h" #include "options.h"
@@ -410,7 +410,7 @@ static void printlim(enum limtype how, const struct rlimit *limit,out1fmt ("unlimited\n" ); else { val /= l->factor; -out1fmt ("%jd\n" , (intmax_t ) val); +out1fmt ("%" PRIdMAX"\n" , (intmax_t ) val); } }
src/mkbuiltins +15 -0
@@ -40,6 +40,21 @@ if ! type tempfile > /dev/null 2>&1; then tempfile="mktemp ${TMPDIR:-/tmp}/builtin.XXXXXX" fi +if ! type mktemp > /dev/null 2>&1; then + _my_tempfile() + { + index=0 + while test -f "${TMPDIR:-/tmp}/builtin.$$.$index"; do + index=`expr $index + 1` + done + + touch "${TMPDIR:-/tmp}/builtin.$$.$index" + echo "${TMPDIR:-/tmp}/builtin.$$.$index" + } + + tempfile="_my_tempfile" +fi + trap 'rm -f $temp $temp2' EXIT temp=$($tempfile) temp2=$($tempfile)
src/mystring.c +1 -1
@@ -46,7 +46,7 @@#include <errno.h> #include <inttypes.h> #include <limits.h> -#include <stdint.h> +#include <inttypes.h> #include <stdlib.h> #include "shell.h" #include "syntax.h"
src/mystring.h +1 -1
@@ -34,7 +34,7 @@* @(#)mystring.h 8.2 (Berkeley) 5/4/95 */ -#include <stdint.h> +#include <inttypes.h> #include <string.h> extern const char snlfmt[];
src/output.c +14 -0
@@ -378,6 +378,20 @@ xvsnprintf(char *outbuf, size_t length, const char *fmt, va_list ap) {int ret; +#ifdef __sun +/* +* vsnprintf() on older versions of Solaris returns -1 when +* passed a length of 0. To avoid this, use a dummy +* 1-character buffer instead. +*/ +char dummy[1 ]; + +if (length ==0 ) { + outbuf = dummy; + length =sizeof (dummy); + } +#endif +INTOFF ; ret =vsnprintf (outbuf, length, fmt, ap);INTON ;
src/system.c +8 -0
@@ -170,9 +170,11 @@ int isupper(int c) { } +#if HAVE_DECL_ISBLANK int isblank (int c) {return _isblank (c); } +#endif int isgraph (int c) {
@@ -189,3 +191,9 @@ int isxdigit(int c) { return _isxdigit(c); }#endif + +#if !HAVE_DECL_ISBLANK +int isblank (int c) { +return c ==' ' || c =='\t' ; +} +#endif
src/system.h +5 -0
@@ -26,6 +26,7 @@* SUCH DAMAGE. */ +#include "config.h" #include <limits.h> #include <signal.h> #include <sys/types.h>
@@ -98,6 +99,10 @@ static inline int killpg(pid_t pid, int signal)long sysconf (int ) __attribute__((__noreturn__));#endif +#if !HAVE_DECL_ISBLANK +int isblank (int c); +#endif +/* * A trick to suppress uninitialized variable warning without generating any * code
src/var.c +6 -1
@@ -32,9 +32,14 @@* SUCH DAMAGE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include <unistd.h> #include <stdlib.h> +#ifdef HAVE_PATHS_H #include <paths.h> +#endif /* * Shell variables.
@@ -223,7 +228,7 @@ intmax_t setvarint(const char *name, intmax_t val, int flags)int len =max_int_length (sizeof (val));char buf[len]; -fmtstr (buf, len,"%jd" , val); +fmtstr (buf, len,"%" PRIdMAX, val);setvar (name, buf, flags);return val; }
src/var.h +1 -1
@@ -34,7 +34,7 @@* @(#)var.h 8.2 (Berkeley) 5/4/95 */ -#include <stdint.h> +#include <inttypes.h> /* * Shell variables.
Signature · 1 line
1.7.1
Re: [PATCH] Port to Solaris
Quoted 1 line · Brian Koropoff
Signed-off-by Brian Koropoff <[email protected]>
Thanks for the patch. I've made some minor updates before applying:
* Remove unnecessary config.h inclusions (already included on command line)
* Only check mktemp when tempfile is unavailable
Please take a look at the end result to see if I've messed anything up.
Thanks,
Signature · 38 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- commit bfcdc4969510997fe81debf52982641febfa1bdf Author: Brian Koropoff <[email protected]> Date: Tue Mar 15 15:35:14 2011 +0800 [SHELL] Port to Solaris - Solaris lacks paths.h and the various _PATH_* #defines. Check for them in configure.ac and fall back on the usual suspects when they are missing. - Older Solaris lacks isblank(), and versions that have it use a macro. Check for the declaration in configure.ac and fall back on a naive version when missing. - Older Solaris does not support %jd (intmax_t) in format strings, but it does support the PRIdMAX macro from inttypes.h. Do a configure check for PRIdMAX and use it in the code. If it doesn't exist, define it to "lld" when sizeof(long long) equals sizeof(intmax_t) as this is more likely to work on older systems. Otherwise, use "jd" and hope for the best. - Older Solaris lacks stdint.h, but inttypes.h provides the same types and works on all platforms I've tried dash on, so just use it instead. - Older Solaris doesn't like it when vsnprintf() is passed a NULL buffer (in violation of the POSIX spec, of course). Pass a 1-byte dummy buffer instead. - Solaris lacks tempfile and mktemp programs. Fall back on a "good-enough" custom function in mkbuiltins. Signed-off-by: Brian Koropoff <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
ChangeLog +4 -0
@@ -1,3 +1,7 @@ +2011-03-15 Brian Koropoff <[email protected]> + + * Port to Solaris. + 2011-03-11 Herbert Xu <[email protected]> * Fix backslash handling in read(1).
configure.ac +40 -1
47 lines not on this page · raw message
src/arith_yacc.c +0 -1
@@ -33,7 +33,6 @@*/ #include <inttypes.h> -#include <stdint.h> #include <stdlib.h> #include "arith_yacc.h" #include "expand.h"
src/bltin/test.c +1 -1
@@ -12,7 +12,7 @@#include <sys/types.h> #include <fcntl.h> -#include <stdint.h> +#include <inttypes.h> #include <stdlib.h> #include <string.h> #include <unistd.h>
src/cd.c +1 -0
@@ -37,6 +37,7 @@#include <stdlib.h> #include <string.h> #include <unistd.h> +#include <limits.h> /* * The cd and pwd commands.
src/exec.c +2 -0
@@ -37,7 +37,9 @@#include <unistd.h> #include <fcntl.h> #include <stdlib.h> +#ifdef HAVE_PATHS_H #include <paths.h> +#endif /* * When commands are first encountered, they are entered in a hash table.
src/expand.c +2 -2
@@ -42,7 +42,7 @@#endif #include <stdlib.h> #include <stdio.h> -#include <stdint.h> +#include <inttypes.h> #include <limits.h> #include <string.h> #include <fnmatch.h>
@@ -1691,7 +1691,7 @@ cvtnum(intmax_t num)int len =max_int_length (sizeof (num)); expdest =makestrspace (len, expdest); - len =fmtstr (expdest, len,"%jd" , num); + len =fmtstr (expdest, len,"%" PRIdMAX, num);STADJUST (len, expdest);return len; }
src/expand.h +1 -1
@@ -34,7 +34,7 @@* @(#)expand.h 8.2 (Berkeley) 5/4/95 */ -#include <stdint.h> +#include <inttypes.h> struct strlist {struct strlist *next;
src/histedit.c +2 -0
@@ -33,7 +33,9 @@*/ #include <sys/param.h> +#ifdef HAVE_PATHS_H #include <paths.h> +#endif #include <stdio.h> #include <stdlib.h> #include <unistd.h>
src/jobs.c +2 -0
@@ -36,7 +36,9 @@#include <signal.h> #include <unistd.h> #include <stdlib.h> +#ifdef HAVE_PATHS_H #include <paths.h> +#endif #include <sys/types.h> #include <sys/param.h> #ifdef BSD
src/jobs.h +1 -1
@@ -34,7 +34,7 @@* @(#)jobs.h 8.2 (Berkeley) 5/4/95 */ -#include <stdint.h> +#include <inttypes.h> #include <sys/types.h> /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
src/miscbltin.c +2 -2
@@ -44,7 +44,7 @@#include <unistd.h> #include <stdlib.h> #include <ctype.h> -#include <stdint.h> +#include <inttypes.h> #include "shell.h" #include "options.h"
@@ -410,7 +410,7 @@ static void printlim(enum limtype how, const struct rlimit *limit,out1fmt ("unlimited\n" ); else { val /= l->factor; -out1fmt ("%jd\n" , (intmax_t ) val); +out1fmt ("%" PRIdMAX"\n" , (intmax_t ) val); } }
src/mkbuiltins +14 -1
@@ -36,7 +36,20 @@ # @(#)mkbuiltins 8.2 (Berkeley) 5/4/95 tempfile=tempfile -if ! type tempfile > /dev/null 2>&1; then +if ! type tempfile > /dev/null 2>&1 && ! type mktemp > /dev/null 2>&1; then + _my_tempfile() + { + local index=0 + while test -f "${TMPDIR:-/tmp}/builtin.$$.$index"; do + index=`expr $index + 1` + done + + touch "${TMPDIR:-/tmp}/builtin.$$.$index" + echo "${TMPDIR:-/tmp}/builtin.$$.$index" + } + + tempfile="_my_tempfile" +elif ! type tempfile > /dev/null 2>&1; then tempfile="mktemp ${TMPDIR:-/tmp}/builtin.XXXXXX" fi
src/mystring.c +1 -1
@@ -46,7 +46,7 @@#include <errno.h> #include <inttypes.h> #include <limits.h> -#include <stdint.h> +#include <inttypes.h> #include <stdlib.h> #include "shell.h" #include "syntax.h"
src/mystring.h +1 -1
@@ -34,7 +34,7 @@* @(#)mystring.h 8.2 (Berkeley) 5/4/95 */ -#include <stdint.h> +#include <inttypes.h> #include <string.h> extern const char snlfmt[];
src/output.c +14 -0
@@ -378,6 +378,20 @@ xvsnprintf(char *outbuf, size_t length, const char *fmt, va_list ap) {int ret; +#ifdef __sun +/* +* vsnprintf() on older versions of Solaris returns -1 when +* passed a length of 0. To avoid this, use a dummy +* 1-character buffer instead. +*/ +char dummy[1 ]; + +if (length ==0 ) { + outbuf = dummy; + length =sizeof (dummy); + } +#endif +INTOFF ; ret =vsnprintf (outbuf, length, fmt, ap);INTON ;
src/system.c +8 -0
@@ -170,9 +170,11 @@ int isupper(int c) { } +#if HAVE_DECL_ISBLANK int isblank (int c) {return _isblank (c); } +#endif int isgraph (int c) {
@@ -189,3 +191,9 @@ int isxdigit(int c) { return _isxdigit(c); }#endif + +#if !HAVE_DECL_ISBLANK +int isblank (int c) { +return c ==' ' || c =='\t' ; +} +#endif
src/system.h +4 -0
@@ -98,6 +98,10 @@ static inline int killpg(pid_t pid, int signal)long sysconf (int ) __attribute__((__noreturn__));#endif +#if !HAVE_DECL_ISBLANK +int isblank (int c); +#endif +/* * A trick to suppress uninitialized variable warning without generating any * code
src/var.c +3 -1
@@ -34,7 +34,9 @@#include <unistd.h> #include <stdlib.h> +#ifdef HAVE_PATHS_H #include <paths.h> +#endif /* * Shell variables.
@@ -223,7 +225,7 @@ intmax_t setvarint(const char *name, intmax_t val, int flags)int len =max_int_length (sizeof (val));char buf[len]; -fmtstr (buf, len,"%jd" , val); +fmtstr (buf, len,"%" PRIdMAX, val);setvar (name, buf, flags);return val; }
src/var.h +1 -1
@@ -34,7 +34,7 @@* @(#)var.h 8.2 (Berkeley) 5/4/95 */ -#include <stdint.h> +#include <inttypes.h> /* * Shell variables.
PATCH 2/3 Port to AIX
In reply to Brian Koropoff- AIX lacks a WCOREDUMP macro. It's just used to
append "(core dumped)" to the crash message, so
#ifdef around it.
- For some reason, the nl program on AIX defaults to not printing line numbers ("-b n"), even though the spec says it should default to "-b t". Explicitly pass "-b a" for good measure in mkbuiltins.
--- src/jobs.c | 2 ++ src/mkbuiltins | 2 +- 2 files changed, 3 insertions(+), 1 deletions(-)
src/jobs.c +2 -0
@@ -431,9 +431,11 @@ sprint_status(char *s, int status, int sigonly)#endif } col =fmtstr (s,32 ,strsignal (st)); +#ifdef WCOREDUMP if (WCOREDUMP (status)) { col +=fmtstr (s + col,16 ," (core dumped)" ); } +#endif }else if (!sigonly) {if (st) col =fmtstr (s,16 ,"Done(%d)" , st);
src/mkbuiltins +1 -1
@@ -99,7 +99,7 @@ cat <<\! */ ! -sed 's/ -[a-z]*//' $temp2 | nl -v 0 | LC_COLLATE=C sort -u -k 3,3 | +sed 's/ -[a-z]*//' $temp2 | nl -b a -v 0 | LC_COLLATE=C sort -u -k 3,3 | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | awk '{ printf "#define %s (builtincmd + %d)\n", $3, $1}' printf '\n#define NUMBUILTINS %d\n' $(wc -l < $temp2)
Signature · 1 line
1.7.1
Re: [PATCH 2/3] Port to AIX
Quoted 10 lines · Brian Koropoff
- AIX lacks a WCOREDUMP macro. It's just used to
append "(core dumped)" to the crash message, so
#ifdef around it.- For some reason, the nl program on AIX defaults to not printing line numbers ("-b n"), even though the spec says it should default to "-b t". Explicitly pass "-b a" for good measure in mkbuiltins.
Signed-off-by Brian Koropoff <[email protected]>
Patch applied. Thanks.
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
PATCH 3/3 Port to HP-UX
In reply to Brian Koropoff- strtoimax and strtoumax are macros and not functions, so switch to using AC_CHECK_DECLS in configure.ac to find them.
- HP-UX lacks strsignal() and sys_siglist. Check for sys_siglist in configure.ac and #ifdef around it.
- HP-UX's vsnprintf() completely violates the standard by returning -1 (and neglecting to set errno) if the buffer is not large enough rather than returning the size necessary. Work around it by (yuck) reallocating a dynamic buffer until it succeeds so we can return the expected result.
- HP-UX needs _LARGEFILE64_SOURCE to be defined for open64() and friends to be available. This seems to be safe to define everywhere, so do so.
- The nl program doesn't like spaces between flags and their arguments, so remove them in mkbuiltins.
--- configure.ac | 16 +++++++++++++--- src/Makefile.am | 3 ++- src/mkbuiltins | 2 +- src/output.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/system.c | 2 ++ src/system.h | 4 ++-- 6 files changed, 72 insertions(+), 7 deletions(-)
configure.ac +13 -3
@@ -43,7 +43,7 @@ AC_ARG_ENABLE(glob, AS_HELP_STRING(--enable-glob, [Use glob(3) from libc])) dnl Checks for libraries. dnl Checks for header files. -AC_CHECK_HEADERS(alloca.h paths.h) +AC_CHECK_HEADERS(alloca.h paths.h unistd.h signal.h) dnl Check for declarations AC_CHECK_DECL([_PATH_BSHELL],,AC_DEFINE_UNQUOTED([_PATH_BSHELL], "/bin/sh", [Define to system shell path]),[
@@ -65,6 +65,17 @@ AC_CHECK_DECL([_PATH_TTY],,AC_DEFINE_UNQUOTED([_PATH_TTY], "/dev/tty", [Define t dnl Some systems lack isblank AC_CHECK_DECLS([isblank],,,[#include <ctype.h>]) +dnl strtoimax is a macro on some systems +AC_CHECK_DECLS([strtoimax, strtoumax],,,[#include <inttypes.h>]) + +dnl Check for sys_siglist +AC_CHECK_DECLS([sys_siglist], [], [], + [#include <signal.h> + #ifdef HAVE_UNISTD_H + # include <unistd.h> + #endif + ]) + dnl Check for types and sizes AC_CHECK_SIZEOF([intmax_t]) AC_CHECK_SIZEOF([long long int])
@@ -82,8 +93,7 @@ AC_DEFINE_UNQUOTED([INTMAX_FSTR], "$intmax_fstr", [Define to printf format strin dnl Checks for library functions. AC_CHECK_FUNCS(bsearch faccessat getpwnam getrlimit imaxdiv isalpha killpg \ mempcpy \ - sigsetmask stpcpy strchrnul strsignal strtod strtoimax \ - strtoumax sysconf) + sigsetmask stpcpy strchrnul strsignal strtod sysconf) if test "$enable_fnmatch" = yes; then use_fnmatch=
src/Makefile.am +2 -1
@@ -4,7 +4,8 @@ COMMON_CFLAGS = -Wall COMMON_CPPFLAGS = \ -include $(top_builddir)/config.h \ -DBSD=1 -DSHELL \ - -DIFS_BROKEN + -DIFS_BROKEN \ + -D_LARGEFILE64_SOURCE AM_CFLAGS = $(COMMON_CFLAGS) AM_CPPFLAGS = $(COMMON_CPPFLAGS)
src/mkbuiltins +1 -1
@@ -99,7 +99,7 @@ cat <<\! */ ! -sed 's/ -[a-z]*//' $temp2 | nl -b a -v 0 | LC_COLLATE=C sort -u -k 3,3 | +sed 's/ -[a-z]*//' $temp2 | nl -ba -v0 | LC_COLLATE=C sort -u -k 3,3 | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | awk '{ printf "#define %s (builtincmd + %d)\n", $3, $1}' printf '\n#define NUMBUILTINS %d\n' $(wc -l < $temp2)
src/output.c +52 -0
61 lines not on this page · raw message
src/system.c +2 -0
@@ -92,8 +92,10 @@ char *strsignal(int sig) {static char buf[19 ]; +#if HAVE_DECL_SYS_SIGLIST if ((unsigned )sig <NSIG && sys_siglist[sig])return (char *)sys_siglist[sig]; +#endif fmtstr (buf,sizeof (buf),"Signal %d" , sig);return buf; }
src/system.h +2 -2
@@ -70,11 +70,11 @@ static inline double strtod(const char *nptr, char **endptr) }#endif -#ifndef HAVE_STRTOIMAX +#if !HAVE_DECL_STRTOIMAX #define strtoimax strtoll#endif -#ifndef HAVE_STRTOUMAX +#if !HAVE_DECL_STRTOUMAX #define strtoumax strtoull#endif
Signature · 1 line
1.7.1
Re: [PATCH 3/3] Port to HP-UX
Quoted 4 lines · Brian Koropoff
- HP-UX needs
_LARGEFILE64_SOURCEto be defined foropen64()and friends to be available. This seems to be safe to define everywhere, so do so.
Shouldn't this go into configure.ac? In fact, how can your patch have any effect if configure.ac doesn't detect open64 in the first place?
The rest looks OK.
Thanks,
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH 3/3] Port to HP-UX
AC_CHECK_FUNC just checks that the symbol exists in libc, so it succeeds. _LARGEFILE64_SOURCE is necessary to get the system headers to give you function prototypes, but it doesn't affect the configure test.
-- Brian
Quoted 13 lines · Herbert Xu
Quoted 4 lines · Brian Koropoff
- HP-UX needs
_LARGEFILE64_SOURCEto be defined foropen64()and friends to be available. This seems to be safe to define everywhere, so do so.Shouldn't this go into configure.ac? In fact, how can your patch have any effect if configure.ac doesn't detect open64 in the first place?
The rest looks OK.
Thanks,
Re: [PATCH 3/3] Port to HP-UX
Quoted 3 lines · Brian Koropoff
AC_CHECK_FUNCjust checks that the symbol exists in libc, so it succeeds._LARGEFILE64_SOURCEis necessary to get the system headers to give you function prototypes, but it doesn't affect the configure test.
OK, please regenerate the patch against the head of my tree and please move the macro definition from Makefile into config.h through configure.ac.
Thanks,
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt