int fcgi_flush(fcgi_request *req, int close) { int len; close_packet(req); len = req->out_pos - req->out_buf; if (close) { fcgi_end_request_rec *rec = (fcgi_end_request_rec*)(req->out_pos); fcgi_make_header(&rec->hdr, FCGI_END_REQUEST, req->id, sizeof(fcgi_end_request)); rec->body.appStatusB3 = 0; rec->body.appStatusB2 = 0; rec->body.appStatusB1 = 0; rec->body.appStatusB0 = 0; rec->body.protocolStatus = FCGI_REQUEST_COMPLETE; len += sizeof(fcgi_end_request_rec); } if (safe_write(req, req->out_buf, len) != len) { req->keep = 0; return 0; } req->out_pos = req->out_buf; return 1; }
void barectf_platform_linux_fs_fini(struct barectf_platform_linux_fs_ctx *ctx) { if (barectf_packet_is_open(&ctx->ctx) && !barectf_packet_is_empty(&ctx->ctx)) { close_packet(ctx); } fclose(ctx->fh); free(barectf_packet_buf(&ctx->ctx)); free(ctx); }
int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int len) { int limit, rest; if (len <= 0) { return 0; } if (req->out_hdr && req->out_hdr->type != type) { close_packet(req); } #if 0 /* Unoptimized, but clear version */ rest = len; while (rest > 0) { limit = sizeof(req->out_buf) - (req->out_pos - req->out_buf); if (!req->out_hdr) { if (limit < sizeof(fcgi_header)) { if (!fcgi_flush(req, 0)) { return -1; } } open_packet(req, type); } limit = sizeof(req->out_buf) - (req->out_pos - req->out_buf); if (rest < limit) { memcpy(req->out_pos, str, rest); req->out_pos += rest; return len; } else { memcpy(req->out_pos, str, limit); req->out_pos += limit; rest -= limit; str += limit; if (!fcgi_flush(req, 0)) { return -1; } } } #else /* Optimized version */ limit = sizeof(req->out_buf) - (req->out_pos - req->out_buf); if (!req->out_hdr) { limit -= sizeof(fcgi_header); if (limit < 0) limit = 0; } if (len < limit) { if (!req->out_hdr) { open_packet(req, type); } memcpy(req->out_pos, str, len); req->out_pos += len; } else if (len - limit < sizeof(req->out_buf) - sizeof(fcgi_header)) { if (!req->out_hdr) { open_packet(req, type); } if (limit > 0) { memcpy(req->out_pos, str, limit); req->out_pos += limit; } if (!fcgi_flush(req, 0)) { return -1; } if (len > limit) { open_packet(req, type); memcpy(req->out_pos, str + limit, len - limit); req->out_pos += len - limit; } } else { int pos = 0; int pad; close_packet(req); while ((len - pos) > 0xffff) { open_packet(req, type); fcgi_make_header(req->out_hdr, type, req->id, 0xfff8); req->out_hdr = NULL; if (!fcgi_flush(req, 0)) { return -1; } if (safe_write(req, str + pos, 0xfff8) != 0xfff8) { req->keep = 0; return -1; } pos += 0xfff8; } pad = (((len - pos) + 7) & ~7) - (len - pos); rest = pad ? 8 - pad : 0; open_packet(req, type); fcgi_make_header(req->out_hdr, type, req->id, (len - pos) - rest); req->out_hdr = NULL; if (!fcgi_flush(req, 0)) { return -1; } if (safe_write(req, str + pos, (len - pos) - rest) != (len - pos) - rest) { req->keep = 0; return -1; } if (pad) { open_packet(req, type); memcpy(req->out_pos, str + len - rest, rest); req->out_pos += rest; } } #endif return len; }