$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r80304 - trunk/tools/build/v2/engine
From: jurko.gospodnetic_at_[hidden]
Date: 2012-08-29 11:52:29
Author: jurko
Date: 2012-08-29 11:52:29 EDT (Wed, 29 Aug 2012)
New Revision: 80304
URL: http://svn.boost.org/trac/boost/changeset/80304
Log:
Boost Jam cleanup on Linux/Free-BSD - replaced strndup() usage with malloc()/strncpy() as strndup() does not get declared in older glibc version header files unless some version specific symbols are defined first. This corrects a compiler warning on such systems about strndup() function being implicitly (and incorrectly) declared.
Text files modified: 
   trunk/tools/build/v2/engine/jam.c |    38 +++++++++++++++++++++++++++++++++++---  
   1 files changed, 35 insertions(+), 3 deletions(-)
Modified: trunk/tools/build/v2/engine/jam.c
==============================================================================
--- trunk/tools/build/v2/engine/jam.c	(original)
+++ trunk/tools/build/v2/engine/jam.c	2012-08-29 11:52:29 EDT (Wed, 29 Aug 2012)
@@ -628,6 +628,8 @@
     return strdup( getexecname() );
 }
 #elif defined(__FreeBSD__)
+# include <stdlib.h>
+# include <string.h>
 # include <sys/sysctl.h>
 char * executable_path( char const * argv0 )
 {
@@ -635,15 +637,45 @@
     char buf[ 1024 ];
     size_t size = sizeof( buf );
     sysctl( mib, 4, buf, &size, NULL, 0 );
-    return ( !size || size == sizeof( buf ) ) ? NULL : strndup( buf, size );
+    if ( size && size != sizeof( buf ) )
+    {
+        /* Using strndup() here might not work with older glibc installations as
+         * their headers do not declare that function unless certain symbols are
+         * defined. We could work around this issue by defining appropriate
+         * symbols but they depend on the exact glibc version used so simply
+         * using malloc()/strncpy() seems like a cleaner solution.
+         *
+         * Note: such old glibc installations have so far only been found on
+         * Linux and not Free-BSD installations but using the same logic on
+         * Free-BSD seems like something that could not hurt.
+         */
+        char * const result = (char *)malloc( size );
+        if ( result )
+            return strncpy( result, buf, size );
+    }
+    return NULL;
 }
 #elif defined(__linux__)
+# include <stdlib.h>
+# include <string.h>
 # include <unistd.h>
 char * executable_path( char const * argv0 )
 {
     char buf[ 1024 ];
-    ssize_t const ret = readlink( "/proc/self/exe", buf, sizeof( buf ) );
-    return ( !ret || ret == sizeof( buf ) ) ? NULL : strndup( buf, ret );
+    ssize_t const size = readlink( "/proc/self/exe", buf, sizeof( buf ) );
+    if ( size && size != sizeof( buf ) )
+    {
+        /* Using strndup() here might not work with older glibc installations as
+         * their headers do not declare that function unless certain symbols are
+         * defined. We could work around this issue by defining appropriate
+         * symbols but they depend on the exact glibc version used so simply
+         * using malloc()/strncpy() seems like a cleaner solution.
+         */
+        char * const result = (char *)malloc( size );
+        if ( result )
+            return strncpy( result, buf, size );
+    }
+    return NULL;
 }
 #else
 char * executable_path( char const * argv0 )