Index: misc.c =================================================================== RCS file: /projects/pgadmin-tools/support/misc.c,v retrieving revision 1.5 retrieving revision 1.6 diff -Lsupport/misc.c -Lsupport/misc.c -u -w -r1.5 -r1.6 --- support/misc.c +++ support/misc.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include "commands/dbcommands.h" #include "miscadmin.h" @@ -203,7 +205,6 @@ Datum pg_postmaster_starttime(PG_FUNCTION_ARGS) { Timestamp result; - struct pg_tm tm; if (!superuser()) ereport(ERROR, @@ -212,6 +213,7 @@ #ifdef WIN32 { + struct pg_tm tm; extern DLLIMPORT HANDLE PostmasterHandle; FILETIME creationTime; FILETIME exitTime, kernelTime, userTime; @@ -230,17 +232,82 @@ tm.tm_hour = st.wHour; tm.tm_min = st.wMinute; tm.tm_sec = st.wSecond; + + if (tm2timestamp(&tm, 0, NULL, &result) != 0) + { + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("postmaster timestamp out of range"))); + } } #else - PG_RETURN_NULL(); -#endif + { + FILE *fp; + char buffer[MAXPGPATH]; + pg_time_t now = time(NULL); + struct pg_tm *tm = pg_localtime(&now); + double systemSeconds; + long procJiffies; + int i; - if (tm2timestamp(&tm, 0, NULL, &result) != 0) + tm->tm_year += 1900; + tm->tm_mon += 1; + + if (tm2timestamp(tm, 0, NULL, &result) != 0) { ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("postmaster timestamp out of range"))); } + fp = fopen("/proc/uptime", "r"); + if (!fp) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not open /proc/uptime: %m"))); + + if (fscanf(fp, "%lf", &systemSeconds) != 1) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not interpret /proc/uptime: %m"))); + + fclose(fp); + + sprintf(buffer, "/proc/%u/stat", PostmasterPid); + fp = fopen(buffer, "r"); + if (!fp) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not open %s: %m", buffer))); + + +#define PROC_STAT_POS 22 + + for (i=1 ; i < PROC_STAT_POS ; i++) + { + char c; + do + { + c = fgetc(fp); + } + while (c && c != ' '); + } + + if (fscanf(fp, "%ld", &procJiffies) != 1) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not interpret %s: %m", buffer))); + + fclose(fp); + +#ifdef HAVE_INT64_TIMESTAMP + result += (procJiffies/100. - systemSeconds) / INT64CONST(1000000); +#else + result += (procJiffies/100. - systemSeconds); +#endif + } +#endif + + PG_RETURN_TIMESTAMP(result); }