[comp.unix.questions] More help needed...

steven@pearl.berkeley.edu (Stephen the Greatest) (05/07/87)

Thank you guys for all your great help.  The first problem is solved.
There are, however, some more things I would like to clearify about
sockets.  All I need to do is to have communications between two
processes (which are spawned separately).  How does the processes know
where to connect to?  Also, I would like some form of interrupt-driven
mechanism to signal one process when a message arrives.  I don't want
to keep polling the socket for that will eat up cpu time.  Is there any
way to cause a process to sleep when the socket is empty and wakes up
when new messages arrive?  
Thanx for all your help.  By the way, we are running 4.3 BSD here.
I will get to the Primer on Interprocess Communications later.

					- Stephen 

edw@ius2.cs.cmu.edu (Eddie Wyatt) (05/07/87)

    Here's one way to generate an interrupt over a socket.

    first initialization:




/**************************************************************************
 *                                                                        *
 *                             Ninit                                      *
 *                                                                        *
 **************************************************************************

   Purpose :  This function initializes the client network connection with the
	     LMB.  If the module can not bind to the socket it will try
	     every second until it can.
                Also determining whether byte swapping is needed and
             synchronizing the clocks in done here.

   Programmer : Tony Stenz (Eddie Wyatt)
 
   Date : ? (January 1987)

   Input : 
    name - the name one wants to give to the module

   Output : None

   Locals : 
    h, sp, sin - all used in establishing the connection
    hostname - the name of the computer the LMB resides on

   Globals : 
     port - is modified to be the file descriptor for the connection between
	    the LMB and the module 

 ************************************************************************/

Ninit(name)
    char *name;
    {
    struct hostent *h;
    struct servent *sp;
    struct sockaddr_in  sin;
    char    hostname[80];

    if ((sp = getservbyname(SERVERNAME, "tcp")) == 0)
        signalerror("Ninit",NENOSERVER,FATAL,SERVERNAME);
    endservent();

    if (getenv(LMBHOSTENV) != NULL)
	(void) strcpy(hostname,getenv(LMBHOSTENV));
    else
	{
        (void) printf("Enter host name for LMB: ");
        (void) scanf("%s", hostname);
        clearline();
	}

    do
        {
        if   ((h = gethostbyname(hostname)) != 0) break;
        signalerror("Ninit",NENOHOST,WARNING,hostname);
        (void) printf("Enter host name for LMB: ");
        (void) scanf("%s", hostname);
        clearline();
        }
    while  (TRUE);

    endhostent();

    (void) printf("Waiting to connect to LMB on %s\n",hostname);
    do
        {
        if ((port = socket(AF_INET, SOCK_STREAM, 0))  < 0)
	    signalerror("Ninit",NENOSOCKET,FATAL);

	bzero((char *) & sin, sizeof(sin));
	bcopy(h->h_addr, (char *) &sin.sin_addr, h->h_length);
	sin.sin_family = h->h_addrtype;
	sin.sin_port = sp->s_port;

        if (connect(port,&sin, sizeof(sin)) >= 0) break;

	(void) close (port);
	sleep(1);
        }
    while (TRUE);

    enable_sspec_interrupts();
    BBCONVERT = (SWAP_NUM != Nreceiveint());
    sync_clocks();
    Nsendmodname(name);

    (void) printf("Connection established with LMB.\n");
    }


Enabling interrupts :



/**************************************************************************
 *                                                                        *
 *                             enable_sspec_interrupts                    *
 *                                                                        *
 **************************************************************************

   Purpose :  This function enables SIGURG interrupts to be generated on
	     the port that connects the LMB and module.  Also the interrupt
	     handle is setup for the interrupt.

   Programmer : Eddie Wyatt
 
   Date : January 1987

   Input : None

   Output : None

   Locals : None
    pgrp - the process group id of the module (used to enable SIGURG
	   interrupts to be generate at this end of the connection)

   Globals : 
    port - not modified

 ************************************************************************/

enable_sspec_interrupts()
    {
    int pgrp = -getpid();


    (void) signal(SIGURG,urgent_message_processor);
    (void) ioctl(port,SIOCSPGRP, (char *) &pgrp);
    }


urgent message processor :



/**************************************************************************
 *                                                                        *
 *                            urgent_message_processor                    *
 *                                                                        *
 **************************************************************************

   Purpose :  This function is call when a SIGURG interrupt is sent to
	     the module.  An SIGURG is sent to the module to notify the 
	     module that a standing spec token has arrived and that the
	     module should mediately stop what it is doing and start
	     processing the standing spec token.  How this is actually
	     done is by setting up this routine as the interrupt
	     handler for the signal SIGURG using the UNIX system call
	     "signal".
	        The "recv" call is used to read a single character
  	     which has no meaning that was sent out of bound (OOB) by the LMB
	     to generate a SIGURG interrupt at this end of the communications.

   Programmer : Eddie Wyatt
 
   Date : January 1987

   Input : 
     sig - is which interrupt us generate to cause this function call
     code - is additional information about the interrupt
     scp - is a point to a structure which is used by the operating system
           to restore the context from before the signal

   Output : None

   Locals : 
    ch - used to read character send out of bounds to generate SIGURG
    msgtype - message type of the current message on the port connecting
	      the LMB and module (might not always be SENDSTANDINGSPEC)

   Globals :
	port - not modified

 ************************************************************************/

int urgent_message_processor(sig, code, scp)
    int sig, code;
    struct sigcontext *scp;
    {
    char ch;
    int msgtype;

    (void) recv(port,&ch,sizeof(char),MSG_OOB);

    msgtype = ready_to_read(port) ? peek_at_port() : UNKNOWN;
    if ((msgtype == M_SENDSTANDINGLIST) || (msgtype == M_KILL)) 
        (void) Nreceive_message(M_SENDSTANDINGLIST);
    }


-- 
					Eddie Wyatt

e-mail: edw@ius2.cs.cmu.edu