Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!rochester!pt.cs.cmu.edu!ius2.cs.cmu.edu!edw From: edw@ius2.cs.cmu.edu (Eddie Wyatt) Newsgroups: comp.unix.wizards,comp.unix.questions Subject: Re: More help needed... Message-ID: <1150@ius2.cs.cmu.edu> Date: Thu, 7-May-87 10:08:56 EDT Article-I.D.: ius2.1150 Posted: Thu May 7 10:08:56 1987 Date-Received: Sat, 9-May-87 04:17:31 EDT References: <3480@jade.BERKELEY.EDU> Organization: Carnegie-Mellon University, CS/RI Lines: 203 Summary: (interrupts over sockets) Xref: mnetor comp.unix.wizards:2196 comp.unix.questions:2185 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