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 +#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 typedef std::map SegmentMap; static SegmentMap Segments; Ipc::Mem::Segment::Segment(const char *const id): theName(id), theMem(NULL), theSize(0), theReserved(0), doUnlink(false)