rsalz@bbn.com (Rich Salz) (05/18/88)
Submitted-by: libes@cme-durer.ARPA (Don Libes) Posting-number: Volume 14, Issue 94 Archive-name: sharedmem/part01 This system emulates a shared memory system for 4.2BSD. A common memory server handles requests to access shared variables. Because communication uses TCP/IP, processes may be distributed across machines. The system is all user level code and requires no kernel modifications. This implementation provides interfaces for C and Franz Lisp. It is known to work on Sun UNIX releases from 1.0 to 3.4. The system is documented by the files in the doc directory. doc/usenix contains a paper that was presented at the Summer 1985 Usenix Conference. The system has changed somewhat since then. #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 4)." PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1424 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XThe NBS Common Memory System (CMS) XSept 25, 1987 X XThis system emulates a shared memory system for 4.2BSD. A common Xmemory server handles requests to access shared variables. Because Xcommunication uses TCP/IP, processes may be distributed across Xmachines. X XThe system is all user level code and requires no kernel Xmodifications. This implementation provides interfaces for C and XFranz Lisp. It is known to work on Sun UNIX releases from 1.0 to X3.4. X XThe system is documented by the files in the doc directory. Xdoc/usenix contains a paper that was presented at the Summer 1985 XUsenix Conference. The system has changed somewhat since then. X XInstallation instructions X XThis package depends upon a tiny communications library called Xstreamlib which must be installed first. X X cd stream X cat README X Xand follow the directions in there. X XOnce you have installed streamlib, change to the common memory Xsource directory and run make. X X cd ../src X make install X XIf you would like to try out some of the examples, type: X X make examples X XThe examples are numbered as sets. I.e. client1 runs with server1. XThe most interesting is server1y, server1z, client1a and client1b. XRun these in 4 different windows. They are documented by their Xsource and serve as coding examples. X XDon Libes XNational Bureau of Standards XMetrology Building, Room A-127 XGaithersburg, MD 20899 X(301) 975-3535 X Xlibes@cme-durer.arpa Xuunet!cme-durer!libes X X END_OF_FILE if test 1424 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'cms.3' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'cms.3'\" else echo shar: Extracting \"'cms.3'\" \(449 characters\) sed "s/^X//" >'cms.3' <<'END_OF_FILE' X.TH CMS 3NBS "11 January 1988" X.SH NAME Xshared memory system emulator X.SH DESCRIPTION X.PP XThis system emulates a shared memory system. A common memory Xserver handles requests to access shared variables. Because Xcommunication uses TCP/IP, processes may be distributed across Xmachines. X.PP XFor further information read the documents in the doc directory Xthat comes with the common memory source. There are several Xexamples in the source directory. END_OF_FILE if test 449 -ne `wc -c <'cms.3'`; then echo shar: \"'cms.3'\" unpacked with wrong size! fi # end of 'cms.3' fi if test ! -d 'doc' ; then echo shar: Creating directory \"'doc'\" mkdir 'doc' fi if test ! -d 'doc/usenix' ; then echo shar: Creating directory \"'doc/usenix'\" mkdir 'doc/usenix' fi if test ! -d 'src' ; then echo shar: Creating directory \"'src'\" mkdir 'src' fi if test -f 'src/README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/README'\" else echo shar: Extracting \"'src/README'\" \(247 characters\) sed "s/^X//" >'src/README' <<'END_OF_FILE' XAm in the process of implementing a way to get the names of the open cm Xvariables from the cmm. Idea is to reserve a variable, say, cm_variable_names Xwhich is written by the cmm whenever a new variable is declared (or the last Xlink is deleted). X END_OF_FILE if test 247 -ne `wc -c <'src/README'`; then echo shar: \"'src/README'\" unpacked with wrong size! fi # end of 'src/README' fi if test -f 'src/client1a.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/client1a.c'\" else echo shar: Extracting \"'src/client1a.c'\" \(795 characters\) sed "s/^X//" >'src/client1a.c' <<'END_OF_FILE' X/* client1a.c XThis process, a, writes a string to variable a_var. XIt then checks variable b_var for a new value, and if it is, prints it. XIt then sleeps for 3 seconds. X*/ X#include "cm.h" X X#define BUFFER_LENGTH 1000 Xchar a_data[BUFFER_LENGTH]; X Xcm_value a_val = {a_data,BUFFER_LENGTH,0,0}, b_val = {0,0,0,1}; X Xmain() X{ X cm_variable *a_var, *b_var; X int seqno = 0; X X if (0> cm_init("a",0,0)) exit(-1); X X if (!(a_var = cm_declare("a_var",CM_ROLE_NONXWRITER))) X exit(-1); X if (!(b_var = cm_declare("b_var",CM_ROLE_READER|CM_ROLE_WAKEUP))) X exit(-1); X X for (;;) { X sprintf(a_data,"Message from a. seq #%d",seqno++); X a_val.size = strlen(a_data) + 1; X cm_set_value(a_var,&a_val); X cm_sync(CM_NO_WAIT); X if (cm_get_new_value(b_var,&b_val)) X printf("b_var: %s\n",b_val.data); X sleep(3); X } X} END_OF_FILE if test 795 -ne `wc -c <'src/client1a.c'`; then echo shar: \"'src/client1a.c'\" unpacked with wrong size! fi # end of 'src/client1a.c' fi if test -f 'src/client1b.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/client1b.c'\" else echo shar: Extracting \"'src/client1b.c'\" \(807 characters\) sed "s/^X//" >'src/client1b.c' <<'END_OF_FILE' X/* XThis process, b, writes a string to variable b_var. XIt then checks variable a_var for a new value, and if it is, prints it. XIt then sleeps for 5 seconds. X*/ X#include <sys/time.h> X#include "cm.h" X X#define BUFFER_LENGTH 1000 Xchar b_data[BUFFER_LENGTH]; X Xcm_value a_val = {0,0,0,1}, b_val = {b_data,BUFFER_LENGTH,0,0}; X Xmain() X{ X cm_variable *a_var, *b_var; X int seqno = 0; X X if (0> cm_init("b",0,0)) exit(-1); X X if (!(a_var = cm_declare("a_var",CM_ROLE_READER|CM_ROLE_WAKEUP))) X exit(-1); X if (!(b_var = cm_declare("b_var",CM_ROLE_NONXWRITER))) X exit(-1); X X for (;;) { X sprintf(b_data,"Message from b. seq #%d",seqno++); X b_val.size = strlen(b_data) + 1; X cm_set_value(b_var,&b_val); X cm_sync(CM_NO_WAIT); X if (cm_get_new_value(a_var,&a_val)) X printf("a_var: %s\n",a_val.data); X sleep(5); X } X} X END_OF_FILE if test 807 -ne `wc -c <'src/client1b.c'`; then echo shar: \"'src/client1b.c'\" unpacked with wrong size! fi # end of 'src/client1b.c' fi if test -f 'src/client2.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/client2.c'\" else echo shar: Extracting \"'src/client2.c'\" \(1056 characters\) sed "s/^X//" >'src/client2.c' <<'END_OF_FILE' X/* client2.c X this client writes the following to common memory: Xs_var: a line read from stdin Xi_var: the length of s_var Xd_var: a random double variable X*/ X#include <sys/time.h> X#include "cm.h" X Xcm_variable *i_var, *d_var, *s_var; Xcm_value i_val, d_val, s_val; Xdouble d_val_data = 3.14159; X Xchar s_val_data[1000]; Xint i_val_data; X Xmain(argc,argv) Xint argc; Xchar **argv; X{ X if (argc>1) printf("going to host %s for cmm\n",argv[1]); X if (0 > cm_init("don",(argc>1?argv[1]:(char *)0),0)) exit(-1); X X s_var = cm_declare("s_var",CM_ROLE_NONXWRITER); X i_var = cm_declare("i_var",CM_ROLE_NONXWRITER); X d_var = cm_declare("d_var",CM_ROLE_NONXWRITER); X X d_val.data = (char *)&d_val_data; X d_val.size = sizeof(d_val_data); X s_val.data = s_val_data; X i_val.data = (char *)&i_val_data; X X while (TRUE) { X cm_set_value(d_var,&d_val); X X printf("enter string for s_val: "); X gets(s_val_data); X s_val.size = strlen(s_val_data); X cm_set_value(s_var,s_val); X X i_val_data = strlen(s_val_data); X cm_set_value(i_var,&i_val); X X if (0 > cm_sync(CM_NO_WAIT)) return; X } X} END_OF_FILE if test 1056 -ne `wc -c <'src/client2.c'`; then echo shar: \"'src/client2.c'\" unpacked with wrong size! fi # end of 'src/client2.c' fi if test -f 'src/client8.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/client8.c'\" else echo shar: Extracting \"'src/client8.c'\" \(382 characters\) sed "s/^X//" >'src/client8.c' <<'END_OF_FILE' X/* client8.c - constantly write a variable to common memory (see server8.c) */ X X#include <sys/time.h> X#include "cm.h" X Xcm_variable *variable; Xcm_value value = { "foo", 4, 4, 0}; X Xmain() X{ X if (0>cm_init("constant writer",0,0)) exit(-1); X X if (!(variable = cm_declare("variable",CM_ROLE_XWRITER))) exit(-1); X X while (1) { X cm_set_value(variable,&value); X cm_sync(CM_NO_WAIT); X } X} END_OF_FILE if test 382 -ne `wc -c <'src/client8.c'`; then echo shar: \"'src/client8.c'\" unpacked with wrong size! fi # end of 'src/client8.c' fi if test -f 'src/cm.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/cm.h'\" else echo shar: Extracting \"'src/cm.h'\" \(269 characters\) sed "s/^X//" >'src/cm.h' <<'END_OF_FILE' X/* cm.h - include common memory include files */ X X#ifndef _TIME_ X#include <sys/time.h> X#endif X X#include "cm_constants.h" X#include "cm_var.h" X#include "cm_sd.h" X#include "cm_interface.h" X#include "cm_slot.h" X#include "cm_msg.h" X#include "cm_sync.h" X#include "cm_time.h" END_OF_FILE if test 269 -ne `wc -c <'src/cm.h'`; then echo shar: \"'src/cm.h'\" unpacked with wrong size! fi # end of 'src/cm.h' fi if test -f 'src/cm.lisp' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/cm.lisp'\" else echo shar: Extracting \"'src/cm.lisp'\" \(1622 characters\) sed "s/^X//" >'src/cm.lisp' <<'END_OF_FILE' X ; load in calls for common memory package X ; Don Libes X X(cfasl '/usr/local/lib/Luser.o '_Lcm_init 'cm_init "function" X "/usr/local/lib/libcm.a /usr/local/lib/libstream.a") X(getaddress X '_Lcm_declare 'cm_declare "integer-function" X '_Lcm_undeclare 'cm_undeclare "subroutine" X '_Lcm_sync 'cm_sync "integer-function" X '_Lcm_set_value 'cm_set_value "subroutine" X '_Lcm_get_value 'cm_get_value "subroutine" X '_Lcm_set_new_command_value 'cm_set_new_command_value "integer-function" X '_Lcm_new_command_pending 'cm_new_command_pending "integer-function" X '_Lcm_get_new_command_value 'cm_get_new_command_value "integer-function" X '_Lcm_status_equal 'cm_status_equal "integer-function" X '_Lcm_status_synchronized 'cm_status_synchronized "integer-function" X '_Lcm_set_status_value 'cm_set_status_value "subroutine" X '_Lcm_print_variable 'cm_print_variable "subroutine" X '_Lcm_exit 'cm_exit "subroutine" X) X X; access types, i.e. roles X(setq oldibase ibase) X(setq ibase 8) X(setq CM_ROLE_NULL 000) X(setq CM_ROLE_READER 001) X(setq CM_ROLE_WAKEUP 002) X(setq CM_ROLE_NONXWRITER 004) X(setq CM_ROLE_NONEXCLUSIVE_WRITER 004) X(setq CM_ROLE_EXCLUSIVE_WRITER 014) X(setq CM_ROLE_XWRITER 014) X(setq ibase oldibase) X X(setq CM_WAIT 0) X(setq CM_NO_WAIT 1) X(setq CM_WAIT_FOR_ALL 0) X(setq CM_WAIT_AT_MOST_ONCE 2) X(setq CM_WAIT_READ 4) X X;(setq CM_WAIT 0) X;(setq CM_NO_WAIT 1) X;(setq CM_WAIT_FOR_ALL 2) X;(setq CM_WAIT_AT_MOST_ONCE 3) X X; define common memory value X(c-declare X (struct cm_value X (data * char) X (msize unsigned-short) X (size unsigned-short) X (mallocable char) X ) X) END_OF_FILE if test 1622 -ne `wc -c <'src/cm.lisp'`; then echo shar: \"'src/cm.lisp'\" unpacked with wrong size! fi # end of 'src/cm.lisp' fi if test -f 'src/cm_bytestuff.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/cm_bytestuff.h'\" else echo shar: Extracting \"'src/cm_bytestuff.h'\" \(372 characters\) sed "s/^X//" >'src/cm_bytestuff.h' <<'END_OF_FILE' X/* cm_bytestuff.h - byte stuffing aids */ X X/* #byteadd is used to add offsets to structures */ X/*#define byteadd(a,b) (((int)a) + ((int)b) + (((int)a) + (int)b) % 2)*/ X#define byteadd(a,b) (align(((int)(a)) + ((int)(b)))) X X/* align converts rounds up addresses if they are odd */ X/* if this is not done, longword stores fail on the 68000 */ X#define align(x) ((x) + (x)%2) END_OF_FILE if test 372 -ne `wc -c <'src/cm_bytestuff.h'`; then echo shar: \"'src/cm_bytestuff.h'\" unpacked with wrong size! fi # end of 'src/cm_bytestuff.h' fi if test -f 'src/cm_constants.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/cm_constants.h'\" else echo shar: Extracting \"'src/cm_constants.h'\" \(445 characters\) sed "s/^X//" >'src/cm_constants.h' <<'END_OF_FILE' X#define CM_PORT 1525 X X/* maximums */ X#define CM_MSGSIZE 100000/* max length of all variables X sent to server at one time */ X#define CM_SLOTSIZE 20000 /* max single variable length */ X#define CM_PROCESSNAMELENGTH 20 X#define CM_VARIABLENAMELENGTH 20 X#define CM_MAXVARIABLENAMELENGTH 20 X#define CM_MAXPROCESSNAMELENGTH 20 X#define CM_MAXUSERVARIABLES 100 X X#define E_CMM_DIED -1 X#define E_CM_INIT_FAILED -2 X#define E_CM_WRONG_VERSION -100 END_OF_FILE if test 445 -ne `wc -c <'src/cm_constants.h'`; then echo shar: \"'src/cm_constants.h'\" unpacked with wrong size! fi # end of 'src/cm_constants.h' fi if test -f 'src/cm_man.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/cm_man.h'\" else echo shar: Extracting \"'src/cm_man.h'\" \(1966 characters\) sed "s/^X//" >'src/cm_man.h' <<'END_OF_FILE' X/* X XCommon memory is local to the CMM process. It is composed of: X XAn array of variables. Each variable is a structure with elements such as Xa name, type, value, etc. X XVariable values can be stored in the variable structure if they are small X(such as an int) or in a piece of malloc'd memory if they are large (such Xas a string). X XAn array of process descriptors. Each process descriptor is a structure. XThe most important element of this structure is the wakeup field. If it is Xset, the process should be informed of new variable values. X*/ X X#define CM_MANAGER_NAME "cm manager" X#define CM_MAXVARIABLES 50 X#define CM_MAXPROCESSES 20 X X#define is_new(proc,var) (var->role[proc].new) X#define is_reader(proc,var) (var->role[proc].reader) X#define is_wakeup(proc,var) (var->role[proc].wakeup) X#define is_writer(proc,var) (var->role[proc].writer) X#define is_nonxwriter(proc,var) (var->role[proc].writer && \ X var->xwriter != proc) X#define is_xwriter(proc,var) (var->xwriter == proc) X X#define CM_NULL_PROCESS -1 X X/* process descriptors */ X/* this table is indexed by corresponding file descriptors (or sockets) */ Xstruct process { X char name[CM_PROCESSNAMELENGTH]; X int inuse; X int wakeup; /* per process wakeup */ X}; X X/* this is how variables are stored internally to the cmm */ Xstruct variable { X char name[CM_VARIABLENAMELENGTH]; X struct cm_value data; /* data (and size, if necessary) */ X unsigned long count; /* nth definition of this var */ X struct timeval timestamp; /* when last written */ X int command_association; X int xwriter; /* name of exclusive writer */ X int writers; /* number of (any type of) writers */ X int readers; /* number of readers */ X struct { X unsigned reader : 1; /* reader */ X unsigned writer : 1; /* writer */ X unsigned wakeup : 1; /* a-wake me */ X unsigned new : 1; /* changed but not read */ X } role[CM_MAXPROCESSES]; X}; X X/* internal errors specific to CMM */ X#define E_GET_VARIABLE_NO_SPACE -1 END_OF_FILE if test 1966 -ne `wc -c <'src/cm_man.h'`; then echo shar: \"'src/cm_man.h'\" unpacked with wrong size! fi # end of 'src/cm_man.h' fi if test -f 'src/cm_msg.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/cm_msg.h'\" else echo shar: Extracting \"'src/cm_msg.h'\" \(938 characters\) sed "s/^X//" >'src/cm_msg.h' <<'END_OF_FILE' X/* X XThis file contains definitions relating to message passing between Xthe CM manager and user. X XFollowing is the structure of a message. Unfortunately, this is illegal Xbecause "number" is variable as well as the sizeof(slot). This structure Xwill be built dynamically when necessary and discarded after the message Xhas been used (read or written). In order to make it legal, we will leave Xcomment out the "slot" field and read/write that by hand. This hack will Xbe used throughout the message code. Yuck. X X*/ X Xstruct msg { X int version; /* version of cmm system */ X int size; /* size of msg structure itself */ X int slots; /* number of slots */ X char name[CM_PROCESSNAMELENGTH]; X char read_wait; /* TRUE, if sender waiting for an acknowledgement */ X struct slot data[1]; /* really want [0] */ X} ; X X/* X XEach message is composed of a header. The header includes the process name, Xnumber of slots, and the slots themselves. X X*/ X X END_OF_FILE if test 938 -ne `wc -c <'src/cm_msg.h'`; then echo shar: \"'src/cm_msg.h'\" unpacked with wrong size! fi # end of 'src/cm_msg.h' fi if test -f 'src/cm_sd.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/cm_sd.h'\" else echo shar: Extracting \"'src/cm_sd.h'\" \(384 characters\) sed "s/^X//" >'src/cm_sd.h' <<'END_OF_FILE' X/* cm_sd.h - sized-data structures */ X X/* there is no reason why the items typed as shorts cannot be longer */ X Xtypedef struct cm_value { X char *data; X unsigned short msize; /* max size of data */ X unsigned short size; /* size of data used */ X char mallocable; /* TRUE, if we can free and malloc data */ X} cm_value; X Xstruct cm_flattened_data { X unsigned short size; X char data[1]; X}; END_OF_FILE if test 384 -ne `wc -c <'src/cm_sd.h'`; then echo shar: \"'src/cm_sd.h'\" unpacked with wrong size! fi # end of 'src/cm_sd.h' fi if test -f 'src/cm_sync.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/cm_sync.h'\" else echo shar: Extracting \"'src/cm_sync.h'\" \(327 characters\) sed "s/^X//" >'src/cm_sync.h' <<'END_OF_FILE' X/* cm_sync.h */ X X/* OR together one from first set to one from second set */ X/* defaults are CM_WAIT|CM_WAIT_FOR_ALL */ X X/* first set of options */ X#define CM_WAIT 0 X#define CM_NO_WAIT 1 X/* second set of options */ X#define CM_WAIT_FOR_ALL 0 X#define CM_WAIT_AT_MOST_ONCE 2 X/* third set of options */ X#define CM_WAIT_READ 4 END_OF_FILE if test 327 -ne `wc -c <'src/cm_sync.h'`; then echo shar: \"'src/cm_sync.h'\" unpacked with wrong size! fi # end of 'src/cm_sync.h' fi if test -f 'src/cm_time.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/cm_time.c'\" else echo shar: Extracting \"'src/cm_time.c'\" \(667 characters\) sed "s/^X//" >'src/cm_time.c' <<'END_OF_FILE' X/* these are utilities for dealing with timeouts */ X X#include <stdio.h> X#include <sys/types.h> X#include <sys/time.h> X#include "cm_time.h" X Xstruct timeval cm_period_zero, cm_period_infinite; X X/* set up some useful constants */ Xcm_time_init() X{ X cm_time_zero(&cm_period_zero); X cm_period_infinite.tv_sec = (u_long)1000000; X cm_period_infinite.tv_usec = (long)0; X} X Xcm_time_zero(p) Xstruct timeval *p; X{ X p->tv_sec = (u_long)0; X p->tv_usec = (long)0; X} X Xcm_time_set(p,s,u) Xstruct timeval *p; Xint s; Xint u; X{ X p->tv_sec = (u_long)s; X p->tv_usec = (long)u; X} X Xcm_time_copy(from,to) Xstruct timeval *from, *to; X{ X safebcopy((char *)from,(char *)to,sizeof(struct timeval)); X} END_OF_FILE if test 667 -ne `wc -c <'src/cm_time.c'`; then echo shar: \"'src/cm_time.c'\" unpacked with wrong size! fi # end of 'src/cm_time.c' fi if test -f 'src/cm_time.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/cm_time.h'\" else echo shar: Extracting \"'src/cm_time.h'\" \(116 characters\) sed "s/^X//" >'src/cm_time.h' <<'END_OF_FILE' Xextern struct timeval cm_period_zero, cm_period_infinite; X X#define time_now(x) gettimeofday(x,(struct timezone *)0) END_OF_FILE if test 116 -ne `wc -c <'src/cm_time.h'`; then echo shar: \"'src/cm_time.h'\" unpacked with wrong size! fi # end of 'src/cm_time.h' fi if test -f 'src/cm_util.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/cm_util.c'\" else echo shar: Extracting \"'src/cm_util.c'\" \(2023 characters\) sed "s/^X//" >'src/cm_util.c' <<'END_OF_FILE' X/* utilities */ X X#include <stdio.h> X#include <strings.h> X#include <ctype.h> X#include <varargs.h> X X/* uh-oh, looks like Lisp has a bcopy too! */ X/* and it doesn't do the same thing as the C bcopy! */ X/* Now who wants to know how long this took me to find? */ Xstatic bcopy(s1,s2,length) Xchar *s1, *s2; Xint length; X{ X while (0 < length--) *s2++ = *s1++; X} X Xvoid Xsafebcopy(b1,b2,length) Xchar *b1, *b2; Xint length; X{ X eprintf(9,"safebcopy(%x,%x,%d)\n",b1,b2,length); X if (!b1) { X printf("error: bcopy dest is null ptr\n"); X abort(); X } else if (!b2) { X printf("error: bcopy src is null ptr\n"); X abort(); X } else bcopy(b1,b2,length); X} X X/* dump first 20 bytes starting at s in hex */ Xhex20(s) Xchar *s; X{ X int i; X for (i=0;i<20;i++) printf("%2x",0xff & s[i]); X putchar('\n'); X} X X/* dump length bytes worth of s in ascii */ Xascii_dump(s,length) Xchar *s; Xint length; X{ X int i; X for (i=0;i<length;i++) { X if (isascii(s[i]) && isprint(s[i])) { X printf(" %c",s[i]); X } else { X printf(" %02x",0xff & s[i]); X } X } X putchar('/n'); X} X Xint cm_debug_level; /* controls how many debugging statements are X /* printed. 0 means none, higher numbers mean X /* more. */ X/* levels are: X0 nothing X1 X2 msgs send/received X3 msgs init, aborted X4 X5 slots composed, decomposed X6 slots broken out X7 X8 X9 bcopy, strcpy, malloc X*/ Xset_cm_debug_level(level) Xint level; X{ X cm_debug_level = level; X eprintf(1,"cm debug level is %d\n",cm_debug_level); X} X X X/* Debugging function, use like printf, but the global var debug_level */ X/* controls how much is printed */ X#if 0 X/* Yes, I know its gross */ X/*VARARGS2*/ Xeprintf(level,fmt,v1,v2,v3,v4,v5,v6,v7,v8,v9) Xint level; Xchar *fmt; Xint v1, v2, v3, v4, v5, v6, v7, v8, v9; X{ X if (cm_debug_level >= level) printf(fmt,v1,v2,v3,v4,v5,v6,v7,v8,v9); X} X#endif X X/*VARARGS2*/ Xeprintf(level,fmt,va_alist) Xint level; Xchar *fmt; Xva_dcl X{ X va_list pvar; X X va_start(pvar); X /* & may be incorrect in following statement */ X if (cm_debug_level >= level) _doprnt(fmt,pvar,stderr); X va_end(pvar); X} END_OF_FILE if test 2023 -ne `wc -c <'src/cm_util.c'`; then echo shar: \"'src/cm_util.c'\" unpacked with wrong size! fi # end of 'src/cm_util.c' fi if test -f 'src/cm_var.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/cm_var.h'\" else echo shar: Extracting \"'src/cm_var.h'\" \(255 characters\) sed "s/^X//" >'src/cm_var.h' <<'END_OF_FILE' X/* access types, i.e. roles */ X#define CM_ROLE_NULL 000 X#define CM_ROLE_READER 001 X#define CM_ROLE_WAKEUP 002 X#define CM_ROLE_NONXWRITER 004 X#define CM_ROLE_NONEXCLUSIVE_WRITER 004 X#define CM_ROLE_EXCLUSIVE_WRITER 010 X#define CM_ROLE_XWRITER 010 END_OF_FILE if test 255 -ne `wc -c <'src/cm_var.h'`; then echo shar: \"'src/cm_var.h'\" unpacked with wrong size! fi # end of 'src/cm_var.h' fi if test ! -d 'src/franz' ; then echo shar: Creating directory \"'src/franz'\" mkdir 'src/franz' fi if test -f 'src/franz/dfuncs.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/franz/dfuncs.h'\" else echo shar: Extracting \"'src/franz/dfuncs.h'\" \(1350 characters\) sed "s/^X//" >'src/franz/dfuncs.h' <<'END_OF_FILE' X/* -[Mon Dec 3 16:37:08 1984 by layer]- X * dfuncs.h $Locker: $ X * external function declaration X * X * $Header: dfuncs.h,v 40.6 85/03/12 12:54:37 layer Exp $ X * X * (c) copyright 1982, Regents of the University of California X * Enhancements (c) copyright 1984, Franz Inc., Oakland California X */ X Xchar *brk(); Xchar *pinewstr(); Xchar *inewstr(); Xchar *newstr(); Xchar *sbrk(); Xchar *xsbrk(); Xchar *ysbrk(); Xint csizeof(); Xlispval Iget(); Xlispval Imakeht(); Xlispval Imkrtab(); Xlispval Iputprop(); Xlispval Istsrch(); Xlispval Lfuncal(); Xlispval Lnegp(); Xlispval Lread(); Xlispval Lsub(); Xlispval copval(); Xlispval csegment(); Xlispval error(); Xlispval errorh(); Xlispval errorh1(); Xlispval errorh2(); Xlispval eval(); Xlispval gc(); Xlispval getatom(); Xlispval inewatom(); Xlispval inewint(); Xlispval inewval(); Xlispval matom(); Xlispval mfun(); Xlispval mstr(); Xlispval newarray(); Xlispval newdot(); Xlispval newdoub(); Xlispval newfunct(); Xlispval newint(); Xlispval newsdot(); Xlispval newval(); Xlispval newhunk(); Xlispval pnewdot(); Xlispval pnewdb(); Xlispval pnewhunk(); Xlispval pnewint(); Xlispval pnewsdot(); Xlispval pnewval(); Xlispval popnames(); Xlispval r(); Xlispval ratomr(); Xlispval readr(); Xlispval readrx(); Xlispval readry(); Xlispval typefrob(); Xlispval typred(); Xlispval unprot(); Xlispval verify(); Xstruct atom *makeatom(); Xstruct atom *newatom(); END_OF_FILE if test 1350 -ne `wc -c <'src/franz/dfuncs.h'`; then echo shar: \"'src/franz/dfuncs.h'\" unpacked with wrong size! fi # end of 'src/franz/dfuncs.h' fi if test -f 'src/franz/lconf.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/franz/lconf.h'\" else echo shar: Extracting \"'src/franz/lconf.h'\" \(16 characters\) sed "s/^X//" >'src/franz/lconf.h' <<'END_OF_FILE' X#define sun_4_2 END_OF_FILE if test 16 -ne `wc -c <'src/franz/lconf.h'`; then echo shar: \"'src/franz/lconf.h'\" unpacked with wrong size! fi # end of 'src/franz/lconf.h' fi if test -f 'src/franz/ltypes.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/franz/ltypes.h'\" else echo shar: Extracting \"'src/franz/ltypes.h'\" \(1031 characters\) sed "s/^X//" >'src/franz/ltypes.h' <<'END_OF_FILE' X/* -[Wed May 15 10:14:01 1985 by layer]- X * ltypes.h $Locker: $ X * lisp data type defs X * X * $Header: ltypes.h,v 40.6 85/05/16 03:58:00 smh Exp $ X * X * (c) copyright 1982, Regents of the University of California X * Enhancements (c) copyright 1984, Franz Inc., Oakland California X */ X X/* type flags */ X X#define UNBO -1 X#define STRNG 0 X#define ATOM 1 X#define INT 2 X#define DTPR 3 X#define DOUB 4 X#define BCD 5 X#define PORT 6 X#define ARRAY 7 X#define OTHER 8 X#define SDOT 9 X#define VALUE 10 X X#define HUNK2 11 /* The hunks */ X#define HUNK4 12 X#define HUNK8 13 X#define HUNK16 14 X#define HUNK32 15 X#define HUNK64 16 X#define HUNK128 17 X X#define VECTOR 18 X#define VECTORI 19 X X#define NUMSPACES (VECTORI + 1) X X#define HUNKP(a1) ((TYPE(a1) >= HUNK2) & (TYPE(a1) <= HUNK128)) X X#define HASHTP(p) ((p)->v.vector[VPropOff] == hasht_atom) X#define PACKAGEP(p) ((p)->v.vector[VPropOff] == pkg_atom) X#define INSTANCEP(p) ((TYPE((p)->v.vector[VPropOff]) == VECTOR) && \ X ((p)->v.vector[VPropOff]->v.vector[VPROPOFF] == \ X flavor)) X END_OF_FILE if test 1031 -ne `wc -c <'src/franz/ltypes.h'`; then echo shar: \"'src/franz/ltypes.h'\" unpacked with wrong size! fi # end of 'src/franz/ltypes.h' fi if test -f 'src/franz/module.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/franz/module.h'\" else echo shar: Extracting \"'src/franz/module.h'\" \(1662 characters\) sed "s/^X//" >'src/franz/module.h' <<'END_OF_FILE' X/* -[Sat Jun 2 08:09:36 1984 by jkf]- X * module.h $Locker: $ X * X * module interface includes X * X * $Header: module.h,v 40.2 84/11/13 14:23:46 schlafly Exp $ X * X * (c) copyright 1984, Franz Inc., Oakland California X */ X X/* X * All C coded modules will contain a VERSION X * header in which the rcs header is stored X */ X X#ifndef lint X#define VERSION(s) static char *rcsid = s X#else X#define VERSION(s) X#endif X X X/* X * All variables are either private in the module or else are X * shared among 2 or more files. X * Private variables are declared Private inside the file. X * Non-private variables are either declared Public in a .h file which X * all files that wish to reference that variable must include, X * or are declared Export in a C (non-header) file. C files wishing X * to reference those variables declare the variable Import. X * X * X * Private corresponds to 'static' in C, although it usually isn't a good X * idea to declare variables or functions to be static if you want to debug X * the code with something like adb. X * Export corresponds to '' (nothing), and Import to 'extern'. X * Public corresponds to 'extern' in C, although there must be one file X * in which the 'extern' isn't declared. To order to strip the extern, X * the macro DefineData should be set before including files. X * X * Public should be used instead of Import and Export since it assures X * that every module gets the same declaration. However it does require X * a .h file, and this may be too much effort for one or two variables. X * X */ X X#define Private static X#define Export X#define Import extern X X#ifdef DefineData X# define Public X#else X# define Public extern X#endif END_OF_FILE if test 1662 -ne `wc -c <'src/franz/module.h'`; then echo shar: \"'src/franz/module.h'\" unpacked with wrong size! fi # end of 'src/franz/module.h' fi if test -f 'src/franz/public.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/franz/public.h'\" else echo shar: Extracting \"'src/franz/public.h'\" \(1909 characters\) sed "s/^X//" >'src/franz/public.h' <<'END_OF_FILE' X/* -[Tue May 21 17:05:40 1985 by layer]- X * public.h $Locker: $ X * X * definition for Public data objects which all files are permitted X * to look at. [These are the very public data objects] X * X * $Header: public.h,v 40.5 85/05/21 17:24:04 layer Exp $ X * X * X * (c) copyright 1984, Franz Inc., Oakland California X */ X X#ifdef apollo Xextern X#else XPublic X#endif Xstruct nament *bnp; /* first free bindstack entry */ XPublic struct nament *bnplim, /* limit of bindstack */ X *orgbnp; /* base of the bindstack */ X X X#ifdef NPINREG XImport X#else X#ifdef apollo Xextern X#else XPublic X#endif apollo X#endif NPINREG X struct argent *lbot, /* base of arguments to function */ X *np; /* first free namestack entry */ X XPublic struct argent *nplim, /* one above limit of namestack */ X *orgnp; /* first slot in the namestack */ X X#ifdef apollo Xextern X#else XPublic X#endif apollo X word retval; /* used by each error/prog call */ X /* retval could be an int */ X#ifdef apollo Xextern X#else XPublic X#endif apollo Xlispval lispretval; /* used by non-local go */ X XPublic lispval datalim; /* limit of valid data area */ X XPublic lispval vtemp; /* used in a few macros as a temp */ XPublic long sigintcnt; /* count of interrupts since processed */ X /* sigintcnt could be an int */ X XImport char typetable[]; /* one byte per page */ X X#ifdef MVR X/* Stuff having to do with Multiple Values */ X#ifdef apollo Xextern X#else XPublic X#endif apollo Xint nmvr; /* # of multiple values being returned less 1 */ XImport int mmvr; /* Max # of multiple values possibly returned*/ X#ifdef apollo Xextern X#else XPublic X#endif apollo Xlispval *mvals; /* pointer to a static storage area for them */ XPublic lispval *mvalsMMVR; /* pointer to end of storage area for them */ X#define clrnmv() (nmvr = 0); X#endif MVR X X#ifdef Savelisp XPublic lispval relvectors; /* for save/restorelisp */ X#endif Savelisp END_OF_FILE if test 1909 -ne `wc -c <'src/franz/public.h'`; then echo shar: \"'src/franz/public.h'\" unpacked with wrong size! fi # end of 'src/franz/public.h' fi if test -f 'src/man_put_slot.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/man_put_slot.c'\" else echo shar: Extracting \"'src/man_put_slot.c'\" \(1541 characters\) sed "s/^X//" >'src/man_put_slot.c' <<'END_OF_FILE' X/* X XThese routines build slots for the cmm. These slots are placed into a Xmsg structure and sent to the user. X X*/ X X#include <stdio.h> X#include <sys/time.h> X#include "cm_constants.h" X#include "cm_sd.h" X#include "cm_slot.h" /* definitions of slot structures */ X#include "cm_bytestuff.h" X Xextern struct msg *omsg; /* this is soooo... messy */ X Xput_slot_read_response(m,name,count,timestamp,cmd,data) Xstruct msg *m; Xchar *name; Xunsigned long count; Xstruct timeval *timestamp; Xint cmd; Xcm_value *data; X{ X struct big_slot s; X unsigned int size; X X init_slot(&s,name,CM_SLOT_READ_RESPONSE); X size = align(sizeof(struct slot_hdr)); X size += align(sizeof(struct slot_read_response_hdr)); X s.subslot.read_response.srr_count = count; X cm_time_copy(timestamp,&s.subslot.read_response.srr_timestamp); X s.subslot.read_response.srr_command_association = cmd; X size += cm_sd_to_flat(data,&s.subslot.read_response.fdata); X finish_slot(m,&s,size); X} X X/* error slots should never be generated by the user since infinite loops */ X/* could result between the user and cmm sending each other back error slots */ Xput_slot_error(m,name,type,string) Xstruct msg *m; Xchar *name; Xint type; Xchar *string; X{ X struct big_slot s; X unsigned int size; X X fprintf(stdout,"slot error in <%s> type %d - %s\n",name,type,string); X X init_slot(&s,name,CM_SLOT_ERROR); X size = align(sizeof(struct slot_hdr)); X size += align(sizeof(struct slot_error_hdr)); X size += strlen(string) + 1; X s.subslot.error.se_type = type; X strcpy(s.subslot.error.msg,string); X finish_slot(m,&s,size); X} END_OF_FILE if test 1541 -ne `wc -c <'src/man_put_slot.c'`; then echo shar: \"'src/man_put_slot.c'\" unpacked with wrong size! fi # end of 'src/man_put_slot.c' fi if test -f 'src/msg.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/msg.c'\" else echo shar: Extracting \"'src/msg.c'\" \(966 characters\) sed "s/^X//" >'src/msg.c' <<'END_OF_FILE' X/* msg.c */ X X#include <sys/time.h> X#include "cm_constants.h" X#include "cm_sd.h" X#include "cm_slot.h" X#include "cm_msg.h" X#include "cm_bytestuff.h" X Xextern int cm_debug_level; X X/* returns NULL if no more slots */ Xstruct slot * Xnextslot(m,s) Xstruct msg *m; Xstruct slot *s; X{ X struct slot *next; X X next = (struct slot *)byteadd(s,s->s_size); X if (next >= (struct slot *)byteadd(m,m->size)) X return((struct slot *)0); X return(next); X} X Xprint_msg(m) Xstruct msg *m; X{ X struct slot *s; X X eprintf(3,"msg header:"); X eprintf(3," size = %d",m->size); X eprintf(3," slots = %d",m->slots); X eprintf(3," name = %s",m->name); X eprintf(3," read_wait = %d\n",m->read_wait); X for (s=m->data;s;s=nextslot(m,s)) { X eprintf(5,"slot: name = %s",s->s_name); X eprintf(5," &slot = %x",s); X eprintf(5," size = %d\n",s->s_size); X if (s->s_size == 0) { X eprintf(5,"0 length slot encountered in print_msg\n"); X break; X } X } X if (cm_debug_level >= 10) ascii_dump((char *)m,m->size); X} X END_OF_FILE if test 966 -ne `wc -c <'src/msg.c'`; then echo shar: \"'src/msg.c'\" unpacked with wrong size! fi # end of 'src/msg.c' fi if test -f 'src/name.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/name.c'\" else echo shar: Extracting \"'src/name.c'\" \(216 characters\) sed "s/^X//" >'src/name.c' <<'END_OF_FILE' X/* set_cm_process_name.c */ X X#include <stdio.h> X#include "cm_constants.h" X Xchar cm_process_name[CM_PROCESSNAMELENGTH]; X Xset_cm_process_name(name) Xchar *name; X{ X strncpy(cm_process_name,name,CM_PROCESSNAMELENGTH); X} X END_OF_FILE if test 216 -ne `wc -c <'src/name.c'`; then echo shar: \"'src/name.c'\" unpacked with wrong size! fi # end of 'src/name.c' fi if test -f 'src/put_slot.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/put_slot.c'\" else echo shar: Extracting \"'src/put_slot.c'\" \(2010 characters\) sed "s/^X//" >'src/put_slot.c' <<'END_OF_FILE' X/* X XThese are some utility routines for building slots. These slots Xare placed in a msg structure and sent from the user to the cmm or vice-versa. X X*/ X X#include <stdio.h> X#include <sys/time.h> X#include <strings.h> X#include "cm_constants.h" X#include "cm_sd.h" X#include "cm_slot.h" /* definitions of slot structures */ X#include "cm_msg.h" /* definitions of msg structures */ X#include "cm_bytestuff.h" X X#define TRUE 1 X#define FALSE 0 X Xextern char cm_process_name[]; X Xint /* returns # of bytes written into msg structure */ Xfinish_slot(m,slot,slotsize) Xstruct msg *m; Xstruct slot *slot; Xunsigned int slotsize; X{ X if (m->size + slotsize > CM_MSGSIZE) { X fprintf(stderr,"too much data for msg!!\n"); X fprintf(stderr,"output msg size = %d slotsize = %d CM_MSGSIZE = %d\n", X m->size,slotsize,CM_MSGSIZE); X return(0); X } X /* copy slot into msg after previous slot */ X slot->s_size = slotsize; /* this is not aligned, right? */ X eprintf(10,"finish_slot: bcopying slot (size = %d) into msg\n", X slot->s_size); X safebcopy((char *)slot,(char *)byteadd(m,m->size),slotsize); X eprintf(10,"finish_slot: after bcopy, message slot size = %d\n", X ((struct slot *)byteadd(m,m->size))->s_size); X m->slots++; X m->size += align(slotsize); X return(align(slotsize)); X} X Xinit_msg(m) Xstruct msg *m; X{ X m->version = CMM_VERSION; X m->slots = 0; X m->read_wait = FALSE; X strcpy(m->name,cm_process_name); X m->size = sizeof(struct msg) - sizeof(struct slot); X} X X/* Xinit_slot does the following: X sets the slot name and type X*/ Xinit_slot(s,name,type) Xstruct slot *s; Xchar *name; Xint type; X{ X s->s_type = type; X strcpy(s->s_name,name); X} X Xchar * Xcm_slot_type(t) Xint t; X{ X switch (t) { X case CM_SLOT_NULL: return("null slot type"); X case CM_SLOT_DECLARE: return("declare"); X case CM_SLOT_WRITE: return("write"); X case CM_SLOT_READ: return("read"); X case CM_SLOT_READ_RESPONSE: return("read response"); X case CM_SLOT_ERROR: return("error"); X case CM_SLOT_UNDECLARE: return("undeclare"); X default: return("unknown slot type"); X } X} END_OF_FILE if test 2010 -ne `wc -c <'src/put_slot.c'`; then echo shar: \"'src/put_slot.c'\" unpacked with wrong size! fi # end of 'src/put_slot.c' fi if test -f 'src/server1y.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/server1y.c'\" else echo shar: Extracting \"'src/server1y.c'\" \(652 characters\) sed "s/^X//" >'src/server1y.c' <<'END_OF_FILE' X/* server1y.c X XThis process prints the latest values of variables a_var and b_var when Xthe user presses return. X X*/ X#include <sys/time.h> X#include "cm.h" X Xcm_value a_val = {0,0,0,1}, b_val = {0,0,0,1}; X Xmain() X{ X cm_variable *a_var, *b_var; X X if (0>cm_init("press return",0,0)) exit(-1); X X if (!(a_var = cm_declare("a_var",CM_ROLE_READER))) X exit(-1); X if (!(b_var = cm_declare("b_var",CM_ROLE_READER))) X exit(-1); X X printf("press return for latest values\n"); X for (;;) { X getchar(); X cm_sync(CM_WAIT_READ); X cm_get_value(a_var,&a_val); X printf("a_var: %s\n",a_val.data); X cm_get_value(b_var,&b_val); X printf("b_var: %s\n",b_val.data); X } X} END_OF_FILE if test 652 -ne `wc -c <'src/server1y.c'`; then echo shar: \"'src/server1y.c'\" unpacked with wrong size! fi # end of 'src/server1y.c' fi if test -f 'src/server1z.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/server1z.c'\" else echo shar: Extracting \"'src/server1z.c'\" \(610 characters\) sed "s/^X//" >'src/server1z.c' <<'END_OF_FILE' X/* server1.c XThis process, s, prints the latest values of variables a_var and b_var X*/ X#include <sys/time.h> X#include "cm.h" X Xcm_value a_val = {0,0,0,1}, b_val = {0,0,0,1}; X Xmain() X{ X cm_variable *a_var, *b_var; X X if (0>cm_init("s",0,0)) exit(-1); X X if (!(a_var = cm_declare("a_var",CM_ROLE_READER|CM_ROLE_WAKEUP))) X exit(-1); X if (!(b_var = cm_declare("b_var",CM_ROLE_READER|CM_ROLE_WAKEUP))) X exit(-1); X X for (;;) { X cm_sync(CM_WAIT_AT_MOST_ONCE); X if (cm_get_new_value(a_var,&a_val)) X printf("a_var: %s\n",a_val.data); X if (cm_get_new_value(b_var,&b_val)) X printf("b_var: %s\n",b_val.data); X } X} END_OF_FILE if test 610 -ne `wc -c <'src/server1z.c'`; then echo shar: \"'src/server1z.c'\" unpacked with wrong size! fi # end of 'src/server1z.c' fi if test -f 'src/server2.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/server2.c'\" else echo shar: Extracting \"'src/server2.c'\" \(823 characters\) sed "s/^X//" >'src/server2.c' <<'END_OF_FILE' X/* all this server does is print out whatever its given */ X X/* Note, this has not been converted over to use cmm v7!!! */ X X#include <sys/time.h> X#include "cm.h" X Xmain(argc,argv) Xint argc; Xchar **argv; X{ X cm_variable *i_var, *d_var, *s_var; X char s_val[1000]; X int i_val; X double d_val; X X if (argc>1) printf("going to host %s for cmm\n",argv[1]); X if (0 > cm_init("printer",(argc>1?argv[1]:(char *)0),0)) exit(-1); X X i_var = cm_declare("i_var",CM_ROLE_READER | CM_ROLE_WAKEUP); X d_var = cm_declare("d_var",CM_ROLE_READER); X s_var = cm_declare("s_var",CM_ROLE_READER); X X while (TRUE) { X if (0 > cm_sync(CM_WAIT_AT_MOST_ONCE)) return; X cm_get_value(i_var,&i_val); X printf("i_var = %d\n",i_val); X cm_get_value(d_var,&d_val); X printf("d_var = %g\n",d_val); X cm_get_value(s_var,s_val); X printf("s_var = %s\n",s_val); X } X} END_OF_FILE if test 823 -ne `wc -c <'src/server2.c'`; then echo shar: \"'src/server2.c'\" unpacked with wrong size! fi # end of 'src/server2.c' fi if test -f 'src/server8a.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/server8a.c'\" else echo shar: Extracting \"'src/server8a.c'\" \(388 characters\) sed "s/^X//" >'src/server8a.c' <<'END_OF_FILE' X/* server8a.c - constant wait on common memory to test that cmm doesn't */ X/* blow up when we die and it is writing to us (SIGPIPE) */ X X#include <sys/time.h> X#include "cm.h" X Xcm_variable *variable; X Xmain() X{ X if (0>cm_init("constant reader SIGPIPE",0,0)) exit(-1); X X if (!(variable = cm_declare("variable",CM_ROLE_READER|CM_ROLE_WAKEUP))) exit(-1); X X while (1) { X cm_sync(CM_WAIT); X } X} END_OF_FILE if test 388 -ne `wc -c <'src/server8a.c'`; then echo shar: \"'src/server8a.c'\" unpacked with wrong size! fi # end of 'src/server8a.c' fi if test -f 'src/server8b.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/server8b.c'\" else echo shar: Extracting \"'src/server8b.c'\" \(366 characters\) sed "s/^X//" >'src/server8b.c' <<'END_OF_FILE' X/* server8b.c - receive updates from common memory but do not read() */ X/* see if cmm eventually hangs on write() */ X X#include <sys/time.h> X#include "cm.h" X Xcm_variable *variable; X Xmain() X{ X if (0>cm_init("constant reader hang",0,0)) exit(-1); X X if (!(variable = cm_declare("variable",CM_ROLE_READER|CM_ROLE_WAKEUP))) exit(-1); X X cm_sync(CM_NO_WAIT); X sigpause(); X} END_OF_FILE if test 366 -ne `wc -c <'src/server8b.c'`; then echo shar: \"'src/server8b.c'\" unpacked with wrong size! fi # end of 'src/server8b.c' fi if test -f 'src/usr_get_slot.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/usr_get_slot.c'\" else echo shar: Extracting \"'src/usr_get_slot.c'\" \(1508 characters\) sed "s/^X//" >'src/usr_get_slot.c' <<'END_OF_FILE' X/* X Xthese functions are used by the user to read and process information from Xincoming slots X X*/ X X#include <stdio.h> X#include <sys/time.h> X#include "cm_constants.h" X#include "cm_sd.h" X#include "cm_interface.h" X#include "cm_slot.h" X Xcm_variable *get_variable(); X Xuser_decode_slot(s) Xstruct slot *s; X{ X int rc = 0; X X switch (s->s_type) { X case CM_SLOT_READ_RESPONSE: X rc = get_slot_read_response(s->s_name, X &s->subslot.read_response); X break; X case CM_SLOT_ERROR: X rc = get_slot_error(s->s_name,&s->subslot.error); X break; X default: X fprintf(stderr,"user_decode_slot: unknown slot type (%d)...msg aborted\n",s->s_type); X rc = E_CM_GET_SLOT_UNKNOWN_SLOT_TYPE; X break; X } X return(rc); X} X X/* returns 0 if ok, negative if problem decoding slot */ Xint Xget_slot_error(name,s) Xchar *name; Xstruct slot_error *s; X{ X fprintf(stderr,"CMM: error processing variable <%s> - %s\n",name, X s->msg); X /* isn't there a "type" field in the error subslot, too? */ X return(0); X} X X/* 0 if ok, negative if problem decoding slot */ Xint Xget_slot_read_response(name,s) Xchar *name; Xstruct slot_read_response *s; X{ X int rc; X cm_variable *v; X X if (!(v = get_variable(name))) { X fprintf(stderr,"get_slot_read_response: <%s> unknown (sent from cm)\n",v->name); X return(E_CM_GET_SLOT_GET_VARIABLE); X } X X if (0 > cm_flat_to_sd(&s->fdata,&v->data)) X return(E_CM_GET_SLOT_FLAT_TO_SD); X v->count = s->srr_count; X v->command_association = s->srr_command_association; X cm_time_copy(&s->srr_timestamp,&v->timestamp); X return(0); X} X END_OF_FILE if test 1508 -ne `wc -c <'src/usr_get_slot.c'`; then echo shar: \"'src/usr_get_slot.c'\" unpacked with wrong size! fi # end of 'src/usr_get_slot.c' fi if test -f 'src/usr_put_slot.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/usr_put_slot.c'\" else echo shar: Extracting \"'src/usr_put_slot.c'\" \(2058 characters\) sed "s/^X//" >'src/usr_put_slot.c' <<'END_OF_FILE' X X/* X XThese routines build slots for the user. These slots are placed into a Xmsg structure and sent to the cmm. The all return 0 for failure, or a Xpositive number indicating the number of bytes in the slot. X X*/ X X#include <stdio.h> X#include <sys/time.h> X#include "cm_constants.h" X#include "cm_sd.h" X#include "cm_slot.h" X#include "cm_msg.h" X#include "cm_bytestuff.h" X#include "cm_interface.h" X X/* this indicates that the user wants the cmm to send back the latest value */ X/* of all variables */ Xput_slot_read(m) Xstruct msg *m; X{ X struct slot s; X unsigned int size; X X init_slot(&s,"read all",CM_SLOT_READ); X size = align(sizeof(struct slot_hdr)); X/* size += align(sizeof(struct slot_read));*/ X return(finish_slot(m,&s,size)); X} X Xint /* returns size of data written in msg */ Xput_slot_write(m,name,data,cmd) Xstruct msg *m; Xchar *name; Xcm_value *data; Xint cmd; X{ X struct big_slot s; X unsigned int size; X X init_slot((struct slot *)&s,name,CM_SLOT_WRITE); X size = align(sizeof(struct slot_hdr)); X size += align(sizeof(struct slot_write_hdr)); X s.subslot.write.sw_command_association = cmd; X size += cm_sd_to_flat(data,&s.subslot.write.fdata); X return(finish_slot(m,(struct slot *)&s,size)); X} X Xint Xput_slot_declare(m,name,role,cmd_assoc) Xstruct msg *m; Xchar *name; Xstruct usr_var_role *role; Xint cmd_assoc; X{ X struct slot s; X unsigned int size; X X init_slot(&s,name,CM_SLOT_DECLARE); X size = align(sizeof(struct slot_hdr)); X size += align(sizeof(struct slot_declare)); X /* could do some checking on the following */ X s.subslot.declare.role.reader = role->reader; X s.subslot.declare.role.wakeup = role->wakeup; X s.subslot.declare.role.xwriter = role->xwriter; X s.subslot.declare.role.nonxwriter = role->nonxwriter; X s.subslot.declare.command_association = cmd_assoc; X return(finish_slot(m,&s,size)); X} X Xint Xput_slot_undeclare(m,name) Xstruct msg *m; Xchar *name; X{ X struct slot s; X unsigned int size; X X init_slot(&s,name,CM_SLOT_UNDECLARE); X size = align(sizeof(struct slot_hdr)); X/* size += align(sizeof(struct slot_undeclare));*/ X return(finish_slot(m,&s,size)); X} END_OF_FILE if test 2058 -ne `wc -c <'src/usr_put_slot.c'`; then echo shar: \"'src/usr_put_slot.c'\" unpacked with wrong size! fi # end of 'src/usr_put_slot.c' fi if test -f 'src/usr_var.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/usr_var.c'\" else echo shar: Extracting \"'src/usr_var.c'\" \(2280 characters\) sed "s/^X//" >'src/usr_var.c' <<'END_OF_FILE' X/* usr_var.c - utility functions for user only! */ X X#include <stdio.h> X#include <sys/types.h> X#include <sys/time.h> X#include <strings.h> X X#include "cm_constants.h" X#include "cm_sd.h" X#include "cm_interface.h" X Xcm_variable cm_variables[CM_MAXUSERVARIABLES]; X Xcm_variable * Xget_variable(name) Xchar *name; X{ X int i; X X eprintf(10,"entering get_variable(%s)\n",name); X for (i=0;i<CM_MAXUSERVARIABLES;i++) { X /* create it if we come to an empty variable */ X if (!cm_variables[i].status.inuse) { X eprintf(10,"get_variable: found empty variable slot\n"); X strcpy(cm_variables[i].name,name); X cm_sd_clear(&cm_variables[i].data); X cm_variables[i].role.reader = 0; X cm_variables[i].role.nonxwriter = 0; X cm_variables[i].role.wakeup = 0; X cm_variables[i].role.xwriter = 0; X cm_variables[i].old_count = 0; X cm_variables[i].count = 0; X cm_variables[i].command_association = 0; X cm_time_zero(&cm_variables[i].timestamp); X cm_variables[i].status.inuse = TRUE; X cm_variables[i].status.written = FALSE; X cm_variables[i].status.declared = FALSE; X return(&cm_variables[i]); X } X /* found an old definition */ X if (!(strcmp(cm_variables[i].name,name))) { X eprintf(10,"get_variable() found old defn\n"); X return(&cm_variables[i]); X } X } X /* no old definition and no space for a new one!!!! */ X return(NULL); X} X X/* XThe following function allows the user to step through all the common Xmemory values, for example, to see if any have changed. If v is NULL, Xthe first value is returned. If no more cm_variables are in use, NULL is Xreturned. X XThis function is also used by the common memory system itself, as it Xhides the implementation of the user cm_variables as a large array. XPresumably, it will be changed to have a hash index in the future Xfor speed. X*/ Xcm_variable * Xnext_user_variable(v) Xcm_variable *v; /* if NULL, start from the beginning */ X{ X if (v == 0) v = cm_variables; /* reinitialize */ X else v++; /* next one */ X X for (;v<&cm_variables[CM_MAXUSERVARIABLES];v++) { X if (v->status.inuse) return(v); X } X return((cm_variable *)NULL); X} END_OF_FILE if test 2280 -ne `wc -c <'src/usr_var.c'`; then echo shar: \"'src/usr_var.c'\" unpacked with wrong size! fi # end of 'src/usr_var.c' fi if test ! -d 'stream' ; then echo shar: Creating directory \"'stream'\" mkdir 'stream' fi if test -f 'stream/Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'stream/Makefile'\" else echo shar: Extracting \"'stream/Makefile'\" \(932 characters\) sed "s/^X//" >'stream/Makefile' <<'END_OF_FILE' XCOMMON = stream.o sized_io.o XOFILES = $(COMMON) reader.o writer.o XHFILES = inet.h XCFLAGS = X#CFLAGS = -g -DDEBUG XLIB = libstream.a X X# for testing purposes X Xtest: libstream.a reader writer X Xlibstream.a: stream.o sized_io.o X ar cr libstream.a `lorder $(COMMON) | tsort` X ranlib libstream.a X Xcleanup: X rm $(OFILES) libstream.a X Xinstall: libstream.a makedirs X cp $(HFILES) /usr/local/include/inet/stream X cp libstream.a /usr/local/lib X cp stream.3 /usr/local/man/manl/sized_io.l X Xmakedirs: /usr/local/include/inet /usr/local/include/inet/stream X X/usr/local/include/inet: X mkdir /usr/local/include/inet X X/usr/local/include/inet/stream: X mkdir /usr/local/include/inet/stream X Xlint: X lint -u stream.c _sized_io.c X Xlintc: X lint -Cstream stream.c _sized_io.c X su -c "mv llib-lstream.ln /usr/lib/lint" -f X Xreader: reader.o $(COMMON) X cc $(CFLAGS) -o reader reader.o $(LIB) X Xwriter: writer.o $(COMMON) X cc $(CFLAGS) -o writer writer.o $(LIB) END_OF_FILE if test 932 -ne `wc -c <'stream/Makefile'`; then echo shar: \"'stream/Makefile'\" unpacked with wrong size! fi # end of 'stream/Makefile' fi if test -f 'stream/README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'stream/README'\" else echo shar: Extracting \"'stream/README'\" \(2493 characters\) sed "s/^X//" >'stream/README' <<'END_OF_FILE' XThis package provides a quick-and-easy means of providing reliable Xand large-packet communication between processes. X XIt is especially nice because initport() does all the hard work of Xinitializing TCP connections, and select_server_stream() does the Xhard work of connecting processes to each other. X XTo install, type X X make install X XTo test, type X X make test X reader X writer (in different window) X writer (in yet another window) X writer (in yet ...) X and so on. X X Xreader and writer are two programs that should communicate with Xeach other. Type things into any of the writers and reader will Xprint it out prefaced by the file descriptor the data came in on. X XBugs and problems to Don Libes XNational Bureau of Standards XBldg 220, Rm A-127 XGaithersburg, MD 20899 X(301) 975-3535 X X XSYNOPSIS X X#include <sys/socket.h> X#include <netinet/in.h> X#include <inet.h> X X cc [options] [files] sized_io.o stream.o X XDESCRIPTION X XThis package implements packet or stream IO between a server process and Xa number of client processes, using the TCP/IP (stream) facilities. X XA client uses the call: X X s = initport(PORT_NUMBER(XXX),CLIENT,SOCK_STREAM); X Xs is the server's data socket and is used as a file descriptor in further Xcommunication. The port may be specified by name (PORT_NAME("foo")), if it Xis registered. X XSimilarly, the server uses the following call: X X s = initport(PORT_NUMBER(XXX),SERVER,SOCK_STREAM); X Xs is the server's connection socket. To receive data or connections, the Xserver calls select_server_stream(). X X client = select_server_stream(s,&fds); X XThis returns a file descriptor corresponding to a client, when a client has Xsent a message to the server. It handles initial connections as well as Xclient deaths. s is the server's connection socket that was returned by Xinitport(). fds is an int used by select...() for storing a bit string Xcorresponding to client sockets. Initialize it to 0, and don't mess with it Xafter that. X XTo use the file descriptors in a stream-oriented manner, use read() and Xwrite(). To use the file descriptors in a packet-oriented manner, use Xsized_read() and sized_write(). The sized...() calls read and write one Xpacket at a time, while packet boundaries are ignored in read() and write(). X X cc = sized_read(fd,buffer,maxsize) X cc = sized_write(fd,buffer,size) X XThe arguments for sized_read() and sized_write() are very similar to read() Xand write(). The only difference is that in sized_read(), maxsize is the Xmaximum size of an acceptable packet. END_OF_FILE if test 2493 -ne `wc -c <'stream/README'`; then echo shar: \"'stream/README'\" unpacked with wrong size! fi # end of 'stream/README' fi if test -f 'stream/inet.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'stream/inet.h'\" else echo shar: Extracting \"'stream/inet.h'\" \(417 characters\) sed "s/^X//" >'stream/inet.h' <<'END_OF_FILE' X#define TRUE 1 X#define FALSE 0 X X#define PORT_TYPE_NAME 1 X#define PORT_TYPE_NUMBER 2 X X#define PORT_NAME(name) PORT_TYPE_NAME,name,(u_short)0 X#define PORT_NUMBER(number) PORT_TYPE_NUMBER,0,(u_short)number X X/* sockettypes are SOCKET_STREAM and SOCKET_DGRAM */ X X#define DATAGRAM_FLAGS 0 /* for recv and sendto */ X X#define SERVER 1 X#define CLIENT 2 X#define server (role == SERVER) X#define client (role == CLIENT) END_OF_FILE if test 417 -ne `wc -c <'stream/inet.h'`; then echo shar: \"'stream/inet.h'\" unpacked with wrong size! fi # end of 'stream/inet.h' fi if test -f 'stream/reader.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'stream/reader.c'\" else echo shar: Extracting \"'stream/reader.c'\" \(729 characters\) sed "s/^X//" >'stream/reader.c' <<'END_OF_FILE' X#include <stdio.h> X#include <sys/types.h> X#include <sys/socket.h> X#include <netinet/in.h> X#include <netdb.h> X#include "inet.h" X Xchar buf[2000]; X Xmain(argc,argv) Xint argc; Xchar **argv; X{ X int writer; X int cc; X int fd; X int fds = 0; X X /* if an arg is provided, use that as the hostname to look for the */ X /* service */ X fd = initport(PORT_NUMBER(2000),SERVER,SOCK_STREAM,(char *)0); X if (fd < 0) { X fprintf(stderr,"initport() = %d\n",fd); X exit(-1); X } X X while (TRUE) { X writer = select_server_stream(fd,&fds); X cc = sized_read(writer,buf,2000); X if (cc <= 0) { X printf("%d: EOF\n",writer); X close(writer); X continue; X } X printf("%d: %s\n",writer,buf); X if (cc == 1) cc = sized_write(writer,"1 char",6); X } X} END_OF_FILE if test 729 -ne `wc -c <'stream/reader.c'`; then echo shar: \"'stream/reader.c'\" unpacked with wrong size! fi # end of 'stream/reader.c' fi if test -f 'stream/stream.3' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'stream/stream.3'\" else echo shar: Extracting \"'stream/stream.3'\" \(2306 characters\) sed "s/^X//" >'stream/stream.3' <<'END_OF_FILE' X.TH SIZED_IO 3NBS "11 January 1988" X.SH NAME Xinitport, sized_read, sized_write - send datagrams using TCP X.SH SYNOPSIS X.B #include <sys/socket.h> X.br X.B #include <netinet/in.h> X.br X.B #include <inet.h> X.PP X.B int s = initport(PORT_NUMBER(XXX),SERVER,SOCK_STREAM); X.PP X.B int client = select_server_stream(s,&fds); X.br X.B int s; X.br X.B int fds; X.PP X.B int cc = sized_read(fd,buffer,maxsize) X.br X.B int cc = sized_write(fd,buffer,size) X.br X.B int fd; X.br X.B char *buffer; X.br X.B int maxsize; X.SH DESCRIPTION XThis package implements packet or stream IO between a server Xprocess and a number of client processes, using the TCP/IP (stream) Xfacilities. It is particularly useful to send packets larger than Xthat allowed by UDP. UDP packets are also not reliable - these are. X.PP XA client uses the call: X.PP X.B s = initport(PORT_NUMBER(XXX),CLIENT,SOCK_STREAM); X.PP Xs is the server's data socket and is used as a file descriptor in further Xcommunication. The port may be specified by name (PORT_NAME("foo")), if it Xis registered. X.PP XSimilarly, the server uses the following call: X.PP X.B s = initport(PORT_NUMBER(XXX),SERVER,SOCK_STREAM); X.PP Xs is the server's connection socket. To receive data or connections, the Xserver calls select_server_stream(). X.PP X.B client = select_server_stream(s,&fds); X.PP XThis returns a file descriptor corresponding to a client, when a client has Xsent a message to the server. It handles initial connections as well as Xclient deaths. s is the server's connection socket that was returned by Xinitport(). fds is an int used by select...() for storing a bit string Xcorresponding to client sockets. Initialize it to 0, and don't mess with it Xafter that. X.PP XTo use the file descriptors in a stream-oriented manner, use read() and Xwrite(). To use the file descriptors in a packet-oriented manner, use Xsized_read() and sized_write(). The sized...() calls read and write one Xpacket at a time, while packet boundaries are ignored in read() and write(). X.PP X.B cc = sized_read(fd,buffer,maxsize) X.PP X.B cc = sized_write(fd,buffer,size) X.PP XThe arguments for sized_read() and sized_write() are very similar to read() Xand write(). The only difference is that in sized_read(), maxsize is the Xmaximum size of an acceptable packet. X.SH AUTHOR XDon Libes - National Bureau of Standards END_OF_FILE if test 2306 -ne `wc -c <'stream/stream.3'`; then echo shar: \"'stream/stream.3'\" unpacked with wrong size! fi # end of 'stream/stream.3' fi if test -f 'stream/writer.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'stream/writer.c'\" else echo shar: Extracting \"'stream/writer.c'\" \(763 characters\) sed "s/^X//" >'stream/writer.c' <<'END_OF_FILE' X#include <stdio.h> X#include <sys/types.h> X#include <sys/time.h> X#include <sys/socket.h> X#include <netinet/in.h> X/* #include <netdb.h> */ X#include "inet.h" X Xchar msg[2000]; X Xstruct timeval timeout = {0L, 0L}; Xint maxfds; X Xmain(argc,argv) Xint argc; Xchar **argv; X{ X int cc; X int i; X int fd; X int readfds; X X maxfds = getdtablesize(); X fd = initport(PORT_NUMBER(2000),CLIENT,SOCK_STREAM,argc>1?argv[1]:""); X X if (fd < 0) { X fprintf(stderr,"initport() = %d\n",fd); X exit(-1); X } X for (i=0;;i++) { X printf("%d: ",i); X gets(msg); X cc = sized_write(fd,msg,strlen(msg)+1); X readfds = 1<<fd; X if (0 < select(maxfds,&readfds,0,0,&timeout) X && readfds == 1<<fd) { X cc = sized_read(fd,msg,2000); X msg[cc] = '\0'; X printf("msg from server: %s\n",msg); X } X } X} END_OF_FILE if test 763 -ne `wc -c <'stream/writer.c'`; then echo shar: \"'stream/writer.c'\" unpacked with wrong size! fi # end of 'stream/writer.c' fi echo shar: End of archive 1 \(of 4\). cp /dev/null ark1isdone MISSING="" for I in 1 2 3 4 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 4 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.