📄 simusched.c
字号:
#define SCO 1#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <stddef.h>#include <string.h>#include <errno.h>#include <signal.h>#include <fcntl.h>#include <unistd.h>#include <netdb.h>#include <sys/types.h>#include <sys/time.h>#ifndef HPUX#include <sys/select.h>#endif#include <sys/socket.h>#ifndef SCO#include <sys/socketvar.h>#endif#include <netinet/in.h>#include <arpa/inet.h>#include "simu112.h"#ifdef WIN32_ENV#include <io.h>#endifSOCKETSTRUCT so[MAX_FD];void ProcessCallback(int socket_fd);/*extern sig_atomic_t Child_died; *//*************************************************************** ****************************************************************/int attachClient(int fd, void *buf, int cnt){ int sd; struct sockaddr_in sock_addr; int sock_len; sock_len = sizeof(sock_addr); sd = accept(fd, (struct sockaddr *) &sock_addr, &sock_len); if (sd < 0) { /* error */ return (-1); } attachSocket(sd, clientRequest, IS_CLIENT); return (0);}/*:**************************************************************************** Function Name: attachSocket Param: socket_fd - File descriptor of socket fptr - Call-back function pointer whtype - indicate the so's type Return: - handle to use to scheduler or (-1) error. The handle will be the file descriptor of output. *************************************************************************** */int attachSocket(int socket_fd, CBF fptr, int whtype){ /* note: must handle running case different from stoped !!! */ if (socket_fd < 0) return (-1); if (socket_fd >= MAX_FD) return (-1); /* !!!! add here check of existing entry !!!!! */ /* clear entry */ memset((void *) &so[socket_fd], 0, sizeof(SOCKETSTRUCT)); /* get buffer */ so[socket_fd].count++; so[socket_fd].whichType = whtype; so[socket_fd].readSize = TL1_MAX; switch (whtype) { case 1: if ((so[socket_fd].readBuffer = (unsigned char *) malloc((size_t) 1)) == NULL) { /* can't get space */ return (-1); } if ((so[socket_fd].writeBuffer = (unsigned char *) malloc((size_t) 1)) == NULL) { /* can't get space */ free(so[socket_fd].readBuffer); return (-1); } so[socket_fd].status = STATUS_READY; printf("Listen Socket, SocketID=%d, Type=%d\n", socket_fd, whtype); break; case 2: if ((so[socket_fd].readBuffer = (unsigned char *) malloc((size_t) TL1_MAX)) == NULL) { /* can't get space */ return (-1); } if ((so[socket_fd].writeBuffer = (unsigned char *) malloc((size_t) TL1_MAX)) == NULL) { /* can't get space */ free(so[socket_fd].readBuffer); return (-1); } so[socket_fd].status = STATUS_READY; printf("New Client Connect SocketID=%d, Type=%d\n", socket_fd, whtype); break; case 3: if ((so[socket_fd].readBuffer = (unsigned char *) malloc((size_t) TL1_MAX)) == NULL) { /* can't get space */ return (-1); } if ((so[socket_fd].writeBuffer = (unsigned char *) malloc(sizeof(TESTREQMSG))) == NULL) { /* can't get space */ free(so[socket_fd].readBuffer); return (-1); } so[socket_fd].status = STATUS_CONNECT; printf("New Drive Connect SocketID=%d, Type=%d\n", socket_fd, whtype); } /* populate structure */ so[socket_fd].cbfptr = fptr; /* make input file descriptor none blocking */ /* !!!!! This may be crashing uniface */ /* fcntl(socket_fd,F_SETFL,O_NONBLOCK); */ return 0;}void ProcessCallback(int socket_fd){ int j; if (so[socket_fd].cbfptr == NULL) { return; /* no call back function available */ } j = so[socket_fd].cbfptr( socket_fd, so[socket_fd].readBuffer, so[socket_fd].readOffset ); /* Note: it is possible the socket was closed by function */ if (so[socket_fd].readBuffer == NULL) { /* socket was closed so we are done */ return; } so[socket_fd].readOffset = j;}/*:************************************************************************** Function Name: schedProcess Param: Return: - void *************************************************************************** */void schedProcess(){ fd_set rfds, wfds; int i, j, l, m, iselect; long temp; struct timeval tv, *timeout; while (1) {/* handle_child_died(); *//* !!!! add here process timers and get value to set */ tv.tv_sec = processTimers(); tv.tv_usec = 0; if (tv.tv_sec) { timeout = &tv; } else { timeout = NULL; } /* setup select statement */ FD_ZERO(&rfds); for (i = 0; i < MAX_FD; i++) { if ((so[i].readBuffer != NULL) && (so[i].status == STATUS_READY)) { FD_SET(i, &rfds); } }/* FD_ZERO(&wfds); for(i = 0; i <MAX_FD; i++) { if((so[i].status == STATUS_CONNECT) ||(so[i].status == STATUS_READY)){ FD_SET(i,&wfds); max_fd++; } *//* see if any output is pending (consider it any more) *//* if (so[i].writeOffset != so[i].writeSize) { FD_SET(i,&wfds); } } /* call select */#ifndef WIN32_ENV iselect = select(MAX_FD + 1, &rfds, (fd_set *) 0, (fd_set *) 0, timeout);#else iselect = select(max_fd, &rfds, NULL, NULL, timeout);#endif /* Note: we may want to allow a hook for signal return later */ if (iselect <= 0) { /* Go to top of loop and process timers etc. */ continue; } /* process sockets which have become available for writing *//* for(i=0; i <MAX_FD; i++) { if(FD_ISSET(i,&wfds)) { switch(so[i].status) { case STATUS_CONNECT: so[i].status = STATUS_READY; *//* notify caller *//* if(so[i].cbfptr != NULL) { so[i].cbfptr(i,so[i].writeBuffer,0); } break; default: *//* see if there is something in writeBuffer to send *//* while(so[i].writeOffset != so[i].writeSize) { *//* !!!! try to send block *//* l =so[i].writeSize - so[i].writeOffset+1; *//* this is the count to send *//*#ifdef WIN32_ENV m = send(i,&so[i].writeBuffer[so[i].writeOffset],l,0); #else m = write(i,&so[i].writeBuffer[so[i].writeOffset],l); #endif if (m < 0) { #ifndef WIN32_ENV if(errno == EWOULDBLOCK) { *//* can not do it now *//* break; } else { #endif *//* error throw it all away *//* so[i].writeOffset=so[i].writeSize=0; break; #ifndef WIN32_ENV } #endif } if(m == l) { memset((void *)so[i].writeBuffer,0,so[i].writeSize); so[i].writeOffset=so[i].writeSize=0; continue; } *//* just partial so upDate out pointer *//* so[i].writeOffset += m; break; } break; } } } */ /* process pending input */ for (i = 0; i < MAX_FD; i++) { if (FD_ISSET(i, &rfds)) { switch (so[i].whichType) { case IS_HIMSELF: /* listen socket */ if (so[i].cbfptr != NULL) { so[i].cbfptr(i, "0", 0); } continue; break; default: /* !!!! read into buffer and call process */ if (so[i].readBuffer == NULL) { /* we were closed above */ continue; } /* insure last byte is not used so we can null terminate */ temp = (so[i].readSize - so[i].readOffset) - 1;#ifdef WIN32_ENV j = recv(i, &so[i].readBuffer[so[i].readOffset], temp, 0);#else j = read(i, &so[i].readBuffer[so[i].readOffset], temp);#endif /* printf("read_fd:%d,read_size:%d\n",i,j); */ if (j < 0) {#ifndef WIN32_ENV if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) { /* This is what occurs when listening on socket */ if (so[i].cbfptr != NULL) { so[i].cbfptr(i, "0", 0); } continue; /* ignore this */ } else {#endif /* we have an error */ if (so[i].cbfptr != NULL) { so[i].cbfptr(i, NULL, j); } continue;#ifndef WIN32_ENV }#endif } /* !!!! if j == 0 then EOF ??how to process */ if (j > 0) { so[i].readOffset += j; } if (j == 0) { /* buffer is not null cause that will indicate eof */ if (so[i].cbfptr != NULL) { so[i].cbfptr(i, NULL, 0); } continue; /* no more data */ } ProcessCallback(i); } /*switch */ } } /*process pending input for */ } /*while */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -