Beispiel #1
0
tcmRet oalMsg_receive(int fd, tcmMsgHeader **buf, unsigned int *timeout)
{
   tcmMsgHeader *msg;
   int rc;
   tcmRet ret;

   if (buf == NULL)
   {
      return TCMRET_INVALID_PARAMETER;
   }
   else
   {
      *buf = NULL;
   }

   if (timeout)
   {
      if ((ret = waitForDataAvailable(fd, *timeout)) != TCMRET_SUCCESS)
      {
         return ret;
      }
   }

   /*
    * Read just the header in the first read.
    * Do not try to read more because we might get part of
    * another message in the TCP socket.
    */
   msg = (tcmMsgHeader *) malloc(sizeof(tcmMsgHeader));
   if (msg == NULL)
   {
      return TCMRET_INTERNAL_ERROR;
   }

   rc = read(fd, msg, sizeof(tcmMsgHeader));
   if ((rc == 0) ||
       ((rc == -1) && (errno == 131)))  /* new 2.6.21 kernel seems to give us this before rc==0 */
   {
      /* broken connection */
      free(msg);
      return TCMRET_DISCONNECTED;
   }
   else if (rc < 0 || rc != sizeof(tcmMsgHeader))
   {
      free(msg);
      return TCMRET_INTERNAL_ERROR;
   }

   if (msg->dataLength > 0)
   {
      int totalReadSoFar=0;
      int totalRemaining=msg->dataLength;
      char *inBuf;

      /* there is additional data in the message */
      msg = (tcmMsgHeader *) realloc(msg, sizeof(tcmMsgHeader) + msg->dataLength);
      if (msg == NULL)
      {
         free(msg);
         return TCMRET_DISCONNECTED;
      }

      inBuf = (char *) (msg + 1);
      while (totalReadSoFar < msg->dataLength)
      {
         if (timeout)
         {
            if ((ret = waitForDataAvailable(fd, *timeout)) != TCMRET_SUCCESS)
            {
               free(msg);
               return ret;
            }
         }

         rc = read(fd, inBuf, totalRemaining);
         if (rc <= 0)
         {
            free(msg);
            return TCMRET_INTERNAL_ERROR;
         }
         else
         {
            inBuf += rc;
            totalReadSoFar += rc;
            totalRemaining -= rc;
         }
      }
   }

   *buf = msg;

   return TCMRET_SUCCESS;
}
CmsRet oalMsg_receive(SINT32 fd, CmsMsgHeader **buf, UINT32 *timeout)
{
   CmsMsgHeader *msg;
   SINT32 rc;
   CmsRet ret;

   if (buf == NULL)
   {
      cmsLog_error("buf is NULL!");
      return CMSRET_INVALID_ARGUMENTS;
   }
   else
   {
      *buf = NULL;
   }

   if (timeout)
   {
      if ((ret = waitForDataAvailable(fd, *timeout)) != CMSRET_SUCCESS)
      {
         return ret;
      }
   }

   /*
    * Read just the header in the first read.
    * Do not try to read more because we might get part of 
    * another message in the TCP socket.
    */
   msg = (CmsMsgHeader *) cmsMem_alloc(sizeof(CmsMsgHeader), ALLOC_ZEROIZE);
   if (msg == NULL)
   {
      cmsLog_error("alloc of msg header failed");
      return CMSRET_RESOURCE_EXCEEDED;
   }

   rc = read(fd, msg, sizeof(CmsMsgHeader));
   if ((rc == 0) ||
       ((rc == -1) && (errno == 131)))  /* new 2.6.21 kernel seems to give us this before rc==0 */
   {
      /* broken connection */
      cmsMem_free(msg);
      return CMSRET_DISCONNECTED;
   }
   else if (rc < 0 || rc != sizeof(CmsMsgHeader))
   {
      cmsLog_error("bad read, rc=%d errno=%d", rc, errno);
      cmsMem_free(msg);
      return CMSRET_INTERNAL_ERROR;
   }

   if (msg->dataLength > 0)
   {
      SINT32 totalReadSoFar=0;
      SINT32 totalRemaining=msg->dataLength;
      char *inBuf;

      /* there is additional data in the message */
      msg = (CmsMsgHeader *) cmsMem_realloc(msg, sizeof(CmsMsgHeader) + msg->dataLength);
      if (msg == NULL)
      {
         cmsLog_error("realloc to %d bytes failed", sizeof(CmsMsgHeader) + msg->dataLength);
         cmsMem_free(msg);
         return CMSRET_RESOURCE_EXCEEDED;
      }

      inBuf = (char *) (msg + 1);
      while (totalReadSoFar < msg->dataLength)
      {
         cmsLog_debug("reading segment: soFar=%d total=%d", totalReadSoFar, totalRemaining);
         if (timeout)
         {
            if ((ret = waitForDataAvailable(fd, *timeout)) != CMSRET_SUCCESS)
            {
               cmsMem_free(msg);
               return ret;
            }
         }

         rc = read(fd, inBuf, totalRemaining);
         if (rc <= 0)
         {
            cmsLog_error("bad data read, rc=%d errno=%d readSoFar=%d remaining=%d", rc, errno, totalReadSoFar, totalRemaining);
            cmsMem_free(msg);
            return CMSRET_INTERNAL_ERROR;
         }
         else
         {
            inBuf += rc;
            totalReadSoFar += rc;
            totalRemaining -= rc;
         }
      }
   }

   *buf = msg;

   return CMSRET_SUCCESS;
}