+++ /dev/null
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <architecture/byte_order.h>
-#include <security_cdsa_utilities/cssmdb.h>
-#include "SharedMemoryClient.h"
-#include <string>
-#include <security_utilities/crc.h>
-
-static const char* kPrefix = "/var/db/mds/messages/se_";
-
-using namespace Security;
-
-SharedMemoryClient::SharedMemoryClient (const char* segmentName, SegmentOffsetType segmentSize)
-{
- StLock<Mutex> _(mMutex);
-
- mSegmentName = segmentName;
- mSegmentSize = segmentSize;
- mSegment = mDataArea = mDataPtr = 0;
-
- // make the name
- int segmentDescriptor;
- {
- std::string name (kPrefix);
- name += segmentName;
-
- // make a connection to the shared memory block
- segmentDescriptor = open (name.c_str (), O_RDONLY, S_IROTH);
- if (segmentDescriptor < 0) // error on opening the shared memory segment?
- {
- // CssmError::throwMe (CSSM_ERRCODE_INTERNAL_ERROR);
- return;
- }
- }
-
- // map the segment into place
- mSegment = (u_int8_t*) mmap (NULL, segmentSize, PROT_READ, MAP_SHARED, segmentDescriptor, 0);
- close (segmentDescriptor);
-
- if (mSegment == MAP_FAILED)
- {
- return;
- }
-
- mDataArea = mSegment + sizeof (SegmentOffsetType);
- mDataMax = mSegment + segmentSize;
- mDataPtr = mDataArea + GetProducerCount ();
-}
-
-
-
-SharedMemoryClient::~SharedMemoryClient ()
-{
- StLock<Mutex> _(mMutex);
- if (mSegment == NULL || mSegment == MAP_FAILED) // error on opening the shared memory segment?
- {
- CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
- }
- munmap (mSegment, mSegmentSize);
-}
-
-
-
-SegmentOffsetType SharedMemoryClient::GetProducerCount ()
-{
- if (mSegment == NULL || mSegment == MAP_FAILED) // error on opening the shared memory segment?
- {
- CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
- }
- return OSSwapBigToHostInt32 (*(u_int32_t*) mSegment);
-}
-
-
-
-const char* SharedMemoryClient::GetSegmentName ()
-{
- return mSegmentName.c_str ();
-}
-
-
-
-size_t SharedMemoryClient::GetSegmentSize ()
-{
- return mSegmentSize;
-}
-
-
-
-void SharedMemoryClient::ReadData (void* buffer, SegmentOffsetType length)
-{
- if (mSegment == NULL || mSegment == MAP_FAILED) // error on opening the shared memory segment?
- {
- CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
- }
-
- u_int8_t* bptr = (u_int8_t*) buffer;
-
- SegmentOffsetType bytesToEnd = (SegmentOffsetType)(mDataMax - mDataPtr);
-
- // figure out how many bytes we can read
- SegmentOffsetType bytesToRead = (length <= bytesToEnd) ? length : bytesToEnd;
-
- // move the first part of the data
- memcpy (bptr, mDataPtr, bytesToRead);
- bptr += bytesToRead;
-
- // see if we have anything else to read
- mDataPtr += bytesToRead;
-
- length -= bytesToRead;
- if (length != 0)
- {
- mDataPtr = mDataArea;
- memcpy(bptr, mDataPtr, length);
- mDataPtr += length;
- }
-}
-
-
-
-SegmentOffsetType SharedMemoryClient::ReadOffset()
-{
- SegmentOffsetType offset;
- ReadData(&offset, sizeof(SegmentOffsetType));
- offset = OSSwapBigToHostInt32 (offset);
- return offset;
-}
-
-
-
-bool SharedMemoryClient::ReadMessage (void* message, SegmentOffsetType &length, UnavailableReason &ur)
-{
- StLock<Mutex> _(mMutex);
-
- if (mSegment == NULL || mSegment == MAP_FAILED) // error on opening the shared memory segment?
- {
- CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
- }
-
- ur = kURNone;
-
- size_t offset = mDataPtr - mDataArea;
- if (offset == GetProducerCount())
- {
- ur = kURNoMessage;
- return false;
- }
-
- // get the length of the message in the buffer
- length = ReadOffset();
-
- // we have the possibility that data is correct, figure out where the data is actually located
- // get the length of the message stored there
- if (length == 0 || length >= kPoolAvailableForData)
- {
- if (length == 0)
- {
- ur = kURNoMessage;
- }
- else
- {
- ur = kURBufferCorrupt;
- }
-
- // something's gone wrong, reset.
- mDataPtr = mDataArea + GetProducerCount ();
- return false;
- }
-
- // read the crc
- SegmentOffsetType crc = ReadOffset();
-
- // read the data into the buffer
- ReadData (message, length);
-
- // calculate the CRC
- SegmentOffsetType crc2 = CalculateCRC((u_int8_t*) message, length);
- if (crc != crc2)
- {
- ur = kURBufferCorrupt;
- mDataPtr = mDataArea + GetProducerCount ();
- return false;
- }
-
- return true;
-}