Open System Services Programmer's Guide
Example 40 Static Echo Server
/* sserver.c
*
* Simple OSS server example using OSS APIs for communication
* between requester and server.
*
* sserver is a static echo server. A sserver process is launched
* for each cpu with stdin being used for fd passing from slaunch
* to sserver. When an fd is passed to sserver, it adds it to an
* fdset and then echoes the input on that connection.
*/
#define _XOPEN_SOURCE_EXTENDED 1 /* needed for OSS sockets */
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <tdmext.h>
/* Guardian APIs */
#include <cextdecs.h(PROCESSHANDLE_GETMINE_, \
PROCESSHANDLE_DECOMPOSE_, PROCESSORSTATUS)>
short cpu, phandle[10]; /* our cpu and process handle */
int fd, fdpassfd, newfd, highfd, fdcount, readycount, bytesread;
struct sockaddr_in addr; /* socket address (family,addr,port) */
struct timeval timeval; /* timeout structure for select() call */
fd_set fdset, rdset; /* set of fds, set of fds ready for reading */
struct msghdr fdmsghdr; /* msghdr for recvmsg() call */
struct iovec iov[1]; /* io vector for recvmsg() call */
struct { /* ancillary data for recvmsg() call */
struct cmsghdr fdcmsghdr;/* ancillary data header */
int fd; /* ancillary data (one fd) */
} fdadata;
#define IDLE_PERIOD 60 /* 60 seconds for timeout */
#define BUFF_LEN 1024 /* buffer size */
char msg_buff[BUFF_LEN+1]; /* single buffer is enough for all connections */
int main(int argc, char **argv)
{
/* get process handle and cpu number */
PROCESSHANDLE_GETMINE_(phandle);
PROCESSHANDLE_DECOMPOSE_(phandle, &cpu);
/* print startup message */
fprintf(stderr, "sserver [cpu %d] - starting\n", cpu);
fdcount = 1;
highfd = STDIN_FILENO;
fdpassfd = STDIN_FILENO;
FD_ZERO(&fdset);
FD_SET(fdpassfd, &fdset); /* initially fdset has only one active fd */
/* prepare fd passing message */
fdmsghdr.msg_name = NULL;
fdmsghdr.msg_namelen = 0;
fdmsghdr.msg_iov = iov;
Performance Considerations 147