static apr_status_t pipe_bucket_read(apr_bucket *a, const char **str, apr_size_t *len, apr_read_type_e block) { apr_file_t *p = a->data; char *buf; apr_status_t rv; apr_interval_time_t timeout; if (block == APR_NONBLOCK_READ) { apr_file_pipe_timeout_get(p, &timeout); apr_file_pipe_timeout_set(p, 0); } *str = NULL; *len = APR_BUCKET_BUFF_SIZE; buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */ rv = apr_file_read(p, buf, len); if (block == APR_NONBLOCK_READ) { apr_file_pipe_timeout_set(p, timeout); } if (rv != APR_SUCCESS && rv != APR_EOF) { apr_bucket_free(buf); return rv; } /* * If there's more to read we have to keep the rest of the pipe * for later. Otherwise, we'll close the pipe. * XXX: Note that more complicated bucket types that * refer to data not in memory and must therefore have a read() * function similar to this one should be wary of copying this * code because if they have a destroy function they probably * want to migrate the bucket's subordinate structure from the * old bucket to a raw new one and adjust it as appropriate, * rather than destroying the old one and creating a completely * new bucket. */ if (*len > 0) { apr_bucket_heap *h; /* Change the current bucket to refer to what we read */ a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free); h = a->data; h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */ *str = buf; APR_BUCKET_INSERT_AFTER(a, apr_bucket_pipe_create(p, a->list)); } else { apr_bucket_free(buf); a = apr_bucket_immortal_make(a, "", 0); *str = a->data; if (rv == APR_EOF) { apr_file_close(p); } } return APR_SUCCESS; }
static void set_timeout(abts_case *tc, void *data) { apr_status_t rv; apr_interval_time_t timeout; rv = apr_file_pipe_create(&readp, &writep, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); ABTS_PTR_NOTNULL(tc, readp); ABTS_PTR_NOTNULL(tc, writep); rv = apr_file_pipe_timeout_get(readp, &timeout); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); ABTS_ASSERT(tc, "Timeout mismatch, expected -1", timeout == -1); rv = apr_file_pipe_timeout_set(readp, apr_time_from_sec(1)); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); rv = apr_file_pipe_timeout_get(readp, &timeout); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); ABTS_ASSERT(tc, "Timeout mismatch, expected 1 second", timeout == apr_time_from_sec(1)); }
static void set_timeout(CuTest *tc) { apr_status_t rv; apr_file_t *readp = NULL; apr_file_t *writep = NULL; apr_interval_time_t timeout; rv = apr_file_pipe_create(&readp, &writep, p); CuAssertIntEquals(tc, APR_SUCCESS, rv); CuAssertPtrNotNull(tc, readp); CuAssertPtrNotNull(tc, writep); rv = apr_file_pipe_timeout_get(readp, &timeout); CuAssertIntEquals(tc, APR_SUCCESS, rv); CuAssert(tc, "Timeout mismatch, expected -1", timeout == -1); rv = apr_file_pipe_timeout_set(readp, apr_time_from_sec(1)); CuAssertIntEquals(tc, APR_SUCCESS, rv); rv = apr_file_pipe_timeout_get(readp, &timeout); CuAssertIntEquals(tc, APR_SUCCESS, rv); CuAssert(tc, "Timeout mismatch, expected 1 second", timeout == apr_time_from_sec(1)); }
static int pipe_timeout_get(lua_State *L) { lua_apr_file *pipe; apr_status_t status; apr_interval_time_t timeout; pipe = file_check(L, 1, 1); status = apr_file_pipe_timeout_get(pipe->handle, &timeout); if (status != APR_SUCCESS) return push_file_error(L, pipe, status); else if (timeout <= 0) lua_pushboolean(L, timeout != 0); else lua_pushinteger(L, (lua_Integer) timeout); return 1; }
/** * Get the timeout value for a pipe or manipulate the blocking state. * @param thepipe The pipe we are getting a timeout for. * @param timeout The current timeout value in microseconds. */ SWITCH_DECLARE(switch_status_t) switch_file_pipe_timeout_get(switch_file_t *thepipe, switch_interval_time_t *timeout) { return apr_file_pipe_timeout_get((apr_file_t *) thepipe, (apr_interval_time_t *) timeout); }