sinqhm_srv_server.c --> SinqHM_srv_server.c
This commit is contained in:
@ -1,282 +0,0 @@
|
|||||||
#define IDENT "1A08"
|
|
||||||
/*
|
|
||||||
** +--------------------------------------------------------------+
|
|
||||||
** | Paul Scherrer Institute |
|
|
||||||
** | SINQ Division |
|
|
||||||
** | |
|
|
||||||
** | This software may be used freely by non-profit organizations.|
|
|
||||||
** | It may be copied provided that the name of P.S.I. and of the |
|
|
||||||
** | author is included. Neither P.S.I. nor the author assume any |
|
|
||||||
** | responsibility for the use of this software outside of P.S.I.|
|
|
||||||
** +--------------------------------------------------------------+
|
|
||||||
**
|
|
||||||
** Module Name . . . . . . . . : [...SinqHM]SinqHM_srv_server.c
|
|
||||||
**
|
|
||||||
** Author . . . . . . . . . . : D. Maden
|
|
||||||
** Date of creation . . . . . . : Oct 1996
|
|
||||||
**
|
|
||||||
** Updates:
|
|
||||||
** 1A01 2-Oct-1996 DM Initial version.
|
|
||||||
**
|
|
||||||
** SinqHM_srv_server.c forms a child process of the SINQ Histogram Memory
|
|
||||||
** process. It does the communication with the client.
|
|
||||||
**
|
|
||||||
** To compile this program for VxWorks on PSS123, use:
|
|
||||||
**
|
|
||||||
ccvx SinqHM_srv_server.c
|
|
||||||
** where
|
|
||||||
ccvx = ccppc -O0 \
|
|
||||||
-mcpu=603 \
|
|
||||||
-I${WIND_BASE}/target/h \
|
|
||||||
-fno-builtin \
|
|
||||||
-fno-for-scope \
|
|
||||||
-nostdinc \
|
|
||||||
-DCPU=PPC603 \
|
|
||||||
-D_GNU_TOOL \
|
|
||||||
-gdwarf -c -Wimplicit
|
|
||||||
**
|
|
||||||
**====================================================================
|
|
||||||
*/
|
|
||||||
#include <vxWorks.h>
|
|
||||||
#include <taskLib.h>
|
|
||||||
#include <msgQLib.h>
|
|
||||||
#include <sockLib.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <setjmp.h>
|
|
||||||
|
|
||||||
#include <unistd.h> /* Get the POSIX environment defined ..
|
|
||||||
** .. see DEC OSF/1 Guide to Realtime Programming */
|
|
||||||
#include <errno.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
#include <sys/mman.h> /* Get POSIX mem mgmnt definitions. */
|
|
||||||
#include <signal.h> /* Get POSIX signal definitions. */
|
|
||||||
#include <timers.h>
|
|
||||||
#include <sys/wait.h> /* Get POSIX wait definitions. */
|
|
||||||
/*
|
|
||||||
**==================== Global Definitions =====================================
|
|
||||||
*/
|
|
||||||
#include "SinqHM_def.h"
|
|
||||||
#include "SinqHM_gbl.h"
|
|
||||||
/*==============================================================================
|
|
||||||
Local Routines for SRV
|
|
||||||
** None
|
|
||||||
*/
|
|
||||||
/*==============================================================================
|
|
||||||
Global Routines for SRV
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void SinqHM_server_setup_id () {
|
|
||||||
/* ======================
|
|
||||||
** Simply copy some ident information to global variables
|
|
||||||
** for use by the SQHM_IDENT request.
|
|
||||||
*/
|
|
||||||
StrJoin (Sqhm_serv_ident, sizeof (Sqhm_serv_ident), IDENT, "");
|
|
||||||
StrJoin (Sqhm_serv_date, sizeof (Sqhm_serv_date), __DATE__, ", ");
|
|
||||||
StrJoin (Sqhm_serv_date, sizeof (Sqhm_serv_date), Sqhm_serv_date, __TIME__);
|
|
||||||
}
|
|
||||||
/*==============================================================================
|
|
||||||
Here beginneth the main code for SinqHM_server ...
|
|
||||||
**
|
|
||||||
** Note: There must be NO return from this function.
|
|
||||||
*/
|
|
||||||
int SinqHM_server (int suspend_flag, int index, int pkt_size) {
|
|
||||||
/* =============
|
|
||||||
**
|
|
||||||
** Set up TCP/IP port for operations with client, accept his
|
|
||||||
** connection and perform services for him.
|
|
||||||
*/
|
|
||||||
int status, status0, status1;
|
|
||||||
int i, is, nbytes, bytes_to_come;
|
|
||||||
char recd[80];
|
|
||||||
char *p_nxt_byte;
|
|
||||||
int cnct_skt, rw_skt;
|
|
||||||
struct sockaddr_in my_lcl_sockname;
|
|
||||||
struct sockaddr_in my_rmt_sockname;
|
|
||||||
int my_rmt_sockname_len;
|
|
||||||
char *buff_pntr;
|
|
||||||
int port;
|
|
||||||
|
|
||||||
sigset_t proc_sigmask;
|
|
||||||
struct sigaction sig_action;
|
|
||||||
|
|
||||||
struct req_buff_struct my_req_bf;
|
|
||||||
struct rply_buff_struct my_rply_bf;
|
|
||||||
|
|
||||||
port = Port_base + index;
|
|
||||||
/*============================================================================
|
|
||||||
*/
|
|
||||||
StrJoin (Tsk_name[index], sizeof (Tsk_name[0]), taskName (get_pid ()), "");
|
|
||||||
|
|
||||||
if (suspend_flag != 0) {
|
|
||||||
printf ("\n%s: Suspending ..\n", Tsk_name[index]);
|
|
||||||
taskSuspend (0); /* We've been told to suspend ourself, ..
|
|
||||||
** .. presumably for debug reasons.
|
|
||||||
*/
|
|
||||||
printf ("\n%s: Suspension ended!\n", Tsk_name[index]);
|
|
||||||
}
|
|
||||||
/*============================================================================
|
|
||||||
** Define our signal mask first and define an action routine to catch
|
|
||||||
** the SIGINT signal our parent will send us when he wants us to exit.
|
|
||||||
*/
|
|
||||||
status = sigemptyset (&proc_sigmask);
|
|
||||||
status = sigprocmask (SIG_SETMASK, &proc_sigmask, NULL);
|
|
||||||
|
|
||||||
status = sigemptyset (&sig_action.sa_mask);
|
|
||||||
sig_action.sa_handler = catch_int_signal;
|
|
||||||
sig_action.sa_flags = 0;
|
|
||||||
if (sigaction (SIGINT, &sig_action, NULL) == -1) {
|
|
||||||
getErrno (&My_errno);
|
|
||||||
perror ("sigaction error:");
|
|
||||||
Child_exit_status[index] = -1; /* Tell our parent we've given up */
|
|
||||||
is = semGive (Sem_Server); /* Let our parent continue */
|
|
||||||
exit (KER__BAD_VALUE);
|
|
||||||
}
|
|
||||||
/*============================================================================
|
|
||||||
** Create a TCP/IP socket for communication, bind it and listen.
|
|
||||||
*/
|
|
||||||
Child_cnct_skt[index] = 0;
|
|
||||||
cnct_skt = socket (AF_INET, SOCK_STREAM, 0);
|
|
||||||
if (cnct_skt == -1) {
|
|
||||||
perror (StrJoin (recd, sizeof (recd),
|
|
||||||
Tsk_name[index], " -- cnct_skt socket error"));
|
|
||||||
Child_exit_status[index] = -2; /* Tell our parent we've given up */
|
|
||||||
is = semGive (Sem_Server); /* Let our parent continue */
|
|
||||||
exit (KER__BAD_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
my_lcl_sockname.sin_family = AF_INET;
|
|
||||||
my_lcl_sockname.sin_port = htons (port);
|
|
||||||
my_lcl_sockname.sin_addr.s_addr = 0;
|
|
||||||
status = bind (cnct_skt, (struct sockaddr *) &my_lcl_sockname,
|
|
||||||
sizeof (my_lcl_sockname));
|
|
||||||
if (status != 0) {
|
|
||||||
close (cnct_skt);
|
|
||||||
perror (StrJoin (recd, sizeof (recd),
|
|
||||||
Tsk_name[index], " -- cnct_skt bind error"));
|
|
||||||
Child_exit_status[index] = -2; /* Tell our parent we've given up */
|
|
||||||
is = semGive (Sem_Server); /* Let our parent continue */
|
|
||||||
exit (KER__BAD_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
status = listen (cnct_skt, 1);
|
|
||||||
if (status != 0) {
|
|
||||||
close (cnct_skt);
|
|
||||||
perror (StrJoin (recd, sizeof (recd),
|
|
||||||
Tsk_name[index], " -- cnct_skt listen error"));
|
|
||||||
Child_exit_status[index] = -3; /* Tell our parent we've given up */
|
|
||||||
is = semGive (Sem_Server); /* Let our parent continue */
|
|
||||||
exit (KER__BAD_VALUE);
|
|
||||||
}
|
|
||||||
/*============================================================================
|
|
||||||
** Tell parent our cnct port is set up and waiting by releasing
|
|
||||||
** semaphore so that our parent can continue. The parent will then
|
|
||||||
** send a message to the client telling him which port he is to use.
|
|
||||||
*/
|
|
||||||
is = semGive (Sem_Server);
|
|
||||||
if (is != OK) {
|
|
||||||
kill (Parent_pid, SIGUSR1); /* Inform parent that we are in trouble */
|
|
||||||
printf ("%s -- sem release error\n", Tsk_name[index]);
|
|
||||||
close (cnct_skt);
|
|
||||||
exit (KER__BAD_VALUE);
|
|
||||||
}
|
|
||||||
Child_cnct_skt[index] = cnct_skt;
|
|
||||||
/*============================================================================
|
|
||||||
** Ensure that our bit in SinqHM_Dsbl_Mask is clear.
|
|
||||||
*/
|
|
||||||
do_daq (&my_rply_bf, index, DAQ__CLR);
|
|
||||||
/*============================================================================
|
|
||||||
** Wait for the client to connect to our port
|
|
||||||
*/
|
|
||||||
my_rmt_sockname_len = sizeof (my_rmt_sockname);
|
|
||||||
rw_skt = accept (cnct_skt, (struct sockaddr *) &my_rmt_sockname,
|
|
||||||
&my_rmt_sockname_len);
|
|
||||||
if (rw_skt == -1) {
|
|
||||||
perror (StrJoin (recd, sizeof (recd),
|
|
||||||
Tsk_name[index], " -- cnct_skt accept error"));
|
|
||||||
close (cnct_skt);
|
|
||||||
Child_cnct_skt[index] = 0;
|
|
||||||
kill (Parent_pid, SIGUSR1); /* Inform parent that we are in trouble */
|
|
||||||
exit (KER__BAD_VALUE);
|
|
||||||
}
|
|
||||||
Child_rw_skt[index] = rw_skt;
|
|
||||||
/*
|
|
||||||
**-------------------------------------------------------------------------
|
|
||||||
** Here is the main recv loop
|
|
||||||
*/
|
|
||||||
main_loop:
|
|
||||||
/*=========
|
|
||||||
*/ bytes_to_come = sizeof (my_req_bf); /* Read a command */
|
|
||||||
p_nxt_byte = (char *) &my_req_bf;
|
|
||||||
while (bytes_to_come > 0) {
|
|
||||||
nbytes = recv (rw_skt, p_nxt_byte, bytes_to_come, 0);
|
|
||||||
if (nbytes <= 0) break;
|
|
||||||
Rw_bytes_got += nbytes;
|
|
||||||
bytes_to_come -= nbytes;
|
|
||||||
p_nxt_byte += nbytes;
|
|
||||||
}
|
|
||||||
if ((bytes_to_come == 0) &&
|
|
||||||
(ntohl (my_req_bf.bigend) == 0x12345678) &&
|
|
||||||
(ntohl (my_req_bf.cmnd) != SQHM_CLOSE)) {
|
|
||||||
is = do_command (index, rw_skt, pkt_size, &my_req_bf, &my_rply_bf);
|
|
||||||
if (is == OK) goto main_loop; /* Break out of loop on error */
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
** End of the main recv loop
|
|
||||||
**-------------------------------------------------------------------------
|
|
||||||
** Get here if we drop out of the "recv" loop.
|
|
||||||
** This should only happen on getting a SQHM_CLOSE message.
|
|
||||||
** Anything else is a fatal error.
|
|
||||||
*/
|
|
||||||
do_daq (&my_rply_bf, index, DAQ__CLR); /* Ensure our inhibit bit is clear */
|
|
||||||
|
|
||||||
close (rw_skt); Child_rw_skt[index] = 0;
|
|
||||||
close (cnct_skt); Child_cnct_skt[index] = 0;
|
|
||||||
/*
|
|
||||||
** Check the various error conditions
|
|
||||||
*/
|
|
||||||
if (bytes_to_come != 0) { /* Was a complete request read? */
|
|
||||||
/* No, it may be a network error, in which case
|
|
||||||
** nbytes is -1, or nothing was read, which
|
|
||||||
** indicates that our client simply closed
|
|
||||||
** his connection (forgetting to send a
|
|
||||||
** SQHM_CLOSE message), or the client has
|
|
||||||
** screwed up the protocol! */
|
|
||||||
if (nbytes == -1) {
|
|
||||||
/* It's a network error */
|
|
||||||
perror (StrJoin (recd, sizeof (recd),
|
|
||||||
Tsk_name[index], " -- rw_skt recv error"));
|
|
||||||
status = KER__EXIT_SIGNAL;
|
|
||||||
}else if (bytes_to_come == sizeof (my_req_bf)) {
|
|
||||||
/* Our client simply closed his connection.
|
|
||||||
** Treat this as normal. */
|
|
||||||
printf ("\n%s exiting.\n", Tsk_name[index]);
|
|
||||||
status = KER__SUCCESS;
|
|
||||||
}else {
|
|
||||||
printf ("\n%s -- rw_skt recv wrong number of bytes: %d\n",
|
|
||||||
Tsk_name[index], nbytes);
|
|
||||||
status = KER__EXIT_SIGNAL;
|
|
||||||
}
|
|
||||||
}else if (ntohl (my_req_bf.bigend) != 0x12345678) {
|
|
||||||
/* Network byte-order wrong! */
|
|
||||||
printf ("\n%s -- big-endian/little-endian problem!\n"
|
|
||||||
" Buffer received in non-network byte order!\n", Tsk_name[index]);
|
|
||||||
status = KER__EXIT_SIGNAL;
|
|
||||||
}else if (ntohl (my_req_bf.cmnd) == SQHM_CLOSE) {
|
|
||||||
/* SQHM_CLOSE request received. This is normal */
|
|
||||||
printf ("\n%s exiting.\n", Tsk_name[index]);
|
|
||||||
status = KER__SUCCESS;
|
|
||||||
}else {
|
|
||||||
/* Unrecognised request received! */
|
|
||||||
printf ("\n%s -- unrecognised command received: 0x%x\n",
|
|
||||||
Tsk_name[index], ntohl (my_req_bf.cmnd));
|
|
||||||
status = KER__EXIT_SIGNAL;
|
|
||||||
}
|
|
||||||
kill (Parent_pid, SIGUSR1); /* Inform parent that we are exiting */
|
|
||||||
exit (status);
|
|
||||||
}
|
|
||||||
/*======================================= End of SinqHM_srv_server.c ========*/
|
|
Reference in New Issue
Block a user