diff options
author | dos-reis <gdr@axiomatics.org> | 2007-08-14 05:14:52 +0000 |
---|---|---|
committer | dos-reis <gdr@axiomatics.org> | 2007-08-14 05:14:52 +0000 |
commit | ab8cc85adde879fb963c94d15675783f2cf4b183 (patch) | |
tree | c202482327f474583b750b2c45dedfc4e4312b1d /src/sman | |
download | open-axiom-ab8cc85adde879fb963c94d15675783f2cf4b183.tar.gz |
Initial population.
Diffstat (limited to 'src/sman')
-rw-r--r-- | src/sman/ChangeLog | 83 | ||||
-rw-r--r-- | src/sman/Makefile.in | 91 | ||||
-rw-r--r-- | src/sman/Makefile.pamphlet | 145 | ||||
-rw-r--r-- | src/sman/nagman.c.pamphlet | 636 | ||||
-rw-r--r-- | src/sman/session.c.pamphlet | 601 | ||||
-rw-r--r-- | src/sman/sman.c.pamphlet | 1111 | ||||
-rw-r--r-- | src/sman/spadclient.c | 66 |
7 files changed, 2733 insertions, 0 deletions
diff --git a/src/sman/ChangeLog b/src/sman/ChangeLog new file mode 100644 index 00000000..f433a88c --- /dev/null +++ b/src/sman/ChangeLog @@ -0,0 +1,83 @@ +2007-08-10 Gabriel Dos Reis <gdr@cs.tamu.edu> + + * sman.c.pamphlet (HypertexProgram): hypertex is installed in lib/ + directory. + +2007-07-29 Gabriel Dos Reis <gdr@cs.tamu.edu> + + * Makefile.pamphlet: Propagate libtoolization changes. + * Makefile.in: Regenerate. + +2007-04-09 Bill Page <bill.page1@synthesis.anikast.ca> + + * Makefile.pamphlet (session_LDADD): Add extrac C runtime libraries. + (spadclient_LDADD): Likewise. + * Makefile.in: Regenerate. + +2007-04-08 Gabriel Dos Reis <gdr@cs.tamu.edu> + Bill Page <bill.page1@synthesis.anikast.ca> + + * Makefile.pamphlet (sman_LDADD): Add extra runtime libraries. + +2006-12-15 Gabriel Dos Reis <gdr@cs.tamu.edu> + + * sman.c.pamphlet: Don't include useproto.h. Avoid including + axiom-c-macros.h twice. + * session.c.pamphlet: Remove K&R C style function declarations. + Don't include useproto.h + * spadclient.c.pamphlet: Likewise. + +2006-11-29 Gabriel Dos Reis <gdr@cs.tamu.edu> + + * sman.c.pamphlet (should_I_clef): Recover lost return type. + +2006-11-26 Gabriel Dos Reis <gdr@cs.tamu.edu> + + * nagman.c.pamphlet: Include axiom-c-macros.h. + * session.c.pamphlet: Likewise. + * sman.c.pamphlet: Likewise. + * spadclient.c.pamphlet: Likewise. + + * Makefile.pamphlet: Add support for OS that require extension for + executable binary files. + * Makefile.in: Regenerate. + +2006-11-23 Gabriel Dos Reis <gdr@cs.tamu.edu> + + * Makefile.pamphlet ($(build_libdir)/libspad.a): Remove. + (LDFLAGS): Likewise. + (SMANOBJS): Likewise. + (LIB): Likewise. + (DOC): Likewise. + +2006-11-24 Gabriel Dos Reis <gdr@cs.tamu.edu> + + * sman.c.pamphlet: Include "axiom-c-macros.h + Remove K&R C style function declarations. + + * Makefile.pamphlet (DOC, CFLAGS, LDFLAGS, SMANOBJS): Remove. + (session_DEPENDENCIES): Clear. + (spadclient_DEPENDENCIES): Likewise. + (sman_DEPENDENCIES): Likewise. + * Makefile.in: Regenerate. + +2006-11-18 Bill Page <bill.page1@synthesis.anikast.ca> + + * Makefile.pamphlet (LDFLAGS): Add X11 libraries flags. + * Makefile.in: Regenerate. + +2006-09-26 Gabriel Dos Reis <gdr@cs.tamu.edu> + + * Makefile.pamphlet (all): Create stamp file. + * Makefile.in: Regenerate. + +2006-09-25 Gabriel Dos Reis <gdr@cs.tamu.edu> + + * Makefile.pamphlet (${OUTLIB}/session, ${OUTLIB}/spadclient, + ${OUT}/sman): Fix thinko. + +2006-09-18 Gabriel Dos Reis <gdr@cs.tamu.edu> + + * Makefile.pamphlet: Simplify. + * Makefile.in: Regenerate. + diff --git a/src/sman/Makefile.in b/src/sman/Makefile.in new file mode 100644 index 00000000..ca0b270f --- /dev/null +++ b/src/sman/Makefile.in @@ -0,0 +1,91 @@ + +subdir = src/sman/ + +# this is where to put the various commands +OUT= $(axiom_target_bindir) +OUTLIB= $(axiom_target_libdir) + +# this is where the include files live +INC= $(axiom_src_srcdir)/include + +build_libdir = $(abs_top_builddir)/src/lib + +bin_PROGRAMS = session$(EXEEXT) \ + spadclient$(EXEEXT) \ + sman$(EXEEXT) + +libspad_la = $(axiom_target_libdir)/libspad.la + +session_sources = session.c +session_SOURCES = $(addsuffix .pamphlet, $(session_sources)) +session_objects = $(session_sources:.c=.lo) +session_LDADD = $(libspad_la) @axiom_c_runtime_extra@ +session_DEPENDENCIES = + +spadclient_sources = spadclient.c +spadclient_objects = $(spadclient_sources:.c=.lo) +spadclient_LDADD = $(libspad_la) @axiom_c_runtime_extra@ +spadclient_DEPENDENCIES = + +sman_sources = sman.c +sman_SOURCES = $(addsuffix .pamphlet, $(sman_sources)) +sman_objects = $(sman_sources:.c=.lo) +sman_LDADD = $(libspad_la) @axiom_c_runtime_extra@ +sman_DEPENDENCIES = + + +pamphlets = $(session_SOURCES) $(sman_SOURCES) + +.PHONY: all all-sman + +all: all-ax + +all-ax all-sman: stamp + +stamp: $(OUTLIB)/session$(EXEEXT) \ + $(OUTLIB)/spadclient$(EXEEXT) \ + $(OUT)/sman$(EXEEXT) + -rm -f stamp + $(STAMP) stamp + +.SUFFIXES: +.SUFFIXES: .c .h .lo .$(OBJEXT) +.PRECIOUS: %.lo %.obj +.PRECIOUS: %.c +.PRECIOUS: %.h + +%.lo: %.c + $(COMPILE) ${CCF} -o $@ $(axiom_includes) -I$(builddir) $< + +%.c: $(srcdir)/%.c.pamphlet + $(axiom_build_document) --tangle --output=$@ $< + +${OUTLIB}/session$(EXEEXT): $(session_objects) $(session_DEPENDENCIES) + $(LINK) -o $@ $(session_objects) $(session_LDADD) ${LDF} + +${OUTLIB}/spadclient$(EXEEXT): $(spadclient_objects) $(spadclient_DEPENDENCIES) + $(LINK) -o $@ $(spadclient_objects) $(spadclient_LDADD) ${LDF} + +spadclient.$(OBJEXT): ${INC}/useproto.h ${INC}/spadclient.H1 \ + $(axiom_configdir)/axiom-c-macros.h + +${OUT}/sman$(EXEEXT): $(sman_objects) $(sman_DEPENDENCIES) + $(LINK) -o $@ $(sman_objects) $(sman_LDADD) ${LDF} + +$(sman_objects): sman.h $(axiom_c_macros_h) + +sman.h: $(srcdir)/sman.c.pamphlet + $(axiom_build_document) --tangle=$@ --output=$@ $< + +mostlyclean-local: + @rm -f $(session_sources) $(session_objects) sman.h + @rm -f $(spadclient_sources) $(session_objects) + @rm -f $(sman_sources) $(sman_objects) + +clean-local: mostlyclean-local + @rm -f $(OUTLIB)/session$(EXEEXT) + @rm -f $(OUTLIB)/spadclient$(EXEEXT) + @rm -f $(OUT)/sman$(EXEEXT) + +distclean-local: clean-local + diff --git a/src/sman/Makefile.pamphlet b/src/sman/Makefile.pamphlet new file mode 100644 index 00000000..db980d94 --- /dev/null +++ b/src/sman/Makefile.pamphlet @@ -0,0 +1,145 @@ +%% Oh Emacs, this is a -*- Makefile -*-, so give me tabs. +\documentclass{article} +\usepackage{axiom} + +\title{\$SPAD/src/sman Makefile} +\author{Gabriel Dos~Reis \and Timothy Daly} + +\begin{document} +\maketitle + +\begin{abstract} +\end{abstract} +\eject + +\tableofcontents +\eject + + +\section{Environment variables} + +<<environment>>= +# this is where to put the various commands +OUT= $(axiom_target_bindir) +OUTLIB= $(axiom_target_libdir) + +# this is where the include files live +INC= $(axiom_src_srcdir)/include + +build_libdir = $(abs_top_builddir)/src/lib + +bin_PROGRAMS = session$(EXEEXT) \ + spadclient$(EXEEXT) \ + sman$(EXEEXT) + +libspad_la = $(axiom_target_libdir)/libspad.la + +session_sources = session.c +session_SOURCES = $(addsuffix .pamphlet, $(session_sources)) +session_objects = $(session_sources:.c=.lo) +session_LDADD = $(libspad_la) @axiom_c_runtime_extra@ +session_DEPENDENCIES = + +spadclient_sources = spadclient.c +spadclient_objects = $(spadclient_sources:.c=.lo) +spadclient_LDADD = $(libspad_la) @axiom_c_runtime_extra@ +spadclient_DEPENDENCIES = + +sman_sources = sman.c +sman_SOURCES = $(addsuffix .pamphlet, $(sman_sources)) +sman_objects = $(sman_sources:.c=.lo) +sman_LDADD = $(libspad_la) @axiom_c_runtime_extra@ +sman_DEPENDENCIES = + + +pamphlets = $(session_SOURCES) $(sman_SOURCES) +@ + +\section{session} +<<session>>= +${OUTLIB}/session$(EXEEXT): $(session_objects) $(session_DEPENDENCIES) + $(LINK) -o $@ $(session_objects) $(session_LDADD) ${LDF} +@ + +\section{nagman} +Note that we do not build the nagman component as we do not have the +necessary code (for instance, [[callnag]]). +<<nagman>>= +${OUT}/nagman$(EXEEXT): $(nagman_objects) $(nagman_DEPENDENCIES) + $(LINK) -o $@ $(nagman_objects) $(nagman_LDADD) ${LDF} +@ + +\section{spadclient} +<<spadclient>>= +${OUTLIB}/spadclient$(EXEEXT): $(spadclient_objects) $(spadclient_DEPENDENCIES) + $(LINK) -o $@ $(spadclient_objects) $(spadclient_LDADD) ${LDF} + +spadclient.$(OBJEXT): ${INC}/useproto.h ${INC}/spadclient.H1 \ + $(axiom_configdir)/axiom-c-macros.h +@ + +\section{sman} +<<sman>>= +${OUT}/sman$(EXEEXT): $(sman_objects) $(sman_DEPENDENCIES) + $(LINK) -o $@ $(sman_objects) $(sman_LDADD) ${LDF} + +$(sman_objects): sman.h $(axiom_c_macros_h) + +sman.h: $(srcdir)/sman.c.pamphlet + $(axiom_build_document) --tangle=$@ --output=$@ $< +@ + +<<*>>= + +subdir = src/sman/ + +<<environment>> + +.PHONY: all all-sman + +all: all-ax + +all-ax all-sman: stamp + +stamp: $(OUTLIB)/session$(EXEEXT) \ + $(OUTLIB)/spadclient$(EXEEXT) \ + $(OUT)/sman$(EXEEXT) + -rm -f stamp + $(STAMP) stamp + +.SUFFIXES: +.SUFFIXES: .c .h .lo .$(OBJEXT) +.PRECIOUS: %.lo %.obj +.PRECIOUS: %.c +.PRECIOUS: %.h + +%.lo: %.c + $(COMPILE) ${CCF} -o $@ $(axiom_includes) -I$(builddir) $< + +%.c: $(srcdir)/%.c.pamphlet + $(axiom_build_document) --tangle --output=$@ $< + +<<session>> + +<<spadclient>> + +<<sman>> + +mostlyclean-local: + @rm -f $(session_sources) $(session_objects) sman.h + @rm -f $(spadclient_sources) $(session_objects) + @rm -f $(sman_sources) $(sman_objects) + +clean-local: mostlyclean-local + @rm -f $(OUTLIB)/session$(EXEEXT) + @rm -f $(OUTLIB)/spadclient$(EXEEXT) + @rm -f $(OUT)/sman$(EXEEXT) + +distclean-local: clean-local + +@ +\eject +\begin{thebibliography}{99} +\bibitem{1} nothing +\end{thebibliography} +\end{document} diff --git a/src/sman/nagman.c.pamphlet b/src/sman/nagman.c.pamphlet new file mode 100644 index 00000000..c8db5f61 --- /dev/null +++ b/src/sman/nagman.c.pamphlet @@ -0,0 +1,636 @@ +\documentclass{article} +\usepackage{axiom} +\begin{document} +\title{\$SPAD/src/sman nagman.c} +\author{The Axiom Team} +\maketitle +\begin{abstract} +\end{abstract} +\eject +\tableofcontents +\eject +\section{nag.x} +<<nag.x>>= + +/* + * msg.x: Remote message printing protocol + */ +const MAXASP = 10; + +/* + * the nago structure is essentially a variable length string + */ + +struct nago { + opaque z <>; + }; +struct nagerr { +nago p; +nago q; +}; + +struct host{ +nago h <>; +}; + +struct nagst { + +/* Okay, if you understand this bit you know the essentials of how the link + * works. h <> is an array of nago, which is an array of fortran source + * code, the length of the array being the no. of asps (0 for most routines). + * y is the actual (XDR) input data for the routine. nm is the name of the + * routine. id is a tag identifying the host/axiom session. Finally per is a + * number telling whether or not to erase old fortran files on the remote + * machine (persistence - the number per distinct fortran files will be + * stored, any more than this and earlier ones will be deleted. + */ + + nago h <>; + nago y; + nago nm; + nago id; + int per; + }; +program NAGPROG { + version NAGVERS { + nagerr CALLNAG(nagst) = 1; + nago NAGMON(int)=2; + void AXEND(nago)=3; + } = 1; +/* + * the following number is very important. It tells the + * portmapper what number to register the nag daemon under. + * There are rules about which number to pick - check SUN + * technical info for more details + */ +} = 100088; + + +@ +\section{nagman} +\subsection{includes} +<<includes>>= +#include "axiom-c-macros.h" +#include "useproto.h" +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <termios.h> +#include <signal.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <rpc/rpc.h> /* always needed */ +#include <fcntl.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include "nag.h" /* generated by rpcgen */ +#include "com.h" +#include "bsdsignal.h" +#include "sockio-c.H1" +#include "bsdsignal.H1" +#include "nagman.H1" + +@ +\subsection{variables} +<<variables>>= +#ifdef ALPHAplatform +extern int getdomainname( char *, int ); +#endif +#ifdef SUN4OS5platform +extern int getdomainname( char *, int ); +extern int gethostname( char *, int ); +#endif + +#ifdef _NO_PROTO +nagerr * callnag_1(); +nago * nagmon_1(); +void * axend_1(); +#else +nagerr * callnag_1(nagst *,CLIENT *); +nago * nagmon_1(int *,CLIENT *); +void * axend_1(nago *,CLIENT *); +#endif + +#define DO 1 +#define DONT 0 + +int hnum, vmax; +char *datafile, *resultsfile; + +struct hostnode { + char * name; + struct hostnode *next; +} *hlist=NULL; + +nagst nag4; +Sock *sock1; + +@ +\subsection{term} +this code runs when the user quits axiom. before nagman dies, it does +an rpc call to nagd to tell it to get rid of files etc. The rpc call in +question is [[axend_1]] +we also send a USR1 to sman to beget another nagman +<<term>>= +static void +#ifdef _NO_PROTO +term(sig) + int sig; +#else +term(int sig) +#endif +{ + CLIENT *cld; + void *res; + struct hostnode *pnode; + +#ifndef HP9platform /* can't figure out a way to do this on HP/UX 9 */ + kill(atoi(getenv("SPADNUM")) , SIGUSR1); +#endif + + + if(hnum!=0) + { + unlink(datafile); + unlink(resultsfile); + } + + for(pnode=hlist;pnode!=NULL;pnode=pnode->next) + { + cld=clnt_create(pnode->name,NAGPROG, NAGVERS, "tcp"); + if (cld == NULL) + goto NOHOST; + + res=axend_1(&(nag4.id),cld); + NOHOST: + clnt_destroy(cld); + } + exit(0); +} + +@ +\subsection{size\_of\_file} +<<sizeoffile>>= +static long +#ifdef _NO_PROTO +size_of_file(filename) + char *filename; +#else +size_of_file(char *filename) +#endif +{ + struct stat buf_stat; + + stat(filename,&buf_stat); + return (buf_stat.st_size); + +} + +@ +\subsection{rpcloop} +<<rpcloop>>= +static void +#ifdef _NO_PROTO +rpcloop() +#else +rpcloop(void) +#endif +{ + CLIENT *cl; + int res,j,v=0,u,showMessage; + long i; + register struct hostent *alias1, *alias2; + struct in_addr *addrnum; + u_long junk; + struct timeval tv; + nagerr *result; + char *Buf , *buf1; + char *ffile[MAXASP]; + char routine[12], naghost[256]; + FILE *nfp1, *nfp2, *nfp3; + struct hostnode *phost; + int fd; + + for (;;) + { + + if((Buf=get_string(sock1))==NULL) term(1); /* one string carries all */ + + if(hnum!=0) + { + /* call parameters */ + free(nag4.nm.z.z_val); /* the routine name */ + free(nag4.y.z.z_val); /* the XDR data */ + for(i=0;i<v;i++) + { + unlink(ffile[i]); + free(ffile[i]); /* the asp filenames */ + free(nag4.h.h_val[i].z.z_val); /* the asps themselves*/ + } + free(nag4.h.h_val); /* the asps array */ + unlink(datafile); + unlink(resultsfile); + free(resultsfile); + free(datafile); + vmax= (v>vmax)? v : vmax; + } + + + + + buf1=strtok(Buf," "); + if (buf1) strcpy(naghost,buf1); + else printf("can't parse the naghost\n"); + /* INFO printf("%s\n",naghost);*/ + + buf1=strtok(NULL," "); + if (buf1) strcpy(routine,buf1); + else printf("can't parse the routine\n"); + /* INFO printf("%s\n",routine);*/ + + /* make copy of filenames because we will reuse Buf before deleting the files*/ + buf1=strtok(NULL," "); + if (buf1) resultsfile=strdup(buf1); + else printf("can't parse the resultsfile file\n"); + /* INFO printf("%s\n",resultsfile);*/ + + buf1=strtok(NULL," "); + if (buf1) datafile=strdup(buf1); + else printf("can't parse the datafile file\n"); + /* INFO printf("%s\n",datafile);*/ + + buf1=strtok(NULL," "); + if (buf1) nag4.per=atoi(buf1); + else printf("can't parse the persistence\n"); + /* INFO printf("%d\n",nag4.per);*/ + + buf1=strtok(NULL," "); + if (buf1) { + if (!strcmp(buf1,"on")) showMessage=DO; + else showMessage=DONT; + } + else printf("can't parse the messages flag\n"); + /* INFO printf("%s\n",buf1);*/ + + v=0; /* asp counter */ + while( (buf1=strtok(NULL," ")) ) + { + ffile[v++]=strdup(buf1); + /* INFO printf("%s\n",ffile[v-1]);*/ + } + + /* INFO printf("number of asps seen %d\n",v);*/ + + if(showMessage==DO) printf("nagman:acknowledging request for %s\n",routine); + + res=0; /* prepare result integer to be sent to Lisp */ + + if((nfp3=fopen(resultsfile,"w"))==NULL) + { + printf("can't open output file\n"); + goto END; + } + + /* nag4.h is the XDR array of asp text */ + nag4.h.h_len=v; + nag4.h.h_val=(nago *)malloc((v)*sizeof(nago)); + + + /* get asp text in call argument */ + for(u=0;u<v;u++) + { + /* this should be done by mmap */ + if((nfp1=fopen(ffile[u],"r"))==NULL) + { + fprintf(stderr,"can't open asp file %s\n",ffile[u]); + fclose(nfp1); + goto END; + } + fclose(nfp1); + i=size_of_file(ffile[u]); + + /* allocs memory for the file */ + nag4.h.h_val[u].z.z_val= (char *)malloc((i+1)*sizeof(char)); + + fd=open(ffile[u],O_RDONLY); + read(fd,nag4.h.h_val[u].z.z_val,i); + close(fd); + /* make null-term. string */ + nag4.h.h_val[u].z.z_val[i]='\0'; + /* set the length */ + nag4.h.h_val[u].z.z_len=strlen(nag4.h.h_val[u].z.z_val); + } + + + nag4.nm.z.z_val=strdup(routine); + nag4.nm.z.z_len=strlen(routine); + + /* get XDR data in call argument */ + /* should be done by mmap */ + if((nfp2=fopen(datafile,"r"))==NULL) + { + fprintf(stderr,"can't open data file\n"); + fclose(nfp2); + goto END; + } + + fclose(nfp2); + i=size_of_file(datafile); + nag4.y.z.z_val=(char *)malloc(i*sizeof(char)); + + fd=open(datafile,O_RDONLY); + read(fd,nag4.y.z.z_val,i); + close(fd); + nag4.y.z.z_len=i; + + + /* + * Create client "handle" used for calling MESSAGEPROG on + * the server designated on the command line. We tell + * the RPC package to use the "tcp" protocol when + * contacting the server. + */ + + /* update naghost by lookup */ + + if ((junk = inet_addr(naghost))!=-1) + { + addrnum=(struct in_addr *)junk; + if((alias2=gethostbyaddr((char *)&addrnum, + sizeof(addrnum), + AF_INET))!=NULL) + strcpy(naghost,alias2->h_name); + else + if((alias1=gethostbyname(naghost))!=NULL) + strcpy(naghost,alias1->h_name); + } + else + if((alias1=gethostbyname(naghost))!=NULL) + strcpy(naghost,alias1->h_name); + + + + + cl = clnt_create(naghost, NAGPROG, NAGVERS, "tcp"); + if (cl == NULL) + { + /* + * Couldn't establish connection with server. + * Print error message and die. + */ + clnt_pcreateerror(naghost); + goto END; + } + else + if (showMessage==DO) + printf("nagman:connection successful to %s\n",naghost); + + /* + * this number here sets the "timeout" for the rpc call. after this number + * of seconds, the call will quit if no response is received + * + */ + + tv.tv_sec=1000000; + tv.tv_usec=0; + clnt_control(cl,CLSET_TIMEOUT,(char *)&tv); + + + result = callnag_1(&nag4, cl); + + for(phost=hlist;phost!=NULL;phost=phost->next) + { + /* + * hlist is the "hostlist" of sites that have been contacted by nagman. + * here we check if this call is contacting a new site, and if so add it + * to the hostlist + * + */ + + if(!strcmp(phost->name,naghost)) + goto SKIP; + } + + if(hnum==0) { + hlist=(struct hostnode *)malloc(sizeof(struct hostnode)); + hlist->name=strdup(naghost); + hlist->next=NULL; + } + + else { + phost=(struct hostnode *)malloc(sizeof(struct hostnode)); + phost->name=strdup(naghost); + phost->next=hlist; + hlist=phost; + } + hnum++; + + + SKIP: + if (result == NULL) + { + /* + * An error occurred while calling the server. + * Print error message and die. + */ + if (showMessage==DO) + printf("nagman:no results (error) from %s\n",naghost); + clnt_perror(cl,naghost); + clnt_destroy(cl); + goto END; + } + + /* + * (*result).p is the part of the result with the XDRed results in it + * (numbers). (*result).q is the part with (text) error messages that + * have come from the NAG library. If there is neither an XDR result, + * nor a text error message from the library, then something is wrong + * so we just print out the "no result or error returned" message. + * + */ + + else if ((*result).p.z.z_len==0) + { + if((*result).q.z.z_len==0) + { + if (showMessage==DO) + printf("nagman:empty result (error) from %s\n",naghost); + clnt_destroy(cl); + goto END; + } + else + { + if (showMessage==DO) + printf("nagman:receiving results from %s\n\n",naghost); + for(j=0;j<(*result).q.z.z_len;j++) + printf("%c",(*result).q.z.z_val[j]); + clnt_destroy(cl); + goto END; + } + } + else + if (showMessage==DO) + printf("nagman:receiving results from %s\n\n",naghost); + + if (showMessage==DO) + fwrite(result->q.z.z_val,sizeof(char),result->q.z.z_len,stdout); + + /*INFO printf("\nRESULTS of length %d\n",(*result).p.z.z_len);*/ + + fwrite(result->p.z.z_val,sizeof(char),result->p.z.z_len, nfp3); + res=1; + clnt_destroy(cl); + + /* + * in case of any type of error, a goto END in the above code causes + * nagman to skip here and return to AXIOM + * + */ + + + END: + fclose(nfp3); + /* + * if everything has gone alright, send_int returns the integer res=1. If + * not it returns res=0. This is detected by the boot code which acts + * accordingly. + */ + send_int(sock1,res); + free(Buf); + } + + +} + +@ +\subsection{catchSignals} +catchSignals sets up signal handling. If nagman gets a sigterm it does not +die but goes back to rpcloop +<<catchSignals>>= +static void +#ifdef _NO_PROTO +catchSignals() +#else +catchSignals(void) +#endif +{ + bsdSignal(SIGTERM,term,RestartSystemCalls); + bsdSignal(SIGSEGV,term,RestartSystemCalls); +} + +@ +\subsection{main} +<<main>>= +void +#ifdef _NO_PROTO +main(argc,argv) +int argc; +char **argv; +#else +main(int argc,char **argv) +#endif +{ + char this[256],*hname,*dname,*spadnum; + int stat; + + catchSignals(); + stat=gethostname(this,256); + if (stat!=0) perror("gethostname"); + hname=strdup(this); + + stat=getdomainname(this,256); + if (stat!=0) perror("getdomainname"); + dname=strdup(this); + spadnum=getenv("SPADNUM"); + if (spadnum==0) { + fprintf(stderr,"nagman error: SPADNUM is not in the environment\n"); + exit(0); + } + + /* some machines return a full name from hostname + need to check hname has a . in it */ + + if (strchr(hname,'.')) + /* '.' found */ + sprintf(this,"%s_%i",hname,atoi(spadnum)); + else + /* substring not found */ + sprintf(this,"%s.%s_%i",hname,dname,atoi(spadnum)); + + /* this must contain the Internet address of the current host */ + nag4.id.z.z_val=strdup(this); + nag4.id.z.z_len=strlen(nag4.id.z.z_val); + hnum=0; + vmax=0; + /* + * this line sets up a socket for communication with the lisp + */ + + sock1 = connect_to_local_server(SpadServer, DebugWindow, 120 /*seconds*/); + if (!sock1) exit(0); + + rpcloop(); +} + +@ +\subsection{nagman} +<<nagman>>= +#define _NAGMAN_C +<<includes>> +<<variables>> +<<term>> +<<sizeoffile>> +<<rpcloop>> +<<catchSignals>> +<<main>> +@ +\section{License} +<<license>>= +/* +Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of The Numerical ALgorithms Group Ltd. nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +@ +<<*>>= +<<license>> +<<nagman>> +@ +\eject +\begin{thebibliography}{99} +\bibitem{1} nothing +\end{thebibliography} +\end{document} diff --git a/src/sman/session.c.pamphlet b/src/sman/session.c.pamphlet new file mode 100644 index 00000000..8b6f3e92 --- /dev/null +++ b/src/sman/session.c.pamphlet @@ -0,0 +1,601 @@ +\documentclass{article} +\usepackage{axiom} +\begin{document} +\title{\$SPAD/src/sman session.c} +\author{The Axiom Team} +\maketitle +\begin{abstract} +\end{abstract} +\eject +\tableofcontents +\eject +\section{session} +\subsection{includes} +<<includes>>= +#include "axiom-c-macros.h" +#include <stdlib.h> +#include <sys/time.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> +#ifdef SGIplatform +#include <bstring.h> +#endif +#include "com.h" +#include "bsdsignal.h" +#include "sockio-c.H1" +#include "bsdsignal.H1" +#include "session.H1" + +@ +\subsection{variables} +<<variables>>= +#define BufSize 4096 /* size of communication buffer */ + +typedef struct sock_list { /* linked list of Sock */ + Sock Socket; + struct sock_list *next; +} Sock_List; + +Sock *spad_io = (Sock *) 0; /* to_server socket for SessionIO */ +Sock *spad_server = (Sock *) 0; /* to_server socket for SpadServer */ +Sock *menu_client = (Sock *) 0; /* to_client socket for MenuServerName */ +Sock *active_session = (Sock *) 0; /* pointer to currently active session */ + +Sock_List *plSock = (Sock_List *) 0; + +char big_bad_buf[BufSize]; /* big I/O buffer */ +int num_active_clients = 0; /* number of InterpWindows attached */ +int reading_output = 0; +fd_set session_socket_mask; + +@ +\subsection{usr1\_handler} +<<usr1handler>>= +static void +usr1_handler(int sig) +{ + return; +} + +@ +\subsection{usr2\_handler} +SIGUSR2 is generated by spadclients. +We interpret it as an interrupt for the Lisp. +<<usr2handler>>= +static void +usr2_handler(int sig) +{ + send_signal(spad_server, SIGINT); + return; +} + +@ +\subsection{term\_handler} +<<termhandler>>= +static void +term_handler(int sig) +{ + exit(1); +} + +@ +\subsection{pr} +<<pr>>= +static void +pr() +{ + Sock_List *pSock; + + fprintf(stderr,"The socket list:\n"); + for(pSock=plSock;pSock!=(Sock_List *)0;pSock=pSock->next){ + fprintf(stderr,"(%d,%d,%d)\t",pSock->Socket.pid,2<<(pSock->Socket.socket),pSock->Socket.frame); + } + fprintf(stderr,"\n"); +} + +@ +\subsection{close\_client} +<<closeclient>>= +static void +close_client(int frame) +{ + Sock_List *pSock,*locSock; + int socket_fd; + + /* we will check for frame equality, + kill with send_signal, + notify HyperTex so that it updates its list (if it's a spadbuf), + repair the list, + unset the active_session, + update num_active_clients + */ + + + /* first check head */ +#ifdef DEBUG +fprintf(stderr,"close_client(%d)\n",frame); +#endif + + if ( (plSock) && (plSock->Socket.frame == frame) ){ + socket_fd = plSock->Socket.socket; + send_signal((Sock *)plSock, SIGTERM); + if ( menu_client != (Sock *) 0){ + send_int(menu_client,CloseClient); + send_int(menu_client,(*plSock).Socket.pid); + } +#ifdef DEBUG +fprintf(stderr,"trying to clear %u\n",socket_fd); +#endif + FD_CLR(socket_fd,&session_socket_mask); + locSock = plSock; + if ((*plSock).next == (Sock_List *) 0) + {plSock = (Sock_List *) 0;} + else + {plSock = plSock->next;} + active_session = (Sock *) 0; + num_active_clients--; + free(locSock); + } + + /* now check the rest */ + + else { + for (pSock=plSock; pSock->next != (Sock_List *) 0 ; pSock=pSock->next) + if (pSock->next->Socket.frame == frame){ + socket_fd = pSock->next->Socket.socket; + send_signal((Sock *)pSock->next, SIGTERM); + if ( menu_client != (Sock *) 0){ + send_int(menu_client,CloseClient); + send_int(menu_client,(*plSock).Socket.pid); + } +#ifdef DEBUG +fprintf(stderr,"trying to clear %u\n",socket_fd); +#endif + FD_CLR(socket_fd,&session_socket_mask); + locSock = pSock->next; + if ( pSock->next->next == (Sock_List *) 0 ) + { pSock->next= (Sock_List *) 0;} + else + { pSock->next = pSock->next->next;} + num_active_clients--; + active_session = (Sock *) 0; + free(locSock); + break; + } + } +#ifdef DEBUG +pr(); +#endif +} + +@ +\subsection{read\_SpadServer\_command} +<<readSpadServercommand>>= +static void +read_SpadServer_command(void) +{ + int cmd, frame, num; + cmd = get_int(spad_server); + switch (cmd) { + case EndOfOutput: + if (menu_client != (Sock *) 0) send_signal(menu_client, SIGUSR2); + if (reading_output != 0) reading_output = 0; + break; + case QueryClients: + /* don't count MenuServer */ + num = num_active_clients ; + send_int(spad_server, num); + break; + case CloseClient: + frame = get_int(spad_server); + if (frame != -1) close_client(frame); + break; + case SendXEventToHyperTeX: + break; + default: + fprintf(stderr, "session : unknown command from SpadServer %d\n", cmd); + break; + } +} + +@ +\subsection{test\_sock\_for\_process} +<<testsockforprocess>>= +static int +test_sock_for_process(Sock *sock) +{ + if (sock == (Sock *)0 ) return -1; + return kill(sock->pid, 0); +} + +@ +\subsection{read\_menu\_client\_command} +<<readmenuclientcommand>>= +static void +read_menu_client_command(void) +{ + int cmd,frame, i,socket_fd; + Sock_List *pSock; + + /* save it for possible clearing */ + socket_fd = menu_client->socket; + + if (test_sock_for_process(menu_client) == -1) { + FD_CLR(socket_fd,&session_socket_mask); + menu_client = (Sock *) 0; + reading_output = 0; + return; + } + cmd = get_int(menu_client); + switch(cmd) { + case -1: /* socket closed */ + FD_CLR(socket_fd,&session_socket_mask); + menu_client = (Sock *) 0; + reading_output = 0; + break; + case SwitchFrames: +#ifdef DEBUG +fprintf(stderr,"menu:SwitchFrames\n"); +#endif + frame = get_int(menu_client); + send_int(spad_server, SwitchFrames); + send_int(spad_server, frame); + for(i=0,pSock=plSock; pSock != (Sock_List *) 0 ; i++,pSock=pSock->next) + if ((pSock->Socket.frame == frame)) { + active_session = (Sock *)pSock; + reading_output = 1; + break; + } + if (i == num_active_clients) { + /* fprintf(stderr, "Couldn't find socket for frame %d\n", frame); */ + } + break; + case QuerySpad: +#ifdef DEBUG +fprintf(stderr,"menu:QuerySpad\n"); +#endif + send_int(menu_client, reading_output); + break; + default: + fprintf(stderr, "session : unknown command from MenuServer: %d\n", cmd); + menu_client = (Sock *) 0; + break; + } +} + +@ +\subsection{read\_from\_spad\_io} +<<readfromspadio>>= +static void +read_from_spad_io(void) +{ + int ret_code; + ret_code = sread(spad_io, big_bad_buf, BufSize, "session: stdout socket"); + if (ret_code == -1) return; + if(active_session != (Sock *) 0) { + ret_code = swrite(active_session, big_bad_buf, ret_code, + NULL); + } +} + +@ +\subsection{kill\_spad} +<<killspad>>= +static void +kill_spad(void) +{ + int i; + Sock_List *pSock; + + send_signal(spad_server, SIGTERM); + for (pSock=plSock,i=0; + (i<num_active_clients) && (pSock != (Sock_List *) 0); + i++,pSock=pSock->next) { + if ((pSock->Socket).socket != 0) + send_signal((Sock *)pSock, SIGTERM); + } + if (menu_client != (Sock *) 0) send_signal(menu_client, SIGTERM); + exit(0); +} + +@ +\subsection{accept\_session\_connection} +<<acceptsessionconnection>>= +static int +accept_session_connection(Sock *server_sock) +{ + int sock_fd, ret_code; + Sock_List *pls; + + /* Could be three things : KillSpad MenuServer InterpWindow */ + + pls = (Sock_List *) malloc(sizeof (Sock_List)); + sock_fd = accept(server_sock->socket, 0, 0); + if (sock_fd == -1) { + perror("session : accepting connection"); + return -1; + } + (pls->Socket).socket = sock_fd; + get_socket_type((Sock *)pls); + + switch((pls->Socket).purpose) { + case KillSpad: + kill_spad(); + return KillSpad; + free(pls); + case MenuServer: +#ifdef DEBUG + fprintf(stderr,"session: accepted MenuServer , fd = %d\n",sock_fd); +#endif + menu_client = &(pls->Socket); + FD_SET(menu_client->socket, &session_socket_mask); + return MenuServer; + case InterpWindow: +#ifdef DEBUG + fprintf(stderr,"session: accepted InterpWindow , fd = %d\n",sock_fd); +#endif + + /* new Sock is put at the head of the list */ + if (plSock == (Sock_List *)0 ) { + plSock = pls; + plSock->next = (Sock_List *)0 ; + } + else{ + pls->next = plSock; + plSock = pls; + } + + /* we need to maintain session_socket_mask here since we roll our own accept */ + + FD_SET(plSock->Socket.socket, &session_socket_mask); + send_int(spad_server, CreateFrame); + plSock->Socket.frame = get_int(spad_server); + active_session = (Sock *)plSock; + get_string_buf(spad_server, big_bad_buf, BufSize); + ret_code = swrite((Sock *)plSock, big_bad_buf, strlen(big_bad_buf)+1, + "session: writing to InterpWindow"); + if (ret_code == -1) + return -1; + num_active_clients++; +#ifdef DEBUG +pr(); +#endif + return plSock->Socket.purpose; + } + return (-1); +} + +@ +\subsection{read\_from\_session} +<<readfromsession>>= +static void +read_from_session(Sock *sock) +{ + int ret_code; + if (sock != active_session) { + send_int(spad_server, SwitchFrames); + send_int(spad_server, sock->frame); + } + active_session = sock; + ret_code = sread(sock, big_bad_buf, BufSize, + "session: reading InterpWindow"); + if (ret_code == -1) { + active_session = (Sock *) 0; + reading_output = 0; + return; + } + ret_code = swrite(spad_io, big_bad_buf, ret_code, + "session: writing SessionIO"); + if (ret_code == -1) { + active_session = (Sock *)0 ; + reading_output = 0; + return; + } + reading_output = 1; +} + +@ +\subsection{manage\_sessions} +<<managesessions>>= +static void +manage_sessions(void) +{ + int ret_code; + fd_set rd, wr, ex; + Sock_List *pSock; + + reading_output = 0; + while (1) { + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&ex); + + /* Allow server socket and all connections if not waiting for output + socket_mask is maintained by libspad.a */ +#ifdef DEBUG +fprintf(stderr,"session_socket_mask=%u ",*((long *)session_socket_mask.fds_bits)); +#endif + rd = session_socket_mask; + if (!reading_output) { + rd = session_socket_mask; + } + + /* Allow the active_session if set */ + if (active_session) FD_SET(active_session->socket, &rd); +#ifdef DEBUG +fprintf(stderr,"[rd=%u ",*((long *)rd.fds_bits)); +#endif + + ret_code = sselect(FD_SETSIZE, &rd, &wr, &ex, NULL); + if (ret_code == -1) { + break; + } +#ifdef DEBUG +fprintf(stderr,"rd=%u]\n",*((long *)rd.fds_bits)); +#endif + + if ((menu_client != (Sock *) 0) && FD_ISSET(menu_client->socket, &rd)) { + /* MenuServer wants to talk */ + read_menu_client_command(); } + + + if (FD_ISSET(spad_io->socket, &rd)) { + /* Lisp has output */ + read_from_spad_io(); } + + + if (FD_ISSET(server[1].socket, &rd)) { + /* Someone wants to connect to our server socket */ + accept_session_connection(server+1); } + + + for(pSock=plSock; pSock != (Sock_List *) 0 ; pSock=pSock->next) { + if ((active_session == (Sock *)pSock || !reading_output) && + (pSock->Socket).socket>0 && FD_ISSET(pSock->Socket.socket, &rd)) { + /* An InterpWindow */ + read_from_session((Sock *)pSock); } + } + + + if (FD_ISSET(spad_server->socket, &rd)) { + /* The Lisp socket */ + read_SpadServer_command(); } + } +} + +@ +\subsection{main} +<<main>>= +int +main(void) +{ + +#ifdef DEBUG2 + /* delay for attaching with debugger before interesting things happen */ + sleep(30); +#endif + + /* spad_server connects to Lisp server socket + read_SpadServer_command handles requests */ + spad_server = connect_to_local_server(SpadServer, SessionManager, Forever); + if (spad_server == (Sock *) 0) { + fprintf(stderr, "session: Cannot connect to AXIOM server!\n"); + exit(0); + } + else { +#ifdef DEBUG + fprintf(stderr, "session: connected SpadServer , fd = %d\n", + spad_server->socket); +#endif + FD_SET(spad_server->socket, &session_socket_mask); + } + + + /* spad_io connects to SessionIOName server socket + this is Lisp std IO read_from_spad_io handles requests */ + spad_io = connect_to_local_server(SessionIOName, SessionIO, Forever); + if (spad_io == (Sock *) 0) { + fprintf(stderr, "session: Cannot connect to AXIOM IO!\n"); + exit(0); + } + else { +#ifdef DEBUG + fprintf(stderr,"session: connected SessionIOName , fd = %d\n", + spad_io->socket); +#endif + FD_SET(spad_io->socket, &session_socket_mask); + } + bsdSignal(SIGUSR2, usr2_handler,DontRestartSystemCalls); + bsdSignal(SIGUSR1, usr1_handler,RestartSystemCalls); + bsdSignal(SIGINT, SIG_IGN,RestartSystemCalls); + bsdSignal(SIGTERM, term_handler,RestartSystemCalls); + + /* open_server opens the server socket so that we can accept connections + we expect connections from spadbuf/spadclient(purpose:InterpWindow) + and hypertex (MenuServer) */ + + if (open_server(SessionServer) == -2) { + fprintf(stderr, "session: Cannot make server socket!\n"); + exit(-1); + } + else { +#ifdef DEBUG + fprintf(stderr, "session: opened SessionServer , fd = %d\n", + server[1].socket); +#endif + FD_SET(server[1].socket,&session_socket_mask); + } + manage_sessions(); + return(0); +} + +@ +\subsection{session} +<<session>>= +/* #define DEBUG */ +#define _SESSION_C + +<<includes>> +<<variables>> +<<usr1handler>> +<<usr2handler>> +<<termhandler>> +<<pr>> +<<closeclient>> +<<readSpadServercommand>> +<<testsockforprocess>> +<<readmenuclientcommand>> +<<readfromspadio>> +<<killspad>> +<<acceptsessionconnection>> +<<readfromsession>> +<<managesessions>> +<<main>> + +@ +\section{License} +<<license>>= +/* +Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of The Numerical ALgorithms Group Ltd. nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +@ +<<*>>= +<<license>> +<<session>> +@ +\eject +\begin{thebibliography}{99} +\bibitem{1} nothing +\end{thebibliography} +\end{document} diff --git a/src/sman/sman.c.pamphlet b/src/sman/sman.c.pamphlet new file mode 100644 index 00000000..d0419627 --- /dev/null +++ b/src/sman/sman.c.pamphlet @@ -0,0 +1,1111 @@ +\documentclass{article} +\usepackage{axiom} + +\title{\$SPAD/src/sman sman} +\author{The Axiom Team} + +\begin{document} +\maketitle + +\begin{abstract} +\end{abstract} +\eject + +\tableofcontents +\eject + +\section{sman.h} +<<sman.h>>= +/* Process control definitions. Used by fork_you and spawn_of_hell */ + +/* When a process dies it kills off everything else */ +#define Die 1 +/* When a process dies, do nothing */ +#define NadaDelShitsky 2 +/* When a process dies start it up again */ +#define DoItAgain 3 + +typedef struct spad_proc { + int proc_id; /* process id of child */ + int death_action; /* one of the above constants */ + char *command; /* sh command line to restart the process */ + struct spad_proc *next; +} SpadProcess; + +@ +\section{sman} +\subsection{includes} +<<includes>>= +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <pwd.h> +#include <fcntl.h> +#include <termios.h> +#include <errno.h> +#include <sys/time.h> +#include <sys/wait.h> +#include <signal.h> + +#include "axiom-c-macros.h" + +#if defined(SUN4OS5platform) || defined(HP10platform) +#include <sys/stropts.h> +#endif + +#include "com.h" +#include "bsdsignal.h" +#include "sman.h" + +#include "bsdsignal.H1" +#include "sockio-c.H1" +#include "openpty.H1" +#include "sman.H1" + +@ +\subsection{variables} +We add a debug flag so we can print information about what \Tool{sman} +is trying to do. This change is pervasive as it touches nearly every +routine. +<<debugflag>>= +int tpd=0; /* to-print-debug information */ +@ +This line is no longer used. We would completely elide it except that +it would raise spurious issues about deleting credit and/or copyright +information. +\begin{verbatim} +char *start_line = +"AKCL (Austin Kyoto Common Lisp) Version(1.568) Thu Aug 22 16:49:01 EDT 1991\ +\r\nContains Enhancements by W. Schelter\r\n"; +\end{verbatim} +We modified the place where the command list lives. +The command list used to live in +\begin{verbatim} +$AXIOM/../../share/algebra/command.list +\end{verbatim} +but the open source version of the system no longer has a share +subdirectory so we move this to the lib subdirectory. +<<clefprogram>>= +char *ClefProgram = + "$AXIOM/bin/clef -f $AXIOM/lib/command.list -e "; +@ +and we change the command line arguments +<<clefprogram1>>= + ClefProgram = + strcat(ClefCommandLine, " -f $AXIOM/lib/command.list -e "); +@ +<<variables>>= +char *ws_path; /* location of the AXIOM executable */ +int start_clef; /* start clef under spad */ +int start_graphics; /* start the viewman */ +int start_nagman; /* start the nagman */ +int start_ht; /* start hypertex */ +int start_spadclient; /* Start the client spad buffer */ +int start_local_spadclient; /* Start the client spad buffer */ +int use_X; /* Use the X windows environment */ +int server_num; /* AXIOM server number */ +<<debugflag>> + +/************************************************/ +/* definitions of programs which sman can start */ +/************************************************/ + +char *GraphicsProgram = "$AXIOM/lib/viewman"; +char *NagManagerProgram = "$AXIOM/lib/nagman"; +char *HypertexProgram = "$AXIOM/lib/hypertex -s"; +<<clefprogram>> +char *SessionManagerProgram = "$AXIOM/lib/session"; +char *SpadClientProgram = "$AXIOM/lib/spadclient"; +char *PasteFile = NULL; +char *MakeRecordFile = NULL; +char *VerifyRecordFile = NULL; + +SpadProcess *spad_process_list = NULL; +/***************************/ +/* sman defaults file name */ +/***************************/ + +#define SpadDefaultFile "spadprof.input" + +char ClefCommandLine[256]; + +#define BufSize 4096 /* size of communication buffer */ +char big_bad_buf[BufSize]; /* big I/O buffer */ + +Sock *session_io = NULL; /* socket connecting to session manager */ + +/***********************************************************/ +/* Some characters used and externally defined in edible.h */ +/***********************************************************/ + +unsigned char _INTR, _QUIT, _ERASE, _KILL, _EOF, _EOL, _RES1, _RES2; + +/*************************************/ +/* Stuff for opening pseudo-terminal */ +/*************************************/ + +int ptsNum, ptcNum; +char ptsPath[20], ptcPath[20]; + +char **new_envp; /* new environment for AXIOM */ +int child_pid; /* child's process id */ +struct termios oldbuf; /* the original settings */ +struct termios childbuf; /* terminal structure for user i/o */ + + +int nagman_signal=0; +int death_signal = 0; + +@ +\subsection{process\_arguments} +<<processarguments>>= +static void +process_arguments(int argc,char ** argv) +{ + int arg; + if (tpd == 1) fprintf(stderr,"sman:process_arguments entered\n"); + for (arg = 1; arg < argc; arg++) { + if (strcmp(argv[arg], "-debug") == 0) + tpd = 1; + else if (strcmp(argv[arg], "-noclef") == 0) + start_clef = 0; + else if (strcmp(argv[arg], "-clef") == 0) + start_clef = 1; + else if (strcmp(argv[arg], "-gr") == 0) + start_graphics = 1; + else if (strcmp(argv[arg], "-nogr") == 0) + start_graphics = 0; + else if (strcmp(argv[arg], "-nag") == 0) + start_nagman = 1; + else if (strcmp(argv[arg], "-nonag") == 0) + start_nagman = 0; + else if (strcmp(argv[arg], "-ht") == 0) + start_ht = 1; + else if (strcmp(argv[arg], "-noht") == 0) + start_ht = 0; + else if (strcmp(argv[arg], "-iw") == 0) + start_spadclient = 1; + else if (strcmp(argv[arg], "-ihere") == 0) + start_local_spadclient = 1; + else if (strcmp(argv[arg], "-noihere") == 0) + start_local_spadclient = 0; + else if (strcmp(argv[arg], "-noiw") == 0) + start_spadclient = 0; + else if (strcmp(argv[arg], "-ws") == 0) + ws_path = argv[++arg]; + else if (strcmp(argv[arg], "-comp") == 0) + ws_path = "$AXIOM/etc/images/comp"; + else if (strcmp(argv[arg], "-nox") == 0) + { + use_X = 0; + start_local_spadclient = 1; + start_spadclient = 0; + start_ht = 0; + start_graphics = 0; + } + else if (strcmp(argv[arg], "-grprog") == 0) + GraphicsProgram = argv[++arg]; + else if (strcmp(argv[arg], "-nagprog") == 0) + NagManagerProgram = argv[++arg]; + else if (strcmp(argv[arg], "-htprog") == 0) + HypertexProgram = argv[++arg]; + else if (strcmp(argv[arg], "-clefprog") == 0) { + strcpy(ClefCommandLine,argv[++arg]); +<<clefprogram1>> + } + else if (strcmp(argv[arg], "-sessionprog") == 0) + SessionManagerProgram = argv[++arg]; + else if (strcmp(argv[arg], "-clientprog") == 0) + SpadClientProgram = argv[++arg]; + else if (strcmp(argv[arg], "-rm") == 0) + MakeRecordFile = argv[++arg]; + else if (strcmp(argv[arg], "-rv") == 0) + VerifyRecordFile = argv[++arg]; + else if (strcmp(argv[arg], "-paste") == 0) + PasteFile = argv[++arg]; + else { + fprintf(stderr, "Usage: sman <-clef|-noclef> \ +<-gr|-nogr> <-ht|-noht> <-iw|-noiw> <-nag|-nonag> <-nox> <-comp> <-ws spad_workspace> \ +<-grprog path> <-htprog path> <-clefprog path> <-sessionprog path> <-nagprog path> \ +<-clientprog path>\n"); + exit(-1); + } + } + if (tpd == 1) + { fprintf(stderr," sman "); + if (start_clef == 0) + fprintf(stderr,"-noclef "); + else + fprintf(stderr,"-clef "); + if (start_graphics == 0) + fprintf(stderr,"-nogr "); + else + fprintf(stderr,"-gr "); + if (start_nagman == 0) + fprintf(stderr,"-nonag "); + else + fprintf(stderr,"-nag "); + if (start_ht == 0) + fprintf(stderr,"-noht "); + else + fprintf(stderr,"-ht "); + if (start_spadclient == 0) + fprintf(stderr,"-noiw "); + else + fprintf(stderr,"-iw "); + if (start_local_spadclient == 0) + fprintf(stderr,"-noihere "); + else + fprintf(stderr,"-ihere "); + if (start_local_spadclient == 0) + fprintf(stderr,"-noihere "); + else + fprintf(stderr,"-ihere "); + if (use_X == 0) + fprintf(stderr,"-nox "); + fprintf(stderr,"-ws "); + fprintf(stderr,"'%s' ",ws_path); + fprintf(stderr,"-grprog "); + fprintf(stderr,"'%s' ",GraphicsProgram); + fprintf(stderr,"-nagprog "); + fprintf(stderr,"'%s' ",NagManagerProgram); + fprintf(stderr,"-htprog "); + fprintf(stderr,"'%s' ",HypertexProgram); + fprintf(stderr,"-clefprog "); + fprintf(stderr,"'%s' ",ClefCommandLine); + fprintf(stderr,"-sessionprog "); + fprintf(stderr,"'%s' ",SessionManagerProgram); + fprintf(stderr,"-clientprog "); + fprintf(stderr,"'%s' ",SpadClientProgram); + fprintf(stderr,"-rm "); + fprintf(stderr,"'%s' ",MakeRecordFile); + fprintf(stderr,"-rv "); + fprintf(stderr,"'%s' ",VerifyRecordFile); + fprintf(stderr,"-paste "); + fprintf(stderr,"'%s' ",PasteFile); + fprintf(stderr,"\n"); + } + if (tpd == 1) fprintf(stderr,"sman:process_arguments exit\n"); +} + +@ +\subsection{should\_I\_clef} +<<shouldIclef>>= +static int +should_I_clef(void) +{ + return(1); +} + +@ +\subsection{in\_X} +<<inX>>= +static int +in_X(void) +{ + if (getenv("DISPLAY")) return 1; + return 0; +} + +@ +\subsection{set\_up\_defaults} +These are the default values for sman. A '1' value means that +sman will try to start the given process, a '0' value means not +starting the process. + +We do not have replacement code for the [[nagman]] process nor +do we have a copy of the [[nag fortran library]] to test the process. +Until this changes we set [[start_nagman = 0]] in order to disable +starting this process by default. +<<setupdefaults>>= +static void +set_up_defaults(void) +{ + if (tpd == 1) fprintf(stderr,"sman:set_up_defaults entered\n"); + start_clef = should_I_clef(); + start_graphics = 1; + start_nagman = 0; + start_ht = 1; + start_spadclient = 0; + start_local_spadclient = 1; + use_X = isatty(0) && in_X(); + ws_path = "$AXIOM/bin/AXIOMsys"; + if (tpd == 1) fprintf(stderr,"sman:set_up_defaults exit\n"); +} + +@ +\subsection{process\_options} +<<processoptions>>= +static void +process_options(int argc, char **argv) +{ + if (tpd == 1) fprintf(stderr,"sman:process_options entered\n"); + set_up_defaults(); + process_arguments(argc, argv); + if (tpd == 1) fprintf(stderr,"sman:process_options exit\n"); +} + +@ +\subsection{death\_handler} +<<deathhandler>>= +static void +death_handler(int sig) +{ + death_signal = 1; +} + +@ +\subsection{nagman\_handler} +<<nagmanhandler>>= +static void +nagman_handler(int sig) +{ + nagman_signal=1; +} + +@ +\subsection{sman\_catch\_signals} +<<smancatchsignals>>= +static void +sman_catch_signals(void) +{ + + /* Set up the signal handlers for sman */ + bsdSignal(SIGINT, SIG_IGN,RestartSystemCalls); + bsdSignal(SIGTERM, death_handler,RestartSystemCalls); + bsdSignal(SIGQUIT, death_handler,RestartSystemCalls); + bsdSignal(SIGHUP, death_handler,RestartSystemCalls); + bsdSignal(SIGILL, death_handler,RestartSystemCalls); + bsdSignal(SIGTRAP, death_handler,RestartSystemCalls); + bsdSignal(SIGIOT, death_handler,RestartSystemCalls); + bsdSignal(SIGBUS, death_handler,RestartSystemCalls); + bsdSignal(SIGSEGV, death_handler,RestartSystemCalls); + /* don't restart wait call on SIGUSR1 */ + bsdSignal(SIGUSR1, nagman_handler,DontRestartSystemCalls); + /* ONLY nagman should send this. + If an error (such as C-c) interrupts a NAGLINK call, nagman + gets a signal to clean up. We need to start another nagman + almost immediately to process the next NAGLINK request. + Since nagman takes a while to clean up, we treat it specially. + nagman should send a signal (USR1) to sman. + sman should respond by spawning a new nagman. + + so nagman is NOT a DoItAgain but a NadaDelShitsky. + + The USR1 mechanism does not work for HPUX 9 - use DoItAgain + */ + +} + +@ +\subsection{fix\_env} +insert SPADSERVER and SPADNUM variables into the environemnt +<<fixenv>>= +static void +fix_env(char **envp, int spadnum) +{ + int len, i; + char *sn; + for(len = 0; envp[len] != NULL; len++); + new_envp = (char **) malloc((len + 3) * sizeof(char *)); + new_envp[0] = "SPADSERVER=TRUE"; + sn = (char *) malloc(20 * sizeof(char)); + sprintf(sn, "SPADNUM=%d", spadnum); + new_envp[1] = sn; + for(i=0; i<=len; i++) + new_envp[i+2] = envp[i]; +} + +@ +\subsection{init\_term\_io} +<<inittermio>>= +static void +init_term_io(void) +{ + if(!isatty(0)) return; + if( tcgetattr(0, &oldbuf) == -1) { + perror("getting termios"); + return ; /* exit(-1); */ + } + if( tcgetattr(0, &childbuf) == -1) { + perror("getting termios"); + return ; /* exit(-1); */ + } + _INTR = oldbuf.c_cc[VINTR]; + _QUIT = oldbuf.c_cc[VQUIT]; + _ERASE = oldbuf.c_cc[VERASE]; + _KILL = oldbuf.c_cc[VKILL]; + _EOF = oldbuf.c_cc[VEOF]; + _EOL = oldbuf.c_cc[VEOL]; +} + +@ +\subsection{strPrefix} +<<strPrefix>>= +static char * +strPrefix(char *prefix,char * s) +{ + while (*prefix != '\0' && *prefix == *s) { + prefix++; + s++; + } + if (*prefix == '\0') return s; + return NULL; +} + +@ +\subsection{check\_spad\_proc} +<<checkspadproc>>= +static void +check_spad_proc(char *file, char *prefix) +{ + char *num; + int pid; + if ((num = strPrefix(prefix, file))) { + pid = atoi(num); + if (pid > 2) { + kill(pid, 0); + if (kill(pid, 0) == -1 && errno == ESRCH) { + unlink(file); + } + } + } +} + +@ +\subsection{clean\_up\_old\_sockets} +<<cleanupoldsockets>>= +static void +clean_up_old_sockets(void) +{ + char com[512], tmp_file[128]; + FILE *file; + int len; + sprintf(tmp_file, "/tmp/socks.%d", server_num); + sprintf(com, "ls /tmp/.d* /tmp/.s* /tmp/.i* /tmp/.h* 2> %s > %s", + tmp_file, tmp_file); + system(com); + file = fopen(tmp_file, "r"); + if (file == NULL) { + fprintf(stderr, "Can't open socket listing file\n"); + return; + } + while(fgets(com, 512, file) != NULL) { + len = strlen(com); + if (len) com[len-1] = '\0'; + else break; + check_spad_proc(com, "/tmp/.d"); + check_spad_proc(com, "/tmp/.s"); + check_spad_proc(com, "/tmp/.i"); + check_spad_proc(com, "/tmp/.h"); + } + fclose(file); + unlink(tmp_file); +} + +@ +\subsection{fork\_you} +<<forkyou>>= +static SpadProcess * +fork_you(int death_action) +{ + /* fork a new process, giving it a default death action */ + /* return NULL in child, SpadProcess in parent */ + int child_pid = fork(); + SpadProcess *proc; + if (!child_pid) return NULL; + proc = (SpadProcess *) malloc(sizeof(SpadProcess)); + proc->proc_id = child_pid; + proc->death_action = death_action; + proc->command = NULL; + proc->next = spad_process_list; + spad_process_list = proc; + return proc; +} + +@ +\subsection{exec\_command\_env} +<<execcommandenv>>= +static void +exec_command_env(char *command,char ** env) +{ + char new_command[512]; + sprintf(new_command, "exec %s", command); + execle("/bin/sh","/bin/sh", "-c", new_command, 0, env); +} + +@ +\subsection{spawn\_of\_hell} +<<spawnofhell>>= +static SpadProcess * +spawn_of_hell(char *command, int death_action) +{ + SpadProcess *proc = fork_you(death_action); + if (proc != NULL) { + proc->command = command; + return proc; + } + exec_command_env(command, new_envp); + return NULL; +} + +@ +\subsection{start\_the\_spadclient} +run a AXIOM client in the main process +<<startthespadclient>>= +static void +start_the_spadclient(void) +{ + char command[256]; + if (start_clef) +#ifdef RIOSplatform + sprintf(command, + "aixterm -sb -sl 500 -name axiomclient -n AXIOM -T AXIOM -e %s %s", + ClefProgram, SpadClientProgram); +#else + sprintf(command, + "xterm -sb -sl 500 -name axiomclient -n AXIOM -T AXIOM -e %s %s", + ClefProgram, SpadClientProgram); +#endif + else +#ifdef RIOSplatform + sprintf(command, + "aixterm -sb -sl 500 -name axiomclient -n AXIOM -T AXIOM -e %s", + SpadClientProgram); +#else + sprintf(command, + "xterm -sb -sl 500 -name axiomclient -n AXIOM -T AXIOM -e %s", + SpadClientProgram); +#endif + if (tpd == 1) + fprintf(stderr,"sman:start_the_spadclient: %s\n",command); + spawn_of_hell(command, NadaDelShitsky); +} + +@ +\subsection{start\_the\_local\_spadclient} +<<startthelocalspadclient>>= +static void +start_the_local_spadclient(void) +{ + char command[256]; + if (start_clef) + sprintf(command, "%s %s", ClefProgram, SpadClientProgram); + else + sprintf(command, "%s", SpadClientProgram); + if (tpd == 1) + fprintf(stderr,"sman:start_the_local_spadclient: %s\n",command); + spawn_of_hell(command, NadaDelShitsky); +} + +@ +\subsection{start\_the\_nagman} +<<startthenagman>>= +static void +start_the_nagman(void) +{ +#if defined(HP9platform) + spawn_of_hell(NagManagerProgram,DoItAgain); +#else + spawn_of_hell(NagManagerProgram,NadaDelShitsky ); +#endif +} + +@ +\subsection{start\_the\_session\_manager} +<<startthesessionmanager>>= +static void +start_the_session_manager(void) +{ + spawn_of_hell(SessionManagerProgram, Die); +} + +@ +\subsection{start\_the\_hypertex} +<<startthehypertex>>= +static void +start_the_hypertex(void) +{ + char prog[512]; + + if (PasteFile){ + sprintf(prog, "%s -k -ip %s", HypertexProgram, PasteFile); + spawn_of_hell(prog, NadaDelShitsky); + } + else if (MakeRecordFile){ + sprintf(prog, "%s -k -rm %s", HypertexProgram,MakeRecordFile ); + spawn_of_hell(prog, NadaDelShitsky); + } + else if (VerifyRecordFile){ + sprintf(prog, "%s -k -rv %s", HypertexProgram, VerifyRecordFile); + spawn_of_hell(prog, NadaDelShitsky); + } + else spawn_of_hell(HypertexProgram, NadaDelShitsky); +} + +@ +\subsection{start\_the\_graphics} +<<startthegraphics>>= +static void +start_the_graphics(void) +{ + spawn_of_hell(GraphicsProgram, DoItAgain); +} + +@ +\subsection{fork\_Axiom} +<<forkAxiom>>= +/* Start the AXIOM session in a separate process, */ +/* using a pseudo-terminal to catch all input and output */ +static void +fork_Axiom(void) +{ + char augmented_ws_path[256]; /* will append directory path */ + char *tmp_pointer; + SpadProcess *proc; + + proc = fork_you(Die); + child_pid = (proc == NULL ? 0 : proc->proc_id); + switch(child_pid) { + case -1 : + fprintf(stderr, "Can't create a new process \n"); + exit(0); + case 0: + /* Dissasociate from my parents group so all my child processes */ + /* look at my terminal as the controlling terminal for the */ + /* group */ + + if(setsid() < 0) { + perror("Dissassociating from parents group"); + exit(-1); + } + + close(ptsNum); + /* Now reopen the server side, so that pg, su, etc. work properly */ + + if ((ptsNum = open(ptsPath, O_RDWR)) < 0 ) { + perror("fork_Axiom: Failed to reopen server"); + exit(-1); + } +#if defined(SUN4OS5platform) || defined(HP10platform) + ioctl(ptsNum,I_PUSH,"ptem"); + ioctl(ptsNum,I_PUSH,"ldterm"); +#endif + + /* since I am the child, I can close ptc, and dup pts for all its */ + /* standard descriptors */ + + if( (dup2(ptsNum, 0) == -1) || + (dup2(ptsNum, 1) == -1) || + (dup2(ptsNum, 2) == -1) ) { + perror("trying to dupe the child"); + exit(-1); + } + close(ptcNum); + close(ptsNum); + + + /* I also have to turn off echoing, since I am echoing all the */ + /* input myself */ + + childbuf.c_lflag &= ~ECHO; + if( tcsetattr(0, TCSAFLUSH, &childbuf) == -1) { + perror("setting the term buffer"); + exit(-1); + } + strcpy(augmented_ws_path,ws_path); /* write the name */ + strcat(augmented_ws_path," "); /* space */ + strcat(augmented_ws_path,ws_path); /* name again */ + tmp_pointer = (char *) + strrchr(augmented_ws_path,'/'); /*pointer to last / */ + *(++tmp_pointer) = '\0'; + exec_command_env(augmented_ws_path, new_envp); + + /* fprintf(stderr, "Cannot execute the %s system.\n", ws_path); */ + + exit(0); + } +} + +@ +\subsection{start\_the\_Axiom} +<<starttheAxiom>>= +static void +start_the_Axiom(char **envp) +{ + server_num = make_server_number(); + clean_up_old_sockets(); + if (server_num == -1) { + fprintf(stderr, "could not get an AXIOM server number\n"); + exit(-1); + } + if (ptyopen(&ptcNum, &ptsNum, ptcPath, ptsPath) == -1) { + perror("start_the_Axiom: ptyopen failed"); + exit(-1); + } + fix_env(envp, server_num); + fork_Axiom(); + close(ptsNum); +} + +@ +\subsection{clean\_up\_sockets} +<<cleanupsockets>>= +static void +clean_up_sockets(void) +{ + char name[256]; + sprintf(name, "%s%d", SpadServer, server_num); + unlink(name); + sprintf(name, "%s%d", SessionServer, server_num); + unlink(name); + sprintf(name, "%s%d", SessionIOName, server_num); + unlink(name); + sprintf(name, "%s%d", MenuServerName, server_num); + unlink(name); +} + +@ +\subsection{read\_from\_spad\_io} +<<readfromspadio>>= +static void +read_from_spad_io(int ptcNum) +{ + int ret_code = 0, i=0; + static int mes_len =0; + ret_code = read(ptcNum, big_bad_buf, BufSize); + if (ret_code == -1) { + clean_up_sockets(); + exit(-1); + } + if (session_io == NULL) { + if (ret_code < mes_len) + mes_len -= ret_code; + else { + if (mes_len > 0) { + i = mes_len; + mes_len = 0; + } + else + i = 0; + ret_code = write(1, big_bad_buf+i, ret_code-i); + } + } + else + ret_code = swrite(session_io, big_bad_buf, ret_code, + "writing to session man"); + if (ret_code == -1) { + perror("writing output to session manager"); + clean_up_sockets(); + exit(-1); + } +} + +@ +\subsection{read\_from\_manager} +<<readfrommanager>>= +static void +read_from_manager(int ptcNum) +{ + int ret_code; + ret_code = sread(session_io, big_bad_buf, BufSize, "reading session io"); + if (ret_code == -1) { + return; + } + ret_code = write(ptcNum, big_bad_buf, ret_code); + if (ret_code == -1) { + return; + } +} + +@ +\subsection{manage\_spad\_io} +<<managespadio>>= +static void +manage_spad_io(int ptcNum) +{ + int ret_code, i, p; + fd_set rd; + while (1) { + rd = socket_mask; + FD_SET(ptcNum, &rd); + if (session_io != NULL) + FD_SET(session_io->socket, &rd); + ret_code = sselect(FD_SETSIZE, &rd, 0, 0, NULL); + if (ret_code == -1) { + perror("Session manager select"); + clean_up_sockets(); + exit(-1); + } + if (FD_ISSET(ptcNum, &rd)) { + read_from_spad_io(ptcNum); + } + for(i=0; i<2; i++) { + if (server[i].socket > 0 && FD_ISSET(server[i].socket, &rd)) { + p = accept_connection(server+i); + switch(p) { + case SessionIO: + session_io = purpose_table[SessionIO]; + /* printf("connected session manager\n\r");*/ + printf("\n"); + break; + default: + printf("sman: Unkown connection request type: %d\n", p); + break; + } + } + } + if (session_io != NULL && FD_ISSET(session_io->socket, &rd)) { + read_from_manager(ptcNum); + } + } +} + +@ +\subsection{init\_spad\_process\_list} +<<initspadprocesslist>>= +static void +init_spad_process_list(void) +{ + spad_process_list = NULL; +} + +@ +\subsection{print\_spad\_process\_list} +<<printspadprocesslist>>= +#if 0 +static void +print_spad_process_list() +{ + SpadProcess *proc; + for(proc = spad_process_list; proc != NULL; proc = proc->next) + fprintf(stderr, "proc_id = %d, death_action = %d\n", proc->proc_id, + proc->death_action); +} +#endif + +@ +\subsection{find\_child} +<<findchild>>= +static SpadProcess * +find_child(int proc_id) +{ + SpadProcess *proc; + for(proc = spad_process_list; proc != NULL; proc = proc->next) + if (proc->proc_id == proc_id) return proc; + return NULL; +} + +@ +\subsection{kill\_all\_children} +<<killallchildren>>= +static void +kill_all_children(void) +{ + char name[256]; + SpadProcess *proc; + + + for(proc = spad_process_list; proc != NULL; proc = proc->next) { + kill(proc->proc_id, SIGTERM); + } + sprintf(name, "/tmp/hyper%d.input",server_num); + unlink(name); + +} + +@ +\subsection{clean\_up\_terminal} +<<cleanupterminal>>= +static void +clean_up_terminal(void) +{ + tcsetattr(0, TCSAFLUSH, &oldbuf); +} + +@ +\subsection{monitor\_children} +<<monitorchildren>>= +static void +monitor_children(void) +{ + int dead_baby, stat; + SpadProcess *proc; + while (1) { + stat = 0; + dead_baby = wait(&stat); + /* Check the value of dead_baby, since wait may have returned + a pid but subsequently we have received a signal. Yeuch! */ + if (dead_baby == -1 && death_signal) { + kill_all_children(); + clean_up_sockets(); + clean_up_terminal(); + sleep(2); + exit(0); + } + /* Check the value of dead_baby, since wait may have returned + a pid but subsequently we have received a signal. Yeuch! */ + if(dead_baby == -1 && nagman_signal) { + nagman_signal=0; + spawn_of_hell(NagManagerProgram,NadaDelShitsky); + continue; + } + + if (dead_baby == -1) { + fprintf(stderr, "sman: wait returned -1\n"); + continue; + } + proc = find_child(dead_baby); + if (proc == NULL) { + /* fprintf(stderr, "sman: %d is not known to be a child process\n", + dead_baby); + */ + continue; + } + switch(proc->death_action) { + case Die: + kill_all_children(); + clean_up_sockets(); + clean_up_terminal(); + sleep(2); + exit(0); + case NadaDelShitsky: + break; + case DoItAgain: + spawn_of_hell(proc->command, DoItAgain); + break; + } + } +} + +@ +\subsection{main} +The main procedure should return an [[int]]. We change the return value +here and in [[src/include/sman.H1]]. +<<result>>= + return(0); +@ +<<main>>= +int +main(int argc, char *argv[],char *envp[]) +{ + if (tpd == 1) fprintf(stderr,"sman:main entered\n"); + bsdSignal(SIGINT, SIG_IGN,RestartSystemCalls); + process_options(argc, argv); + + init_term_io(); + init_spad_process_list(); + start_the_Axiom(envp); + if (open_server(SessionIOName) == -2) { + fprintf(stderr, "Fatal error opening I/O socket\n"); + clean_up_sockets(); + exit(-1); + } + start_the_session_manager(); + if (start_spadclient) start_the_spadclient(); + if (start_local_spadclient) start_the_local_spadclient(); + if (start_nagman) start_the_nagman(); + if (start_ht) start_the_hypertex(); + if (start_graphics) start_the_graphics(); + sleep(1); + + if (fork_you(Die) != NULL) { + sman_catch_signals(); + monitor_children(); + exit(0); + } + manage_spad_io(ptcNum); + if (tpd == 1) fprintf(stderr,"sman:main exit\n"); +<<result>> +} + +@ +\subsection{sman} +<<sman>>= +#define _SMAN_C + +<<includes>> +<<variables>> +<<processarguments>> +<<shouldIclef>> +<<inX>> +<<setupdefaults>> +<<processoptions>> +<<deathhandler>> +<<nagmanhandler>> +<<smancatchsignals>> +<<fixenv>> +<<inittermio>> +<<strPrefix>> +<<checkspadproc>> +<<cleanupoldsockets>> +<<forkyou>> +<<execcommandenv>> +<<spawnofhell>> +<<startthespadclient>> +<<startthelocalspadclient>> +<<startthenagman>> +<<startthesessionmanager>> +<<startthehypertex>> +<<startthegraphics>> +<<forkAxiom>> +<<starttheAxiom>> +<<cleanupsockets>> +<<readfromspadio>> +<<readfrommanager>> +<<managespadio>> +<<initspadprocesslist>> +<<printspadprocesslist>> +<<findchild>> +<<killallchildren>> +<<cleanupterminal>> +<<monitorchildren>> +<<main>> + +@ +\section{License} +<<license>>= +/* +Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of The Numerical ALgorithms Group Ltd. nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +@ +<<*>>= +<<license>> +<<sman>> +@ +\eject +\begin{thebibliography}{99} +\bibitem{1} nothing +\end{thebibliography} +\end{document} diff --git a/src/sman/spadclient.c b/src/sman/spadclient.c new file mode 100644 index 00000000..a41fee2a --- /dev/null +++ b/src/sman/spadclient.c @@ -0,0 +1,66 @@ +/* +Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of The Numerical ALgorithms Group Ltd. nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#define _SPADCLIENT_C + +#include <stdio.h> +#include <signal.h> + +#include "axiom-c-macros.h" +#include "com.h" +#include "bsdsignal.h" + +#include "bsdsignal.H1" +#include "sockio-c.H1" +#include "spadclient.H1" + +Sock *sock; + +static void +inter_handler(int sig) +{ + send_signal(sock, SIGUSR2); + fflush(stderr); +} + + +int +main(void) +{ + sock = connect_to_local_server(SessionServer, InterpWindow, Forever); + bsdSignal(SIGINT, inter_handler,RestartSystemCalls); + remote_stdio(sock); + return(0); +} + |