$search
00001 00017 /***************************************************************************** 00018 ** Includes 00019 *****************************************************************************/ 00020 00021 00022 #include "../../include/ecl/ipc/shared_memory_pos.hpp" 00023 00024 #ifdef ECL_HAS_POSIX_SHARED_MEMORY 00025 00026 #include <string> 00027 #include <sys/mman.h> /* For shm_open() */ 00028 #include <fcntl.h> /* For O_* constants */ 00029 #include <errno.h> 00030 #include <ecl/exceptions/macros.hpp> 00031 #include <iostream> 00032 /***************************************************************************** 00033 ** Namespaces 00034 *****************************************************************************/ 00035 00036 namespace ecl { 00037 namespace ipc { 00038 00039 void SharedMemoryBase::unlink() { 00040 shm_unlink(name.c_str()); 00041 } 00042 00043 int SharedMemoryBase::open() { 00044 /********************* 00045 * Open Flags 00046 *********************/ 00047 /* 00048 * O_CREAT : it will try and create some memory or just open if it already exists 00049 * if the shared memory object already exists. 00050 * O_EXCL : when used with O_CREAT fails to open if the message queue already exists. 00051 * : if neither, then it will only open an existing memory. 00052 * O_WRONLY : write only. 00053 * O_RDONLY : read only. 00054 * O_RDWR : read-write. 00055 * O_NONBLOCK : normally it will block if sending to a full queue. Disable this. 00056 */ 00057 static const int open_flags = O_RDWR; 00058 static const int create_flags = O_CREAT|O_RDWR|O_EXCL; 00059 /********************* 00060 * Permissions 00061 *********************/ 00062 /* 00063 * Permissions. Must be specified when O_CRELOC is used, otherwise it is ignored. It 00064 * is combined with the process umask (permissions & ~umask). 00065 * S_IRWXU [00700] - read, write & exec by user 00066 * S_IRUSR [00400] - read by the user who owns it 00067 * S_IWUSR [00200] - write by user 00068 * S_IXUSR [00100] - exec by user 00069 * S_IRWXG [00070] - read, write & exec by group 00070 * S_IRGRP [00040] - read by group 00071 * S_IWGRP [00020] - write by group 00072 * S_IXGRP [00010] - exe by group 00073 * S_IRWXG [00007] - read, write & exec by other 00074 * S_IROTH [00004] - read by other 00075 * S_IWOTH [00002] - write by other 00076 * S_IXOTH [00001] - exe by other 00077 */ 00078 static const int permissions = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH; 00079 /************************************************************************* 00080 ** Name 00081 *************************************************************************/ 00082 /* 00083 * The name is like a filename. To be compatible on all systems, always 00084 * begin with a leading '/' and include no other '/'s. 00085 * In debug mode, might be worth parsing the name here. 00086 */ 00087 /************************************************************************* 00088 ** Open 00089 *************************************************************************/ 00090 int shm_descriptor = shm_open(name.c_str(),create_flags,permissions); 00091 if ( ( shm_descriptor == -1 ) && ( errno == EEXIST ) ) { 00092 // Maybe its already open, try opening it normally 00093 shm_descriptor = shm_open(name.c_str(),open_flags,permissions); 00094 } else { 00095 shared_memory_manager = true; 00096 } 00097 if ( shm_descriptor == -1) { 00098 } 00099 return shm_descriptor; 00100 } 00101 00102 00103 /***************************************************************************** 00104 ** Exception Handlers 00105 *****************************************************************************/ 00106 00107 #ifdef ECL_HAS_EXCEPTIONS 00108 00109 ecl::StandardException openSharedSectionException(const char* loc) { 00110 int error_result = errno; 00111 switch (error_result) { 00112 case ( EACCES ) : { 00113 throw StandardException(LOC,PermissionsError,"Opening shared memory failed - permission denied."); 00114 break; 00115 } 00116 // case ( EEXIST ) : { // If using O_EXCL, need this, otherwise no. 00117 // // pathname exists, assume its a fifo and continue 00118 // break; 00119 // } 00120 case ( EMFILE ) : case ( ENFILE ) : { 00121 throw StandardException(LOC,OutOfResourcesError,"Opening shared memory failed - too many file connections already open."); 00122 break; 00123 } 00124 case ( ENOENT ) : case ( ENAMETOOLONG ) : case ( EINVAL ) : { 00125 throw StandardException(LOC,InvalidArgError,"Opening shared memory failed - pathname problem."); 00126 break; 00127 } 00128 case ( ENOSYS ) : { 00129 throw StandardException(LOC,NotSupportedError,"Opening shared memory failed - kernel system functions are not available (remake the kernel)."); 00130 break; 00131 } 00132 default : 00133 { 00134 std::ostringstream ostream; 00135 ostream << "Posix error " << error_result << ": " << strerror(error_result) << "."; 00136 return StandardException(loc, UnknownError, ostream.str()); 00137 } 00138 } 00139 } 00140 00141 ecl::StandardException memoryMapException(const char* loc) { 00142 int error_result = errno; 00143 switch (error_result) { 00144 case ( EACCES ) : { 00145 return StandardException(LOC,PermissionsError,"Shared mapping failed - permission problems (see man mmap)."); 00146 } 00147 case ( EAGAIN ) : { 00148 return StandardException(LOC,MemoryError,"Shared mapping failed - file locked or too much memory has been locked."); 00149 } 00150 case ( EBADF ) : { 00151 return StandardException(LOC,InvalidArgError,"Shared mapping failed - not a valid file descriptor (see man mmap)."); 00152 } 00153 case ( EINVAL ) : { 00154 return StandardException(LOC,InvalidArgError,"Shared mapping failed - start, length or offset were invalid or MAP_PRIVLOCE and MAP_SHARED were either both present or both obso (see man mmap)."); 00155 } 00156 case ( ENFILE ) : { 00157 return StandardException(LOC,OutOfResourcesError,"Shared mapping failed - system limit on the total number of open files has been reached (see man mmap)."); 00158 } 00159 case ( ENODEV ) : { 00160 return StandardException(LOC,NotSupportedError,"Shared mapping failed - underlying filesystem of the specified file doesn't support memory mapping (see man mmap)."); 00161 } 00162 case ( ENOMEM ) : { 00163 return StandardException(LOC,MemoryError,"Shared mapping failed - no mem available, or max mappings exceeded (see man mmap)."); 00164 } 00165 case ( EPERM ) : { 00166 return StandardException(LOC,PermissionsError,"Shared mapping failed - EPERM (see man mmap)."); 00167 } 00168 // case ( ETXBSY ) : { 00169 // return StandardException(LOC,"Shared mapping failed.","ETXBSY (see man mmap)."); 00170 // break; 00171 // } 00172 default : 00173 { 00174 std::ostringstream ostream; 00175 ostream << "Posix error " << error_result << ": " << strerror(error_result) << "."; 00176 return StandardException(loc, UnknownError, ostream.str()); 00177 } 00178 } 00179 } 00180 #endif /* ECL_HAS_EXCEPTIONS */ 00181 00182 } // namespace ipc 00183 } // namespace ecl 00184 00185 #endif /* ECL_HAS_POSIX_SHARED_MEMORY */