/* PL/I-callable routines for variable-length send & receive of character strings under RSX-11M calls: CALL SNDS(TASK, STRING, DSW); 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. CALL RCVS(TASK, STRING, DSW); receives a string sent by SNDS from the specified task, returning it in the given string variable. if there is no data to be received yet, the calling task is stopped until data is received. CALL RCVAS(TASK, STRING, DSW); same as RCVS, except receives from any task, returning the name of the task in the given variable and returning the string in the given string variable. where: TASK is the RAD50 name of a task (FIXED BIN(31)) for SNDS & RCVS, must be a FIXED BIN(31) variable for RCVAS. STRING is any PL/I string variable or constant for SNDS, must be a variable for RCVS & RCVAS. there's no limit on the size. variables may be either VARYING or UNVARYING. strings can contain arbitrary binary information if needed. DSW is a FIXED BIN(15) variable to receive the returned directive status word. 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. RCVS & RCVAS follow the standard PL/I string assignment rules in storing strings into variables - i.e., if to a VARYING variable, the current length is set, if to an UNVARYING variable and the string is shorter, it is blank padded, and if the string won't fit in the variable, it is truncated and the STRINGSIZE condition is raised. In addition, if truncation occurs, error IE.RBS (-15) is returned. */ #include ; #include ; #include ; #include ; /* 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 */ #define maxchunk 25 typedef struct{char nbytes; char data[maxchunk];} packet; typedef long taskname; /*rad50 variable, in a form that allows assignment*/ procedure SNDS(narg, task, str, dsw) int narg; taskname *task; plistring str; int *dsw; { register charpointer pnext, p, ppkt, plast; packet sendpkt; int n; plient("SNDS"); iff narg<3 then signal(NUMARGS); pnext = plistr(str); plast = pnext + plilen(str); 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 (pplisdptr.plisdvsp)->plivslen = pnext - pfirst; else while (pnext