Logo Search packages:      
Sourcecode: pcsc-lite version File versions  Download package

INTERNAL LONG MessageSend ( void *  buffer_void,
uint64_t  buffer_size,
int32_t  filedes 
)

Sends a menssage from client to server or vice-versa.

Writes the message in the shared file filedes.

Parameters:
[in]buffer_voidMessage to be sent.
[in]buffer_sizeSize of the message to send
[in]filedesSocket handle.
Return values:
SCARD_S_SUCCESSSuccess
SCARD_E_TIMEOUTTimeout.
SCARD_F_COMM_ERRORSocket is closed.
SCARD_F_COMM_ERRORA signal was received.

Definition at line 317 of file winscard_msg.c.

References SCARD_E_NO_SERVICE, SCARD_E_TIMEOUT, SCARD_F_COMM_ERROR, and SCARD_S_SUCCESS.

Referenced by MessageSendWithHeader(), SCardControl(), and SCardTransmit().

{
      char *buffer = buffer_void;

      /* default is success */
      LONG retval = SCARD_S_SUCCESS;

      /* how many bytes remains to be written */
      size_t remaining = buffer_size;

      /* repeat until all data is written */
      while (remaining > 0)
      {
            fd_set write_fd;
            int selret;

            FD_ZERO(&write_fd);
            FD_SET(filedes, &write_fd);

            selret = select(filedes + 1, NULL, &write_fd, NULL, NULL);

            /* try to write only when the file descriptor is writable */
            if (selret > 0)
            {
                  int written;

                  if (!FD_ISSET(filedes, &write_fd))
                  {
                        /* very strange situation. it should be an assert really */
                        retval = SCARD_F_COMM_ERROR;
                        break;
                  }
                  /* since we are a user library we can't play with signals
                   * The signals may already be used by the application */
#ifdef MSG_NOSIGNAL
                  /* Get EPIPE return code instead of SIGPIPE signal
                   * Works on Linux */
                  written = send(filedes, buffer, remaining, MSG_NOSIGNAL);
#else
                  /* we may get a SIGPIPE signal if the other side has closed */
                  written = write(filedes, buffer, remaining);
#endif

                  if (written > 0)
                  {
                        /* we wrote something */
                        buffer += written;
                        remaining -= written;
                  } else if (written == 0)
                  {
                        /* peer closed the socket */
                        retval = SCARD_F_COMM_ERROR;
                        break;
                  } else
                  {
                        /* we ignore the signals and socket full situations, all
                         * other errors are fatal */
                        if (errno != EINTR && errno != EAGAIN)
                        {
                              retval = SCARD_E_NO_SERVICE;
                              break;
                        }
                  }
            } else if (selret == 0)
            {
                  /* timeout */
                  retval = SCARD_E_TIMEOUT;
                  break;
            } else
            {
                  /* ignore signals */
                  if (errno != EINTR)
                  {
                        Log2(PCSC_LOG_ERROR, "select returns with failure: %s",
                              strerror(errno));
                        retval = SCARD_F_COMM_ERROR;
                        break;
                  }
            }
      }

      return retval;
}

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index