1: # include "../ingres.h" 2: # include "../pipes.h" 3: 4: /* 5: ** Buffered Write on Pipe 6: ** 7: ** The message `msg' of length `n' is buffered and written onto 8: ** the pipe with UNIX file descriptor `des'. `Buf' is the addr 9: ** of the buffer in which buffering is to take place. If `n' is 10: ** zero, `msg' is taken to be a null-terminated string of char- 11: ** acters. `Mode' gives the operations mode of wrpipe(). 12: ** 13: ** Buffers written with wrpipe() should be read with rdpipe(). 14: ** 15: ** Modes: 16: ** 17: ** P_PRIME -- Prime the pipe for writing. This involves clearing 18: ** out the error field, setting normal status, etc. In 19: ** general, it should always be done when you want to 20: ** start writing. It need not be done after writing an 21: ** end-of-pipe (EOP), as this operation automatically 22: ** resets the pipe. The "exec_id" field (read by 23: ** rdpipe(P_EXECID)) is set to `des', and the "func_id" 24: ** field is set to `n'. 25: ** 26: ** P_NORM -- Normal mode. `Msg' is buffered into `buf' and 27: ** physically written into the pipe as necessary. 28: ** 29: ** P_END -- Writes an EOP. Only the first three parameters need 30: ** be specified. 31: ** 32: ** P_FLUSH -- Flushes the buffer into the pipe, but does not write 33: ** an EOP. In fact, a non-EOP is guaranteed to be 34: ** written. 35: ** 36: ** P_WRITE -- Same as P_FLUSH, but the mode is unchanged. This 37: ** mode is pretty obscure, and you probably need not use 38: ** it. 39: ** 40: ** P_INT -- Writes an interrupt synchronization block into the 41: ** pipe. This mode need only be called by resyncpipes() 42: ** and need not normally concern the user. It is critical 43: ** that this mode be called by all processes so that dead- 44: ** lock or syserrs do not occur. 45: ** 46: ** P_PARAM -- Copies one byte parameter into structure. Can be 47: ** read via a call to rdpipe(P_PARAM). 48: */ 49: 50: extern int write(); /* standard write function */ 51: int (*Pi_wr_fn)() = &write; /* pipe write function */ 52: 53: wrpipe(mode, buf1, des, msg, n) 54: int mode; 55: struct pipfrmt *buf1; 56: int des; 57: char *msg; 58: int n; 59: { 60: register int nn; 61: extern char *Proc_name; 62: register int msgl; 63: register struct pipfrmt *buf; 64: int flushflg; 65: int i; 66: 67: buf = buf1; 68: # ifdef xATR1 69: if (tTf(99, 8)) 70: printf("\n%s wrpipe md %d buf %u des %d msg %l n %d\n", 71: Proc_name, mode, buf, des, msg, n); 72: # endif 73: nn = msgl = 0; 74: flushflg = 0; 75: switch (mode) 76: { 77: case P_PRIME: 78: buf->buf_len = buf->pbuf_pt = buf->err_id = buf->param_id = 0; 79: buf->hdrstat = NORM_STAT; 80: buf->exec_id = des; 81: buf->func_id = n; 82: return(0); 83: 84: case P_PARAM: 85: buf->param_id = des; 86: return (0); 87: 88: case P_NORM: 89: msgl = nn = (n == 0) ? length(msg) + 1 : n; 90: break; 91: 92: case P_END: 93: buf->hdrstat = LAST_STAT; 94: flushflg++; 95: break; 96: 97: case P_FLUSH: 98: buf->hdrstat = NORM_STAT; 99: flushflg++; 100: break; 101: 102: case P_WRITE: 103: flushflg--; 104: break; 105: 106: case P_INT: 107: buf->hdrstat = SYNC_STAT; 108: flushflg++; 109: break; 110: 111: default: 112: syserr("wrpipe: bad mode %d", mode); 113: } 114: 115: while (nn > 0 || flushflg) 116: { 117: /* BUFFER OUT DATA */ 118: while (nn > 0 && buf->pbuf_pt < PBUFSIZ) 119: buf->pbuf[buf->pbuf_pt++] = msg[msgl - (nn--)]; 120: /* WRITE PIPE ? */ 121: if (buf->pbuf_pt >= PBUFSIZ || flushflg) 122: { 123: if (flushflg >= 0) 124: buf->buf_len = buf->pbuf_pt; 125: # ifdef xATR2 126: if (tTf(99, 10)) 127: prpipe(buf); 128: # endif 129: if ((i = (*Pi_wr_fn)(des, buf, HDRSIZ+PBUFSIZ)) < HDRSIZ+PBUFSIZ) 130: syserr("wrpipe: wr err %d %d", i, des); 131: buf->pbuf_pt = 0; 132: buf->err_id = 0; 133: flushflg = 0; 134: } 135: } 136: # ifdef xATR3 137: if (tTf(99, 9)) 138: { 139: printf("%s wrpipe ret %d\n", Proc_name, msgl); 140: } 141: # endif 142: return (msgl); 143: }