aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/misc/ps_status.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/misc/ps_status.c')
-rw-r--r--src/backend/utils/misc/ps_status.c158
1 files changed, 143 insertions, 15 deletions
diff --git a/src/backend/utils/misc/ps_status.c b/src/backend/utils/misc/ps_status.c
index c99a4f10fa5..3894a017f3d 100644
--- a/src/backend/utils/misc/ps_status.c
+++ b/src/backend/utils/misc/ps_status.c
@@ -86,6 +86,14 @@ static size_t ps_buffer_cur_len; /* nominal strlen(ps_buffer) */
static size_t ps_buffer_fixed_size; /* size of the constant prefix */
+/*
+ * Length of ps_buffer before the suffix was appeneded to the end, or 0 if we
+ * didn't set a suffix.
+ */
+static size_t ps_buffer_nosuffix_len;
+
+static void flush_ps_display(void);
+
#endif /* not PS_USE_NONE */
/* save the original argv[] location here */
@@ -300,37 +308,158 @@ init_ps_display(const char *fixed_part)
#endif /* not PS_USE_NONE */
}
-
-
+#ifndef PS_USE_NONE
/*
- * Call this to update the ps status display to a fixed prefix plus an
- * indication of what you're currently doing passed in the argument.
+ * update_ps_display_precheck
+ * Helper function to determine if updating the process title is
+ * something that we need to do.
*/
-void
-set_ps_display(const char *activity)
+static bool
+update_ps_display_precheck(void)
{
-#ifndef PS_USE_NONE
/* update_process_title=off disables updates */
if (!update_process_title)
- return;
+ return false;
/* no ps display for stand-alone backend */
if (!IsUnderPostmaster)
- return;
+ return false;
#ifdef PS_USE_CLOBBER_ARGV
/* If ps_buffer is a pointer, it might still be null */
if (!ps_buffer)
- return;
+ return false;
#endif
+ return true;
+}
+#endif /* not PS_USE_NONE */
+
+/*
+ * set_ps_display_suffix
+ * Adjust the process title to append 'suffix' onto the end with a space
+ * between it and the current process title.
+ */
+void
+set_ps_display_suffix(const char *suffix)
+{
+#ifndef PS_USE_NONE
+ size_t len;
+
+ /* first, check if we need to update the process title */
+ if (!update_ps_display_precheck())
+ return;
+
+ /* if there's already a suffix, overwrite it */
+ if (ps_buffer_nosuffix_len > 0)
+ ps_buffer_cur_len = ps_buffer_nosuffix_len;
+ else
+ ps_buffer_nosuffix_len = ps_buffer_cur_len;
+
+ len = strlen(suffix);
+
+ /* check if we have enough space to append the suffix */
+ if (ps_buffer_cur_len + len + 1 >= ps_buffer_size)
+ {
+ /* not enough space. Check the buffer isn't full already */
+ if (ps_buffer_cur_len < ps_buffer_size - 1)
+ {
+ /* append a space before the suffix */
+ ps_buffer[ps_buffer_cur_len++] = ' ';
+
+ /* just add what we can and fill the ps_buffer */
+ memcpy(ps_buffer + ps_buffer_cur_len, suffix,
+ ps_buffer_size - ps_buffer_cur_len - 1);
+ ps_buffer[ps_buffer_size - 1] = '\0';
+ ps_buffer_cur_len = ps_buffer_size - 1;
+ }
+ }
+ else
+ {
+ ps_buffer[ps_buffer_cur_len++] = ' ';
+ memcpy(ps_buffer + ps_buffer_cur_len, suffix, len + 1);
+ ps_buffer_cur_len = ps_buffer_cur_len + len;
+ }
+
+ Assert(strlen(ps_buffer) == ps_buffer_cur_len);
+
+ /* and set the new title */
+ flush_ps_display();
+#endif /* not PS_USE_NONE */
+}
+
+/*
+ * set_ps_display_remove_suffix
+ * Remove the process display suffix added by set_ps_display_suffix
+ */
+void
+set_ps_display_remove_suffix(void)
+{
+#ifndef PS_USE_NONE
+ /* first, check if we need to update the process title */
+ if (!update_ps_display_precheck())
+ return;
+
+ /* check we added a suffix */
+ if (ps_buffer_nosuffix_len == 0)
+ return; /* no suffix */
+
+ /* remove the suffix from ps_buffer */
+ ps_buffer[ps_buffer_nosuffix_len] = '\0';
+ ps_buffer_cur_len = ps_buffer_nosuffix_len;
+ ps_buffer_nosuffix_len = 0;
+
+ Assert(ps_buffer_cur_len == strlen(ps_buffer));
+
+ /* and set the new title */
+ flush_ps_display();
+#endif /* not PS_USE_NONE */
+}
+
+/*
+ * Call this to update the ps status display to a fixed prefix plus an
+ * indication of what you're currently doing passed in the argument.
+ *
+ * 'len' must be the same as strlen(activity)
+ */
+void
+set_ps_display_with_len(const char *activity, size_t len)
+{
+ Assert(strlen(activity) == len);
+
+#ifndef PS_USE_NONE
+ /* first, check if we need to update the process title */
+ if (!update_ps_display_precheck())
+ return;
+
+ /* wipe out any suffix when the title is completely changed */
+ ps_buffer_nosuffix_len = 0;
+
/* Update ps_buffer to contain both fixed part and activity */
- strlcpy(ps_buffer + ps_buffer_fixed_size, activity,
- ps_buffer_size - ps_buffer_fixed_size);
- ps_buffer_cur_len = strlen(ps_buffer);
+ if (ps_buffer_fixed_size + len >= ps_buffer_size)
+ {
+ /* handle the case where ps_buffer doesn't have enough space */
+ memcpy(ps_buffer + ps_buffer_fixed_size, activity,
+ ps_buffer_size - ps_buffer_fixed_size - 1);
+ ps_buffer[ps_buffer_size - 1] = '\0';
+ ps_buffer_cur_len = ps_buffer_size - 1;
+ }
+ else
+ {
+ memcpy(ps_buffer + ps_buffer_fixed_size, activity, len + 1);
+ ps_buffer_cur_len = ps_buffer_fixed_size + len;
+ }
+ Assert(strlen(ps_buffer) == ps_buffer_cur_len);
/* Transmit new setting to kernel, if necessary */
+ flush_ps_display();
+#endif /* not PS_USE_NONE */
+}
+#ifndef PS_USE_NONE
+static void
+flush_ps_display(void)
+{
#ifdef PS_USE_SETPROCTITLE
setproctitle("%s", ps_buffer);
#elif defined(PS_USE_SETPROCTITLE_FAST)
@@ -363,9 +492,8 @@ set_ps_display(const char *activity)
ident_handle = CreateEvent(NULL, TRUE, FALSE, name);
}
#endif /* PS_USE_WIN32 */
-#endif /* not PS_USE_NONE */
}
-
+#endif /* not PS_USE_NONE */
/*
* Returns what's currently in the ps display, in case someone needs