1: # include   "../../ingres.h"
   2: # include   "../../symbol.h"
   3: # include   "../../pipes.h"
   4: # include   "IIglobals.h"
   5: 
   6: /*
   7: **  Buffered Read From Pipe
   8: **
   9: **	Reads from the pipe with the UNIX file descriptor `des' into
  10: **	the buffer `buf'.  `Mode' tells what is to be done.  `Msg' is
  11: **	the address of the input buffer, and `n' is the length of the
  12: **	info.  If `n' is zero, the data is assumed to be a null-
  13: **	terminated string.
  14: **
  15: **	`Buf' is defined in "../pipes.h" together with the modes.
  16: **	The pipe should be written by wrpipe() to insure that the
  17: **	pipe formats match.
  18: **
  19: **	Modes:
  20: **
  21: **	P_PRIME -- Primes the buffer.  This involves cleaning out all
  22: **		the header stuff so that a physical read is forced
  23: **		on the next normal call to rdpipe().  It also resets
  24: **		the error flag, etc.
  25: **
  26: **	P_NORM -- This is the normal mode.  If the buffer is empty,
  27: **		it is filled from the pipe.  `N' bytes are moved into
  28: **		`msg'.  If `n' is zero, bytes are moved into `msg' up
  29: **		to and including the first null byte.  The pipe is
  30: **		read whenever necessary, so the size of the data
  31: **		buffer (controlled by PBUFSIZ) has absolutely no
  32: **		effect on operation.
  33: **
  34: **	P_SYNC -- This mode reads the buffer, filling the pipe as
  35: **		necessary, until an End Of Pipe (EOP) is encountered.
  36: **		An EOP is defined as an empty buffer with a mode
  37: **		("hdrstat") of "END_STAT".  Any data left in the pipe
  38: **		is thrown away, but error messages are not.  Anything
  39: **		not already read by the user is read by P_SYNC, so if
  40: **		you are not certain that you have already read the
  41: **		previous EOP.
  42: **
  43: **	P_EXECID -- The first (exec_id) field of the pipe buffer header
  44: **		is read and returned.  This is used (for instance) by
  45: **		the DBU routines, which must get the exec_id, but must
  46: **		not read the rest of the pipe in case they must overlay
  47: **		themselves.  It must ALWAYS be followed by a rdpipe of
  48: **		mode P_FUNCID!!
  49: **
  50: **	P_FUNCID -- The second through last bytes of the pipe are read
  51: **		into the buffer, and the function code ("func_id") is
  52: **		returned.  This is the second half of a P_EXECID call.
  53: **
  54: **	P_INT -- In the event of an interrupt, a wrpipe() call should
  55: **		be made to all writable pipes of mode P_INT, and then
  56: **		rdpipe() calls should be made on all readable pipes
  57: **		of this mode.  This clears out the pipe up until a
  58: **		special type of pipe header ("SYNC_STAT") is read.  It
  59: **		is absolutely critical that this is called in conjunc-
  60: **		tion with all other processes.  This mode is used in
  61: **		resyncpipes(), which performs all the correct calls
  62: **		in the correct order.
  63: **
  64: **	In all cases except P_INT mode, if an error is read from the
  65: **	pipe it is automatically passed to proc_error().  This routine
  66: **	is responsible for passing the error message to the next higher
  67: **	process.
  68: **
  69: **	If an end of file is read from the pipe, the end_job() routine
  70: **	is called.  This routine should do any necessary end of job
  71: **	processing needed (closing relations, etc.) and return with
  72: **	a zero value.
  73: **
  74: **	Default proc_error() and end_job() routines exist in the
  75: **	library, so if you don't want any extra processing, you can
  76: **	just not bother to define them.
  77: **
  78: **	In general, the number of bytes actually read is returned.  If
  79: **	you read an EOP, zero is returned.
  80: */
  81: 
  82: IIrdpipe(mode, buf1, des, msg, n)
  83: int     mode;
  84: char        *msg;
  85: int     n;
  86: int     des;        /* UNIX file descriptor for pipe */
  87: struct pipfrmt  *buf1;
  88: {
  89:     register int        knt;
  90:     register int        syncflg;
  91:     int         i;
  92:     extern char     *IIproc_name;
  93:     char            *proc_name;
  94:     register struct pipfrmt *buf;
  95:     char            *argv[10], args[512];
  96:     char            *ap;
  97:     int         argc, err;
  98: 
  99: #	ifdef xATR1
 100:     proc_name = IIproc_name ? IIproc_name : "";
 101: #	endif
 102: 
 103:     buf = buf1;
 104: 
 105: #	ifdef xATR1
 106:     if (IIdebug > 1)
 107:         printf("\n%s ent rdpipe md %d buf %u des %d\n", proc_name, mode, buf, des);
 108: #	endif
 109:     syncflg = 0;
 110:     switch (mode)
 111:     {
 112: 
 113:       case P_PRIME:
 114:         buf->pbuf_pt = buf->buf_len = buf->err_id = 0;
 115:         buf->hdrstat = NORM_STAT;
 116:         return (0);
 117: 
 118:       case P_NORM:
 119:         break;
 120: 
 121:       case P_SYNC:
 122:         syncflg++;
 123:         break;
 124: 
 125:       case P_EXECID:
 126:         if (read(des, &buf->exec_id, 1) < 1)
 127:         {
 128:             goto eoj;
 129:         }
 130: #		ifdef xATR3
 131:         if (IIdebug > 1)
 132:             printf("%s rdpipe ret %c\n", proc_name,  buf->exec_id);
 133: #		endif
 134:         return (buf->exec_id);
 135: 
 136:       case P_FUNCID:
 137:         i = read(des, &buf->func_id, HDRSIZ+PBUFSIZ-1) + 1;
 138:         buf->pbuf_pt = -1;
 139:         goto chkerr;
 140: 
 141:       case P_INT:
 142:         syncflg--;
 143:         buf->hdrstat = NORM_STAT;
 144:         break;
 145: 
 146:       default:
 147:         IIsyserr("rdpipe: bad call %d", mode);
 148:     }
 149:     knt = 0;
 150:     if (buf->pbuf_pt < 0)
 151:         buf->pbuf_pt = 0;
 152: 
 153:     do
 154:     {
 155:         /* check for buffer empty */
 156:         while (buf->pbuf_pt >= buf->buf_len || syncflg)
 157:         {
 158:             /* read a new buffer full */
 159:             if (buf->hdrstat == LAST_STAT && syncflg >= 0)
 160:             {
 161:                 goto out;
 162:             }
 163: #			ifdef xATR3
 164:             if (IIdebug > 1)
 165:             {
 166:                 printf("%s rdng %d w len %d pt %d err %d sf %d\n",
 167:                     proc_name, des, buf->buf_len, buf->pbuf_pt, buf->err_id, syncflg);
 168:             }
 169: #			endif
 170:             i = read(des, buf, HDRSIZ+PBUFSIZ);
 171:             if (i == 0)
 172:             {
 173:             eoj:
 174: #				ifdef xATR3
 175:                 if (IIdebug > 1)
 176:                     printf("%s rdpipe exit\n", proc_name);
 177: #				endif
 178:                 if (syncflg < 0)
 179:                     IIsyserr("rdpipe: EOF %d", des);
 180:                 /* exit(end_job(buf, des)); */
 181:                 exit(-1);
 182:             }
 183:             buf->pbuf_pt = 0;
 184:         chkerr:
 185: #			ifdef xATR2
 186:             if (IIdebug > 1)
 187:                 IIprpipe(buf);
 188: #			endif
 189:             if (i < HDRSIZ+PBUFSIZ)
 190:                 IIsyserr("rdpipe: rd err buf %u des %d", buf, des);
 191:             if (buf->hdrstat == SYNC_STAT)
 192:             {
 193:                 if (syncflg < 0)
 194:                     return (1);
 195:                 else
 196:                     IIsyserr("rdpipe: unexpected SYNC_STAT");
 197:             }
 198:             if (buf->err_id != 0 && syncflg >= 0)
 199:             {
 200: #				ifdef xATR2
 201:                 if (IIdebug > 1)
 202:                     printf("%s rdpipe err %d\n", proc_name, buf->err_id);
 203: #				endif
 204:                 /* proc_error(buf, des); */
 205:                 /* The error parameters are read here
 206: 				** and put into an argv, argc structure
 207: 				** so that the user doesn't have to use
 208: 				** Ingres utilities to write an intelligent
 209: 				** error handler.
 210: 				*/
 211:                 ap = args;
 212:                 argc = 0;
 213:                 err = buf->err_id;
 214:                 while (i = IIrdpipe(P_NORM,buf,des,ap,0))
 215:                 {
 216:                     argv[argc++] = ap;
 217:                     ap += i;
 218:                     if (argc > 10 || (args - ap) >= 500)
 219:                         IIsyserr("Too many error parameters!");
 220:                 }
 221:                 IIerror(err, argc, argv);
 222: #				ifdef xATR3
 223:                 if (IIdebug > 1)
 224:                     printf("%s pe ret\n", proc_name);
 225: #				endif
 226:                 buf->pbuf_pt = buf->buf_len;
 227:                 buf->hdrstat = NORM_STAT;
 228:             }
 229:             if (buf->pbuf_pt < 0)
 230:             {
 231:                 /* P_FUNCID mode */
 232: #				ifdef xATR1
 233:                 if (IIdebug > 1)
 234:                     printf("%s rdpipe ret %c\n",
 235:                         proc_name, buf->func_id);
 236: #				endif
 237:                 return (buf->func_id);
 238:             }
 239:         }
 240:         /* get a byte of information */
 241:         msg[knt++] = buf->pbuf[buf->pbuf_pt++];
 242:     } while ((n == 0) ? (msg[knt-1]) : (knt < n));
 243: 
 244: out:
 245: #	ifdef xATR1
 246:     if (IIdebug > 1)
 247:     {
 248:         printf("%s rdpipe ret %d", proc_name, knt);
 249:         if (n == 0 && syncflg == 0)
 250:             printf(", str `%s'", msg);
 251:         printf("\n");
 252:     }
 253: #	endif
 254:     return(knt);
 255: }
Last modified: 1995-02-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2887
Valid CSS Valid XHTML 1.0 Strict