/* BEGIN DOCUMENTATION Name: Daniel T. Soldahl Created: 08/02/83 Last Update: 12/20/83 Title: VSENDRECV.C - C callable routines for variable-length send & receive Index: Send, Receive, Intertask Communication Abstract: Variable length character send & receive data under RSX-11M. Compatible with SNDS & RCVS which are PL/I callable. Usage: rc = vsend(&task,buff,buflen) Sends the string to the specified task, in a series of packets using SDAT$ calls. If a send of a packet fails due to pool exhaustion, it is retried indefinitely. rc = vrecv(&task,buff,&buflen) Receives a string sent by SNDS or VSEND from the specified task, returning it in the given buffer area. Buflen is set to actual count of characters received. If there is no data to be received yet, the calling task is stopped until data is received. rc = vrecva(&task,buff,&buflen) Same as VRECV, except receives from any task, returning the name of the task in the given variable and returning the received data in the given buffer area. Parameters: struct rad50 task - Rad50 taskname, INPUT for vsend & vrecv, OUTPUT for vrecva. char *buff - Pointer to data buffer INPUT for vsend, OUTPUT for vrecv & vrecva. Buff may contain arbitrary binary data, there is no size limit. int buflen - INPUT for vsend: number of characters to send. INPUT for vrecv & vrecva: Maximum buffer size. OUTPUT for vrecv & vrecva: Number of characters actually received. int rc - Return code is the returned directive status word (dsw$) from SDAT$, RCST$ directives. int tskabo - INPUT for vrecv & vrecva: External boolean used to force return if receiving task is aborted. (Must be set false on entry, can be set true by an external ast routine.) Environment: RSX11M Ver. 4.0, DECUS C Compiler See Also: SNDRCVS.C (SNDS, RCVS), TCM.C Description: Example(s): Uses: You can use these routines instead of RECEIV & SEND - they are easier to use, and don't constrain your design to an arbitrary 13 word limit. If your data is 25 bytes or less, only one packet is sent. However, since the data sent via these routines is stored in system pool, they should not be used in an application where there is the possibility of a significant amount of data piling up before the receiving task can get it - this could bring the whole system down. This applies both to a few large messages or to a lot of little ones. For this kind of use, use one of the DECUS variable send & receive drivers or use disk queueing. These routines are ideal for the case where one or a few one-line messages are going back and forth between interacting tasks, which wait for a response before sending more, or where data is sent only occasionally to a task that does not exit. Internal: Each 13-word (26-byte) packet has one-byte count and 25-byte data piece if the byte count is negative, there are more packets to come. Update History: 2-AUG-83 SNDSRCVS.C written by Walter Epp was modified to be callable from C by Dan Soldahl. 16-SEP-83 Changed vsend to return IS_SUC if ustp gives IE_ITS (task not stopped), DTS. 20-DEC-83 Added check for tskabo in rcvs_ routine, DTS. END DOCUMENTATION */ #include ; #include ; #define maxchunk 25 typedef struct{char nbytes; char data[maxchunk];} packet; typedef long taskname; /*rad50 variable, in a form that allows assignment*/ extern boolean tskabo; /* If true then vrecv will return if unstopped & no receive data ready. */ int function vsend(task, str, len) taskname *task; charpointer str; int len; { register charpointer pnext, p, ppkt, plast; packet sendpkt; int n,dsw; pnext = str; plast = pnext + len; do { n = plast - pnext; iff n>maxchunk then n = maxchunk; p = pnext; pnext = pnext + n; sendpkt.nbytes = ifx pnext==plast thenx n elsex -maxchunk; ppkt = &sendpkt.data; while (pplast then { pnext = plast; overflow = true; } ppkt = &rcvpkt.pkt.data; while (p