- /* copy and read header */
- memcpy(header, ptr, PIPE_HEADER_SIZE);
- header[PIPE_HEADER_SIZE] = '\0';
- id = header[0];
- subid = header[1];
- required = Ustrtol(header + 2, &endc, 10) + PIPE_HEADER_SIZE; /* header + data */
- if (*endc)
- {
- msg = string_sprintf("failed to read pipe from transport process "
- "%d for transport %s: error reading size from header", pid, addr->transport->driver_name);
+while (!done)
+ {
+ retry_item *r, **rp;
+ uschar pipeheader[PIPE_HEADER_SIZE+1];
+ uschar *id = &pipeheader[0];
+ uschar *subid = &pipeheader[1];
+ uschar *ptr = big_buffer;
+ size_t required = PIPE_HEADER_SIZE; /* first the pipehaeder, later the data */
+ ssize_t got;
+
+ DEBUG(D_deliver) debug_printf(
+ "expect %lu bytes (pipeheader) from tpt process %d\n", (u_long)required, pid);
+
+ /* We require(!) all the PIPE_HEADER_SIZE bytes here, as we know,
+ they're written in a timely manner, so waiting for the write shouldn't hurt a lot.
+ If we get less, we can assume the subprocess do be done and do not expect any further
+ information from it. */
+
+ got = readn(fd, pipeheader, required);
+ if (got != required)
+ {
+ msg = string_sprintf("got " SSIZE_T_FMT " of %d bytes (pipeheader) "
+ "from transport process %d for transport %s",
+ got, PIPE_HEADER_SIZE, pid, addr->transport->driver_name);