psptcpux.c
来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 1,005 行 · 第 1/2 页
C
1,005 行
return PSP_DUPLICATE; if (sock == -1) return PSP_FAILED; if ((lmcdata = psp_getMemory(sizeof(LMC_SERVER_DATA), 0)) == NULL) { close(sock); unlink(tokfile); return PSP_NOMEMORY; } lmcdata->clients = psp_getMemory(maxclients * sizeof(LMC_CLIENT_DATA), 0); if (lmcdata->clients == NULL) { psp_freeMemory(lmcdata, 0); close(sock); unlink(tokfile); return PSP_NOMEMORY; } lmcdata->count = 0; FD_ZERO(&lmcdata->holdFDS); FD_SET(sock, &lmcdata->holdFDS); lmcdata->sock1 = sock; lmcdata->sock2 = -1; if (tokfile[0]) lmcdata->tokfile = psp_strdup(tokfile, 0); else lmcdata->tokfile = NULL; lmcdata->numclients = 0; lmcdata->maxclients = maxclients; *data = lmcdata; return PSP_OKAY;}#endif/* ========================================================================== Handle a new connection*/static void new_connection( int listensock, LMC_SERVER_DATA *lmcdata){ int ii; int len; int sock; LMC_CLIENT_DATA *client; FD_CLR(listensock, &lmcdata->FDS); for (ii = 0; ii < lmcdata->maxclients; ii++) { if (!lmcdata->clients[ii]) break; } if (ii == lmcdata->maxclients) return; if ((client = psp_getMemory(sizeof(LMC_CLIENT_DATA), 0)) == NULL) return; lmcdata->count--; do { len = sizeof(saddr); sock = accept(listensock, (struct sockaddr *) &client->addrinfo, &len); if (sock == -1 && errno != EINTR) { psp_freeMemory(client, 0); return; } } while (sock == -1); client->sock = sock; FD_SET(sock, &lmcdata->holdFDS); if (++lmcdata->numclients == lmcdata->maxclients) { listen(lmcdata->sock1, 0); if (lmcdata->sock2 >= 0) listen(lmcdata->sock2, 0); } lmcdata->clients[ii] = client;}/* ========================================================================== Check for a message or new connection*/static void *handle_data( LMC_SERVER_DATA *lmcdata){ int ii; LMC_CLIENT_DATA **clients; if (lmcdata->sock1 != -1 && FD_ISSET(lmcdata->sock1, &lmcdata->FDS)) new_connection(lmcdata->sock1, lmcdata); if (lmcdata->sock2 >= 0 && FD_ISSET(lmcdata->sock2, &lmcdata->FDS)) new_connection(lmcdata->sock2, lmcdata); if (lmcdata->count) { clients = lmcdata->clients; for (ii = 0; ii < lmcdata->maxclients; ii++) { if (clients[ii] && FD_ISSET(clients[ii]->sock, &lmcdata->FDS)) { FD_CLR(lmcdata->clients[ii]->sock, &lmcdata->FDS); lmcdata->count--; return clients[ii]; } } } lmcdata->count = 0; /* just to be sure */ return NULL; /* timeout */}/* ========================================================================== Wait for a message*/static void *psp_socket_waitmsg( void *data, long timeout){ struct timeval tmout; LMC_SERVER_DATA *lmcdata = (LMC_SERVER_DATA *) data; if (!data) return NULL; if (lmcdata->count) return handle_data(lmcdata); tmout.tv_sec = timeout / 1000; tmout.tv_usec = (timeout % 1000) * 1000; memcpy(&lmcdata->FDS, &lmcdata->holdFDS, sizeof(fd_set)); lmcdata->count = select(FD_SETSIZE, &lmcdata->FDS, NULL, NULL, &tmout); if (lmcdata->count == -1) return NULL; if (lmcdata->count) return handle_data(lmcdata); return NULL; /* timeout */}/* ========================================================================== Shut down the listen*/static void psp_socket_stoplisten( void *data){ int ii; LMC_SERVER_DATA *lmcdata; LMC_CLIENT_DATA **clients; if (!data) return; lmcdata = (LMC_SERVER_DATA *) data; if (lmcdata->numclients > 0) { clients = lmcdata->clients; for (ii = 0; ii < lmcdata->maxclients; ii++) { if (clients[ii]) { close(clients[ii]->sock); psp_freeMemory(clients[ii], 0); } } } close(lmcdata->sock1); if (lmcdata->sock2 >= 0) close(lmcdata->sock2); if (lmcdata->tokfile) { unlink(lmcdata->tokfile); psp_freeMemory(lmcdata->tokfile, 0); } psp_freeMemory(lmcdata->clients, 0); psp_freeMemory(lmcdata, 0);}/* ========================================================================== Close the client connection*/static void psp_socket_disconclient( void *data, void *cdata){ int ii; LMC_SERVER_DATA *lmcdata; LMC_CLIENT_DATA *client; if (!data || !cdata) return; lmcdata = (LMC_SERVER_DATA *) data; client = (LMC_CLIENT_DATA *) cdata; close(client->sock); FD_CLR(client->sock, &lmcdata->holdFDS); if (lmcdata->numclients-- == lmcdata->maxclients) { listen(lmcdata->sock1, 5); if (lmcdata->sock2 >= 0) listen(lmcdata->sock2, 5); } if (FD_ISSET(client->sock, &lmcdata->FDS)) { FD_CLR(client->sock, &lmcdata->FDS); lmcdata->count--; } for (ii = 0; ii < lmcdata->maxclients; ii++) { if (client == lmcdata->clients[ii]) { psp_freeMemory(client, 0); lmcdata->clients[ii] = NULL; } }}/* ========================================================================== Close the connection*/static void psp_socket_disconnect( void *data){ LMC_CLIENT_DATA *lmcdata; if (!data) return; lmcdata = (LMC_CLIENT_DATA *) data; shutdown(lmcdata->sock, 2); close(lmcdata->sock);/* signal(SIGPIPE, lmcdata->pipefcn); */ if (lmcdata->tokfile) psp_freeMemory(lmcdata->tokfile, 0); psp_freeMemory(lmcdata, 0);}/* ========================================================================== Send a message on a socket*/static int socket_send( const MSG_HDR *hdr, const void *msg, int len, int sock){ int bytes; const char *cp; while (send(sock, (const char *) hdr, sizeof(MSG_HDR), 0) == -1) { if (errno != EINTR) return PSP_DISCONNECTED; } cp = msg; while (len) { if ((bytes = send(sock, cp, len, 0)) == -1) { if (errno == EINTR) continue; return PSP_DISCONNECTED; } len -= bytes; cp += bytes; } return PSP_OKAY;}/* ========================================================================== TCP/IP specific send function*/static int psp_tcp_send( const void *msg, size_t len, const void *data){ MSG_HDR hdr; hdr.db_star_id = htonl(DB_STAR_ID); hdr.msglen = htonl(len); return socket_send(&hdr, msg, (int) len, ((LMC_CLIENT_DATA *) data)->sock);}/* ========================================================================== Receive data from a socket*/static int socket_receive( void *msg, int len, int sock){ char *cp = msg; int bytes; do { if ((bytes = recv(sock, cp, len, 0)) <= 0) { if (errno == EINTR) continue; return PSP_DISCONNECTED; } len -= bytes; cp += bytes; } while (len); return PSP_OKAY;}/* ========================================================================== TCP/IP specific receive function*/static int psp_tcp_receive( void **msg, size_t *len, const void *data){ int stat; int sock = ((LMC_CLIENT_DATA *) data)->sock; MSG_HDR hdr; if ((stat = socket_receive(&hdr, sizeof(hdr), sock)) != PSP_OKAY) return stat; if (ntohl(hdr.db_star_id) != DB_STAR_ID) return PSP_INVMSG; *len = ntohl(hdr.msglen); if ((*msg = psp_getMemory(*len, 0)) == NULL) return PSP_NOMEMORY; return socket_receive(*msg, (int) *len, sock);}static void psp_socket_info( const void *data, char *line1, char *line2, char *line3){ saddr *sa = &((LMC_CLIENT_DATA *) data)->addrinfo; if (sa->in.sin_family == AF_INET) { strcpy(line1, "TCP/IP socket connection"); sprintf(line2, "Address: %s", inet_ntoa(sa->in.sin_addr)); } else { strcpy(line1, "Unix domain socket connection"); line2[0] = '\0'; } line3[0] = '\0';} #if !defined(NO_UNIX_DOMAIN) /* ========================================================================== Check to see if IP (Unix Domain sockets) is available*/int psp_ip_avail( int *flags, LOCKCOMM_FCNS **fcns){ *fcns = &ip_lockcomm; return PSP_OKAY;}/* ========================================================================== IP (Unix Domain sockets) specific connect*/static int ip_connect( const char *name, const char *tmp, char *tokfile, int timeout){ int ii; int sock; int addr_len; struct protoent *protocol; struct sockaddr *sockaddr = NULL; struct sockaddr_un sockaddr_un; /* Set up the token file for local IP attempt */ strcpy(tokfile, tmp); strcat(tokfile, name); protocol = getprotobyname("ip"); sockaddr = (struct sockaddr *) &sockaddr_un; addr_len = sizeof(sockaddr_un.sun_family) + strlen(tokfile) + 1; sockaddr_un.sun_family = AF_UNIX; strncpy(sockaddr_un.sun_path, tokfile, sizeof(sockaddr_un.sun_path)); sockaddr_un.sun_path[sizeof(sockaddr_un.sun_path) - 1] = '\0'; /* The first connect may fail if there is a lot of activity on the lockmgr. */ sock = socket(sockaddr_un.sun_family, SOCK_STREAM, protocol->p_proto); if (sock != -1) { for (ii = 0; ii < timeout; ii++) { if (connect(sock, sockaddr, addr_len) != -1) break; /* TBD: Log out error *//* printf("ip connect fail: %s (%d)\n", strerror(errno), errno); */ psp_sleep(1); } if (ii == timeout) { close(sock); return -1; } } return sock;}/* ========================================================================== Open a connection using IP (Unix Domain sockets)*/static int psp_ip_connect( const char *lockmgr, const char *tmp, const char *id, void **data){ int ii; int sock = -1; char tokfile[80]; LMC_CLIENT_DATA *lmcdata; /* TBD: Need to get timeout value (net_timeout) from db.star.ini. */ int timeout = 5; if ((sock = ip_connect(lockmgr, tmp, tokfile, timeout)) == -1) return PSP_FAILED; /* Allocate control data buffer */ lmcdata = (LMC_CLIENT_DATA *) psp_cGetMemory(sizeof(LMC_CLIENT_DATA), 0); if (lmcdata == NULL) return PSP_NOMEMORY; lmcdata->sock = sock;/* lmcdata->pipefcn = signal(SIGPIPE, SIG_IGN); */ lmcdata->tokfile = psp_strdup(tokfile, 0); *data = lmcdata; return PSP_OKAY;}/* ========================================================================== IP (Unix Domain sockets) specific send*/static int psp_ip_send( const void *msg, size_t len, const void *data){ MSG_HDR hdr; hdr.db_star_id = DB_STAR_ID; hdr.msglen = len; return socket_send(&hdr, msg, (int) len, ((LMC_CLIENT_DATA *) data)->sock);}/* ========================================================================== IP (Unix Domain sockets) specific send*/static int psp_ip_receive( void **msg, size_t *len, const void *data){ int stat; int sock = ((LMC_CLIENT_DATA *) data)->sock; MSG_HDR hdr; if ((stat = socket_receive(&hdr, sizeof(hdr), sock)) != PSP_OKAY) return stat; if (hdr.db_star_id != DB_STAR_ID) return PSP_INVMSG; *len = hdr.msglen; if ((*msg = psp_getMemory(*len, 0)) == NULL) return PSP_NOMEMORY; return socket_receive(*msg, (int) *len, sock);}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?