#include <sys/stat.h>
#include <fcntl.h>
#include <sys/param.h>
+#include <executor/spi.h>
#if 0
#include <linux/proc_fs.h>
#define INTEGER_LEN 10
#define BIGINT_LEN 20
+#define GET_PIDS \
+ "SELECT procpid " \
+ "FROM pg_stat_activity"
+
#define GET_NEXT_VALUE(p, q, value, length, msg) \
if ((q = strchr(p, ' ')) == NULL) \
{ \
Datum pg_proctab(PG_FUNCTION_ARGS)
{
- int32 pid = PG_GETARG_INT32(0);
-
FuncCallContext *funcctx;
int call_cntr;
int max_calls;
struct statfs sb;
int fd;
int len;
- char buffer[512];
+ char buffer[4096];
char *p;
char *q;
i_rss, i_signal, i_blocked, i_sigignore, i_sigcatch,
i_wchan, i_exit_signal, i_processor, i_rt_priority, i_policy,
i_delayacct_blkio_ticks};
- char **values = NULL;
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL())
{
MemoryContext oldcontext;
- values = (char **) palloc(34 * sizeof(char *));
- values[i_pid] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
- values[i_comm] = (char *) palloc(1024 * sizeof(char));
- values[i_state] = (char *) palloc(2 * sizeof(char));
- values[i_ppid] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
- values[i_pgrp] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
- values[i_session] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
- values[i_tty_nr] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
- values[i_tpgid] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
- values[i_flags] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
- values[i_minflt] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_cminflt] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_majflt] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_cmajflt] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_utime] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_stime] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_cutime] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_cstime] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_priority] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_nice] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_num_threads] =
- (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_itrealvalue] =
- (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_starttime] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_vsize] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_rss] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_signal] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_blocked] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_sigignore] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_sigcatch] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_wchan] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_exit_signal] =
- (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
- values[i_processor] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
- values[i_rt_priority] =
- (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_policy] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
- values[i_delayacct_blkio_ticks] =
- (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ int ret;
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT();
/* switch to memory context appropriate for multiple function calls */
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
- /* total number of tuples to be returned */
- funcctx->max_calls = 1;
-
/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
ereport(ERROR,
attinmeta = TupleDescGetAttInMetadata(tupdesc);
funcctx->attinmeta = attinmeta;
+ /* Get pid of all client connections. */
+
+ SPI_connect();
+
+ ret = SPI_exec(GET_PIDS, 0);
+ if (ret == SPI_OK_SELECT)
+ {
+ int32 *ppid;
+
+ int i;
+ TupleDesc tupdesc;
+ SPITupleTable *tuptable;
+ HeapTuple tuple;
+
+ /* total number of tuples to be returned */
+ funcctx->max_calls = SPI_processed;
+ funcctx->user_fctx = palloc(sizeof(int32) * funcctx->max_calls);
+ ppid = (int32 *) funcctx->user_fctx;
+
+ tupdesc = SPI_tuptable->tupdesc;
+ tuptable = SPI_tuptable;
+
+ for (i = 0; i < funcctx->max_calls; i++)
+ {
+ tuple = tuptable->vals[i];
+ ppid[i] = atoi(SPI_getvalue(tuple, tupdesc, 1));
+ }
+ }
+ else
+ {
+ /* total number of tuples to be returned */
+ funcctx->max_calls = 0;
+ elog(WARNING, "unable to get procpids from pg_stat_activity");
+ }
+
+ SPI_finish();
+
MemoryContextSwitchTo(oldcontext);
}
{
HeapTuple tuple;
Datum result;
+
+ int32 *ppid;
+ int32 pid;
int length;
+ char **values = NULL;
+
/* Check if /proc is mounted. */
if (statfs(PROCFS, &sb) < 0 || sb.f_type != PROC_SUPER_MAGIC)
{
/* Read the stat info for the pid. */
+ ppid = (int32 *) funcctx->user_fctx;
+ pid = ppid[call_cntr];
+
/*
* Sanity check, make sure we read the pid information that we're
* asking for.
close(fd);
buffer[len] = '\0';
+ values = (char **) palloc(34 * sizeof(char *));
+ values[i_pid] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
+ values[i_comm] = (char *) palloc(1024 * sizeof(char));
+ values[i_state] = (char *) palloc(2 * sizeof(char));
+ values[i_ppid] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
+ values[i_pgrp] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
+ values[i_session] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
+ values[i_tty_nr] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
+ values[i_tpgid] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
+ values[i_flags] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
+ values[i_minflt] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_cminflt] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_majflt] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_cmajflt] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_utime] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_stime] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_cutime] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_cstime] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_priority] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_nice] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_num_threads] =
+ (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_itrealvalue] =
+ (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_starttime] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_vsize] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_rss] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_signal] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_blocked] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_sigignore] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_sigcatch] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_wchan] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_exit_signal] =
+ (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
+ values[i_processor] = (char *) palloc((INTEGER_LEN + 1) * sizeof(char));
+ values[i_rt_priority] =
+ (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_policy] = (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+ values[i_delayacct_blkio_ticks] =
+ (char *) palloc((BIGINT_LEN + 1) * sizeof(char));
+
p = buffer;
/* pid */