Name shared memory segments in a more portable way
to make shm_open() work on FreeBSD and some other OSes.

Linux and friends use "/slashless-name" template for shared memory segment IDs.
HPUX and friends use "/full/path/to/some/file".
FreeBSD uses the former or the latter, depending on version and jail context.

We now distinguish the above cases and prefix the internal segment ID
accordingly. The above analysis and its implementation are based on the
boost::interprocess code.

=== modified file 'CREDITS'
--- CREDITS	2011-02-06 13:46:38 +0000
+++ CREDITS	2011-10-25 05:12:00 +0000
@@ -553,20 +553,53 @@
   and make any changes you like.
   All I ask is that you include a link back
   to this page in your credits.
 
   Are you using this icon set? Send me an email
   (including a link or picture if available) to
   mjames@gmail.com
 
   Any other questions about this icon set please
   contact mjames@gmail.com
 
 
   The icons can also be used under Creative Commons Attribution 3.0 License
   (Hi Debian folks!) with the following requirements:
 
     As an author, I would appreciate a reference to my authorship of
     the Silk icon set contents within a readme file or equivalent
     documentation for the software which includes the set or a subset
     of the icons contained within. 
 
+==============================================================================
+
+shm_portable_segment_name_is_path() implementation:
+
+  Derived from boost/interprocess/shared_memory_object.hpp and
+      boost/interprocess/detail/workaround.hpp at http://www.boost.org/
+
+  (C) Copyright Ion Gaztanaga 2005-2009.
+  Distributed under the Boost Software License, Version 1.0
+
+  Boost Software License - Version 1.0 - August 17th, 2003
+
+  Permission is hereby granted, free of charge, to any person or organization
+  obtaining a copy of the software and accompanying documentation covered by
+  this license (the "Software") to use, reproduce, display, distribute,
+  execute, and transmit the Software, and to prepare derivative works of the
+  Software, and to permit third-parties to whom the Software is furnished to
+  do so, all subject to the following:
+
+  The copyright notices in the Software and this entire statement, including
+  the above license grant, this restriction and the following disclaimer,
+  must be included in all copies of the Software, in whole or in part, and
+  all derivative works of the Software, unless such copies or derivative
+  works are solely in the form of machine-executable object code generated by
+  a source language processor.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+  SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+  FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+  DEALINGS IN THE SOFTWARE.

=== modified file 'compat/Makefile.am'
--- compat/Makefile.am	2011-08-28 17:11:19 +0000
+++ compat/Makefile.am	2011-10-25 03:04:28 +0000
@@ -15,40 +15,41 @@
 	assert.h \
 	compat.cc \
 	compat.h \
 	compat_shared.h \
 	cpu.h \
 	cppunit.h \
 	debug.cc \
 	debug.h \
 	drand48.h \
 	eui64_aton.h \
 	fdsetsize.h \
 	getaddrinfo.h \
 	getnameinfo.h \
 	GnuRegex.c \
 	GnuRegex.h \
 	inet_ntop.h \
 	inet_pton.h \
 	initgroups.h \
 	osdetect.h \
 	psignal.h \
+	shm.cc \
 	shm.h \
 	stdio.h \
 	stdvarargs.h \
 	strnstr.cc \
 	strsep.h \
 	strtoll.h \
 	tempnam.h \
 	types.h \
 	unsafe.h \
 	valgrind.h \
 	xalloc.cc \
 	xalloc.h \
 	xis.h \
 	xstrerror.cc \
 	xstrerror.h \
 	xstring.cc \
 	xstring.h \
 	xstrto.cc \
 	xstrto.h \
 	\

=== added file 'compat/shm.cc'
--- compat/shm.cc	1970-01-01 00:00:00 +0000
+++ compat/shm.cc	2011-10-25 05:31:20 +0000
@@ -0,0 +1,28 @@
+#include "config.h"
+#include "compat/shm.h"
+
+#if defined(__FreeBSD__) && (__FreeBSD__ >= 7)
+#    include <sys/sysctl.h>
+#endif
+
+
+/*
+ * Some systems have filesystem-based resources and interpret segment names
+ * as file paths. The so-called 'portable' "/name" format does not work well 
+ * for them. And, according to Boost::interprocess, recent FreeBSD versions
+ * make this decision depending on whether the shm_open() caller is jailed!
+ */
+bool
+shm_portable_segment_name_is_path()
+{
+#if defined(_SQUID_HPUX_) || defined(_SQUID_OSF_) || defined(__vms) || (defined(_SQUID_FREEBSD_) && (__FreeBSD__ < 7))
+	return true;
+#elif defined(_SQUID_FREEBSD_)
+   int jailed = 0;
+   size_t len = sizeof(jailed);
+   ::sysctlbyname("security.jail.jailed", &jailed, &len, NULL, 0);
+   return jailed != 0;
+#else
+    return false;
+#endif
+}

=== modified file 'compat/shm.h'
--- compat/shm.h	2011-09-06 22:32:30 +0000
+++ compat/shm.h	2011-10-25 03:02:45 +0000
@@ -25,21 +25,25 @@
 #endif
 
 extern "C" {
 
     inline int
     shm_open(const char *, int, mode_t) {
         errno = ENOTSUP;
         return -1;
     }
 
     inline int
     shm_unlink(const char *) {
         errno = ENOTSUP;
         return -1;
     }
 
 } /* extern "C" */
 
 #endif /* HAVE_SHM */
 
+
+/// Determines whether segment names are iterpreted as full file paths.
+bool shm_portable_segment_name_is_path();
+
 #endif /* SQUID_COMPAT_CPU_H */

=== modified file 'src/ipc/mem/Segment.cc'
--- src/ipc/mem/Segment.cc	2011-10-21 23:38:50 +0000
+++ src/ipc/mem/Segment.cc	2011-10-25 03:20:19 +0000
@@ -152,45 +152,49 @@
 }
 
 /// determines the size of the underlying "file"
 off_t
 Ipc::Mem::Segment::statSize(const char *context) const
 {
     Must(theFD >= 0);
 
     struct stat s;
     memset(&s, 0, sizeof(s));
 
     if (fstat(theFD, &s) != 0) {
         debugs(54, 5, HERE << context << " fstat " << theName << ": " << xstrerror());
         fatalf("Ipc::Mem::Segment::statSize: %s failed to fstat(%s): %s\n",
                context, theName.termedBuf(), xstrerror());
     }
 
     return s.st_size;
 }
 
-/// Generate name for shared memory segment. Replaces all slashes with dots.
+/// Generate name for shared memory segment. Starts with a prefix required
+/// for cross-platform portability and replaces all slashes in ID with dots.
 String
 Ipc::Mem::Segment::GenerateName(const char *id)
 {
-    String name("/squid-");
+    static const bool nameIsPath = shm_portable_segment_name_is_path();
+    String name(nameIsPath ? DEFAULT_STATEDIR : "/squid-");
+
+    // append id, replacing slashes with dots
     for (const char *slash = strchr(id, '/'); slash; slash = strchr(id, '/')) {
         if (id != slash) {
             name.append(id, slash - id);
             name.append('.');
         }
         id = slash + 1;
     }
     name.append(id);
     return name;
 }
 
 #else // HAVE_SHM
 
 #include <map>
 
 typedef std::map<String, Ipc::Mem::Segment *> SegmentMap;
 static SegmentMap Segments;
 
 Ipc::Mem::Segment::Segment(const char *const id):
         theName(id), theMem(NULL), theSize(0), theReserved(0), doUnlink(false)