00001 /* 00002 Copyright 2003 by Marc J. Rochkind. All rights reserved. 00003 May be copied only for purposes and under conditions described 00004 on the Web page www.basepath.com/aup/copyright.htm. 00005 00006 The Example Files are provided "as is," without any warranty; 00007 without even the implied warranty of merchantability or fitness 00008 for a particular purpose. The author and his publisher are not 00009 responsible for any damages, direct or incidental, resulting 00010 from the use or non-use of these Example Files. 00011 00012 The Example Files may contain defects, and some contain deliberate 00013 coding mistakes that were included for educational reasons. 00014 You are responsible for determining if and how the Example Files 00015 are to be used. 00016 00017 */ 00018 #include "ux.hpp" 00019 00020 using namespace Ux; 00021 00022 /** 00023 Calls mq_open. 00024 */ 00025 void PosixMsg::open(const char *name, int flags, mode_t perms, struct mq_attr *attr) 00026 { 00027 #if _POSIX_MESSAGE_PASSING > 0 00028 if ((mqd = ::mq_open(name, flags, perms, attr)) == (mqd_t)-1) 00029 throw Error(errno); 00030 #else 00031 throw Error(ENOSYS); 00032 #endif 00033 } 00034 00035 /** 00036 Calls mq_close. 00037 */ 00038 void PosixMsg::close(void) 00039 { 00040 #if _POSIX_MESSAGE_PASSING > 0 00041 if (::mq_close(mqd) == -1) 00042 throw Error(errno); 00043 #else 00044 throw Error(ENOSYS); 00045 #endif 00046 } 00047 00048 /** 00049 Calls mq_unlink. Could be static, as it doesn't refer to the mqd. 00050 */ 00051 void PosixMsg::unlink(const char *name) 00052 { 00053 #if _POSIX_MESSAGE_PASSING > 0 00054 if (::mq_unlink(name) == -1) 00055 throw Error(errno); 00056 #else 00057 throw Error(ENOSYS); 00058 #endif 00059 } 00060 00061 /** 00062 Calls mq_send. 00063 */ 00064 void PosixMsg::send(const char *msg, size_t msgsize, unsigned priority) 00065 { 00066 #if _POSIX_MESSAGE_PASSING > 0 00067 if (::mq_send(mqd, msg, msgsize, priority) == -1) 00068 throw Error(errno); 00069 #else 00070 throw Error(ENOSYS); 00071 #endif 00072 } 00073 00074 /** 00075 Calls mq_receive. 00076 */ 00077 ssize_t PosixMsg::receive(char *msg, size_t msgsize, unsigned *priorityp) 00078 { 00079 #if _POSIX_MESSAGE_PASSING > 0 00080 ssize_t n; 00081 00082 if ((n = ::mq_receive(mqd, msg, msgsize, priorityp)) == -1) 00083 throw Error(errno); 00084 return n; 00085 #else 00086 throw Error(ENOSYS); 00087 #endif 00088 } 00089 00090 /** 00091 Calls mq_timedsend. 00092 */ 00093 void PosixMsg::timedsend(const char *msg, size_t msgsize, unsigned priority, const struct timespec *tmout) 00094 { 00095 #if _POSIX_MESSAGE_PASSING > 0 && _POSIX_TIMEOUTS > 0 00096 if (::mq_timedsend(mqd, msg, msgsize, priority, tmout) == -1) 00097 throw Error(errno); 00098 #else 00099 throw Error(ENOSYS); 00100 #endif 00101 } 00102 00103 /** 00104 Calls mq_timedreceive. 00105 */ 00106 ssize_t PosixMsg::timedreceive(char *msg, size_t msgsize, unsigned *priorityp, const struct timespec *tmout) 00107 { 00108 #if _POSIX_MESSAGE_PASSING > 0 && _POSIX_TIMEOUTS > 0 00109 ssize_t n; 00110 00111 if ((n = ::mq_timedreceive(mqd, msg, msgsize, priorityp, tmout)) == -1) 00112 throw Error(errno); 00113 return n; 00114 #else 00115 throw Error(ENOSYS); 00116 #endif 00117 } 00118 00119 /** 00120 Calls mq_notify. 00121 */ 00122 void PosixMsg::notify(const struct sigevent *ep) 00123 { 00124 #if _POSIX_MESSAGE_PASSING > 0 00125 if (::mq_notify(mqd, ep) == -1) 00126 throw Error(errno); 00127 #else 00128 throw Error(ENOSYS); 00129 #endif 00130 } 00131 00132 /** 00133 Calls mq_getattr. 00134 */ 00135 void PosixMsg::getattr(struct mq_attr *attr) 00136 { 00137 #if _POSIX_MESSAGE_PASSING > 0 00138 if (::mq_getattr(mqd, attr) == -1) 00139 throw Error(errno); 00140 #else 00141 throw Error(ENOSYS); 00142 #endif 00143 } 00144 00145 /** 00146 Calls mq_setattr. 00147 */ 00148 void PosixMsg::setattr(const struct mq_attr *attr, struct mq_attr *oldattr) 00149 { 00150 #if _POSIX_MESSAGE_PASSING > 0 00151 if (::mq_setattr(mqd, attr, oldattr) == -1) 00152 throw Error(errno); 00153 #else 00154 throw Error(ENOSYS); 00155 #endif 00156 } 00157 00158 /** 00159 Calls shm_open. 00160 */ 00161 void PosixShm::open(const char *name, int flags, mode_t perms) 00162 { 00163 #if _POSIX_SHARED_MEMORY_OBJECTS > 0 && !defined(LINUXs) 00164 if ((fd = ::shm_open(name, flags, perms)) == -1) 00165 throw Error(errno); 00166 #else 00167 throw Error(ENOSYS); 00168 #endif 00169 } 00170 00171 /** 00172 Calls shm_unlink. Could be static, as it doesn't refer to the fd. 00173 */ 00174 void PosixShm::unlink(const char *name) 00175 { 00176 #if _POSIX_SHARED_MEMORY_OBJECTS > 0 && !defined(LINUXs) 00177 if (::shm_unlink(name) == -1) 00178 throw Error(errno); 00179 #else 00180 throw Error(ENOSYS); 00181 #endif 00182 } 00183 00184 /** 00185 Calls mmap. Arguments are in a different order to take advantage of defaults, and fd 00186 argument comes from the class. 00187 */ 00188 void *PosixShm::mmap(size_t len, void *addr, int prot, int flags, off_t off) 00189 { 00190 void *p; 00191 00192 if ((p = ::mmap(addr, len, prot, flags, fd, off)) == MAP_FAILED) 00193 throw Error(errno); 00194 return p; 00195 } 00196 00197 /** 00198 Calls munmap. Could be static, as it doesn't refer to the fd. 00199 */ 00200 void PosixShm::munmap(void *addr, size_t len) 00201 { 00202 if (::munmap(addr, len) == -1) 00203 throw Error(errno); 00204 } 00205 00206 /** 00207 Calls sem_open. 00208 */ 00209 void PosixSem::open(const char *name, int flags, mode_t perms, unsigned value) 00210 { 00211 #if _POSIX_SEMAPHORES > 0 00212 if ((sem = ::sem_open(name, flags, perms, value)) == SEM_FAILED) 00213 throw Error(errno); 00214 #else 00215 throw Error(ENOSYS); 00216 #endif 00217 } 00218 00219 /** 00220 Calls sem_close. 00221 */ 00222 void PosixSem::close(void) 00223 { 00224 #if _POSIX_SEMAPHORES > 0 00225 if (::sem_close(sem) == -1) 00226 throw Error(errno); 00227 #else 00228 throw Error(ENOSYS); 00229 #endif 00230 } 00231 00232 /** 00233 Calls sem_destroy. 00234 */ 00235 void PosixSem::destroy(void) 00236 { 00237 #if _POSIX_SEMAPHORES > 0 00238 if (::sem_destroy(sem) == -1) 00239 throw Error(errno); 00240 #else 00241 throw Error(ENOSYS); 00242 #endif 00243 } 00244 00245 /** 00246 Calls sem_getvalue. 00247 */ 00248 void PosixSem::getvalue(int *valuep) 00249 { 00250 #if _POSIX_SEMAPHORES > 0 00251 if (::sem_getvalue(sem, valuep) == -1) 00252 throw Error(errno); 00253 #else 00254 throw Error(ENOSYS); 00255 #endif 00256 } 00257 00258 /** 00259 Calls sem_init. 00260 */ 00261 void PosixSem::init(int pshared, unsigned value) 00262 { 00263 #if _POSIX_SEMAPHORES > 0 00264 if (::sem_init(sem, pshared, value) == -1) 00265 throw Error(errno); 00266 #else 00267 throw Error(ENOSYS); 00268 #endif 00269 } 00270 00271 /** 00272 Calls sem_post. 00273 */ 00274 void PosixSem::post(void) 00275 { 00276 #if _POSIX_SEMAPHORES > 0 00277 if (::sem_post(sem) == -1) 00278 throw Error(errno); 00279 #else 00280 throw Error(ENOSYS); 00281 #endif 00282 } 00283 00284 /** 00285 Calls sem_timedwait. 00286 */ 00287 void PosixSem::timedwait(const struct timespec *time) 00288 { 00289 #if _POSIX_SEMAPHORES > 0 && _POSIX_TIMEOUTS > 0 00290 if (::sem_timedwait(sem, time) == -1) 00291 throw Error(errno); 00292 #else 00293 throw Error(ENOSYS); 00294 #endif 00295 } 00296 00297 /** 00298 Calls sem_trywait. 00299 */ 00300 void PosixSem::trywait(void) 00301 { 00302 #if _POSIX_SEMAPHORES > 0 00303 if (::sem_trywait(sem) == -1) 00304 throw Error(errno); 00305 #else 00306 throw Error(ENOSYS); 00307 #endif 00308 } 00309 00310 /** 00311 Calls sem_unlink. Could be static, as it doesn't use sem. 00312 */ 00313 void PosixSem::unlink(const char *name) 00314 { 00315 #if _POSIX_SEMAPHORES > 0 00316 if (::sem_unlink(name) == -1) 00317 throw Error(errno); 00318 #else 00319 throw Error(ENOSYS); 00320 #endif 00321 } 00322 00323 /** 00324 Calls sem_wait. 00325 */ 00326 void PosixSem::wait(void) 00327 { 00328 #if _POSIX_SEMAPHORES > 0 00329 if (::sem_wait(sem) == -1) 00330 throw Error(errno); 00331 #else 00332 throw Error(ENOSYS); 00333 #endif 00334 }