📄 ipcsockets.c
字号:
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 + -