⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipcsockets.c

📁 支持数字元件仿真的SPICE插件
💻 C
📖 第 1 页 / 共 2 页
字号:
    NONESUMMARY  Read N bytes from a socket. Only returns when the read had an error,  when 0 bytes (EOF) could be read, or LENGTH bytes are read.INTERFACES  Local to this file.  Called by:  ipc_transport_get_line();RETURNED VALUE      int - Returns the total number of bytes read.GLOBAL VARIABLES        NONENON-STANDARD FEATURES    NONE     =============================================================================*/static int read_sock (stream, buffer, length, wait, flags)     int          stream;   /* IN - Socket stream                          */     char         *buffer;  /* OUT - buffer to store incoming data         */     int          length;   /* IN - Number of bytes to be read             */     Ipc_Wait_t   wait;     /* IN - type of read operation                 */     int          flags;    /* IN - Original socket flags for blocking read */{  int   count;			/* Number of bytes read with last `read`    */  int   totalcount;		/* total number of bytes read               */  char  *buf2;  /*  count = 0;                                                               *//*  while (count < length) {                                                 *//*    buffer[count] = 'x';                                                   *//*    count++;                                                               *//*  }                                                                        */  count = read (stream, buffer, length);  if (wait == IPC_NO_WAIT) {    fcntl (stream, F_SETFL, flags); /* Revert to blocking read           */  }  if ((count <= 0) || (count == length)) {    /* If error or if read in reqd number of bytes:                        */    return count;  } else {    /* Only got some of the bytes requested                                */    totalcount = count;    buf2 = &buffer[totalcount];    length = length - count;    while (length > 0) {      count = read (stream, buf2, length);      if (count <= 0)		/* EOF or read error                 */	break;      totalcount = totalcount + count;      buf2 = &buffer[totalcount];      length = length - count;    }    if (length != 0) {      fprintf (stderr, "WARNING: READ_SOCK read %d bytes instead of %d\n",	       totalcount, totalcount + length);    }    return totalcount;  }}				/* end read_sock *//*=============================================================================FUNCTION ipc_transport_get_lineAUTHORS                          July 1991   Stefan RothMODIFICATIONS       NONESUMMARY  Main function for reading one line from a socket. Requires that the  socket be open. Lines are mostly SPICE code, but commands may also  be embedded in the socket data and they are interpreted by this function.  Therefore, this function may cause the socket to be closed.INTERFACES              Called by:  ipc_transport_terminate_server();              (IPC.c) ipc_get_line();RETURNED VALUE      Ipc_Status_t - returns status of the read operationGLOBAL VARIABLES        NONENON-STANDARD FEATURES    NONE     =============================================================================*/Ipc_Status_t ipc_transport_get_line (str, len, wait)     char               *str;    /* returns the result, null terminated    */     int                *len;    /* length of str passed IN and passed OUT */     Ipc_Wait_t         wait;    /* IN - wait or dont wait on incoming msg */{  int count;                     /* number of bytes read                   */  int message_length;            /* extracted from message header          */  if (sock_state == IPC_SOCK_UNINITIALIZED) {    fprintf (stderr,	    "ERROR: IPC: Attempted to read from uninitialized socket\n");    return IPC_STATUS_ERROR;  }    assert ((sock_state == IPC_SOCK_CONNECTED_TO_CLIENT) ||	  (sock_state == IPC_SOCK_INITIALIZED));  if (sock_state == IPC_SOCK_INITIALIZED) {    /* We have an open socket but have not connected to a client.          */    /* Accept a connection from a client.                                  */    msg_stream = accept (sock_desc, (struct sockaddr *)0, (int *)0);    if (msg_stream == -1) {      fprintf (stderr, "ERROR: IPC: Server accepting request\n");      perror ("ERROR: IPC");      return IPC_STATUS_ERROR;    }    sock_state = IPC_SOCK_CONNECTED_TO_CLIENT;  }  /*-----------------------------------------------------------------------*/  /* First read in the message header.                                     */  {    int flags;    flags = fcntl(msg_stream, F_GETFL, NULL);    /* Blocking read mode     */    if (wait == IPC_WAIT) {      /* Block here and wait for the next message                          */      count = read_sock (msg_stream, str, SOCK_MSG_HDR_LEN, wait, flags);      if (count == 0) {	/* EOF, will this ever happen?                                     */	/* fprintf (stderr, "WARNING: IPC: Reached eof on socket\n");  */	return handle_socket_eof ();      }    } else if (wait == IPC_NO_WAIT) {      /* Read message, but do not wait if none available.                  */      fcntl (msg_stream, F_SETFL, flags | O_NDELAY);      count = read_sock (msg_stream, str, SOCK_MSG_HDR_LEN, wait, flags);      if (count == 0) {	/* EOF, will this ever happen?                                     */	/* fprintf (stderr, "WARNING: IPC: Reached eof on socket\n");  */	return handle_socket_eof ();      } else if (count == -1) {	if (errno == EWOULDBLOCK) {	  return IPC_STATUS_NO_DATA;	}      }    } else {      /* Serious problem, since it is not reading anything.                */      fprintf (stderr,	       "ERROR: IPC: invalid wait arg to ipc_transport_get_line\n");    }  }    /* Do more error checking on the read in values of the message header:   */  if (count == -1) {    fprintf (stderr, "ERROR: IPC: Reading from socket\n");    perror ("ERROR: IPC");    return IPC_STATUS_ERROR;  } else if (str[0] != BOL_CHAR) {    fprintf (stderr,	     "ERROR: IPC: Did not find beginning of message header (%c)\n",	     str[0]);    return IPC_STATUS_ERROR;  } else if ((message_length = bytes_to_integer (str, 1)) == -1) {    /* fprintf (stderr, "WARNING: IPC: Reached eof on socket\n");      */    return handle_socket_eof ();  } else if (message_length == 0) {    *len = 0;    return IPC_STATUS_NO_DATA;/*  Invalid test... delete - wbk  } else if (message_length > *len) {    fprintf (stderr,	     "ERROR: IPC: Buffer (%d) is too short for message (%d)\n",	     *len, message_length);    return IPC_STATUS_ERROR;*/  }  /*-----------------------------------------------------------------------*/  /* Now read in the message body.                                         */  /* Always block here since the message header was already read and       */  /* we must get the body.                                                 */  *len = message_length;  count = read_sock (msg_stream, str, message_length);  if (count == 0) {    /* EOF, will this ever happen? */    /* fprintf (stderr,                                                    */    /*          "WARNING: IPC: Reached eof in message body on socket\n");*/    return handle_socket_eof ();  } else if (count == -1) {    fprintf (stderr, "ERROR: IPC: reading message body from socket\n");    perror ("ERROR: IPC");    return IPC_STATUS_ERROR;  }    /* Looks like we have a valid message here. Put in the string terminator. */  *len == count;  str[count] = '\0';  return IPC_STATUS_OK;}   /* end ipc_transport_get_line */ /*=============================================================================FUNCTION ipc_transport_send_lineAUTHORS                          July 1991   Stefan RothMODIFICATIONS       NONESUMMARY  Send a line of information. First sends a message header and  then the actual message body.  Error checking is done to make reasonably sure that the data was sent.    INTERFACES              Called by:   (IPC.c)   ipc_flush ();RETURNED VALUE  Ipc_Status_t - returns status of the send operation (typically  IPC_STATUS_ERROR or IPC_STATUS_OK).GLOBAL VARIABLES      NONENON-STANDARD FEATURES  NONE     =============================================================================*/Ipc_Status_t ipc_transport_send_line (str, len)     char *str;           /* IN - String to write                          */     int len;             /* IN - Number of characters out of STR to write */{  int count;              /* Counts how many bytes were actually written   */  u_long u;               /* 32-bit placeholder for transmission of LEN    */  char hdr_buff[5];       /* Buffer for building header message in         */  int  i;                 /* Temporary counter                             */  char *char_ptr;         /* Pointer for int to bytes conversion           */  if (sock_state != IPC_SOCK_CONNECTED_TO_CLIENT) {    fprintf (stderr, "ERROR: IPC: Attempt to write to non-open socket\n");    return IPC_STATUS_ERROR;  }  /* Write message body header with length: */  hdr_buff[0] = BOL_CHAR;  u = htonl (len);  char_ptr = (char *) &u;  for(i = 0; i < 4; i++)    hdr_buff[i+1] = char_ptr[i];  count = write (msg_stream, hdr_buff, 5);  if (count != 5) {    fprintf (stderr, "ERROR: IPC: (%d) send line error 1\n", count);    return IPC_STATUS_ERROR;  }  /* Write message body: */  count = write (msg_stream, str, len);  if (count != len) {    fprintf (stderr, "ERROR: IPC: (%d) send line error 2\n", count);    return IPC_STATUS_ERROR;  }  return IPC_STATUS_OK;}   /* end ipc_transport_send_line *//*=============================================================================FUNCTION ipc_transport_terminate_serverAUTHORS                          July 1991   Stefan RothMODIFICATIONS       NONESUMMARY  This function reads all pending incoming messages and discards them.  Reading continues until a read error occurs or EOF is reached, at which  time the socket is closed.  Note that this function does not actually close the socket. This is  done in ipc_transport_get_line, which is called in this function.  In this function, the incoming line length is limited. See buffer below.INTERFACES                Called by:  (IPC.c)   ipc_terminate_server();RETURNED VALUE        Ipc_Status_t - returns status of last read operation (always    IPC_STATUS_ERROR or IPC_STATUS_EOF).GLOBAL VARIABLES        NONENON-STANDARD FEATURES    NONE     =============================================================================*/Ipc_Status_t ipc_transport_terminate_server (){   char buffer[17000];		/* temp buffer for incoming data           */   int len;			/* placeholder var to as arg to function   */   Ipc_Status_t status;		/* value to be returned from function      */   int max_size;		/* Max length of buffer                    */   max_size = sizeof (buffer);   do {     len = max_size;     status = ipc_transport_get_line (buffer, &len, IPC_WAIT);   } while ((status != IPC_STATUS_ERROR) &&	    (status != IPC_STATUS_EOF));   return status;}#endif  /* IPC_UNIX_SOCKETS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -