aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/init/miscinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/init/miscinit.c')
-rw-r--r--src/backend/utils/init/miscinit.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 49a6afafe7f..afbf8f86919 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -47,6 +47,7 @@
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/memutils.h"
+#include "utils/pidfile.h"
#include "utils/syscache.h"
#include "utils/varlena.h"
@@ -1149,8 +1150,9 @@ TouchSocketLockFiles(void)
*
* Note: because we don't truncate the file, if we were to rewrite a line
* with less data than it had before, there would be garbage after the last
- * line. We don't ever actually do that, so not worth adding another kernel
- * call to cover the possibility.
+ * line. While we could fix that by adding a truncate call, that would make
+ * the file update non-atomic, which we'd rather avoid. Therefore, callers
+ * should endeavor never to shorten a line once it's been written.
*/
void
AddToDataDirLockFile(int target_line, const char *str)
@@ -1193,19 +1195,26 @@ AddToDataDirLockFile(int target_line, const char *str)
srcptr = srcbuffer;
for (lineno = 1; lineno < target_line; lineno++)
{
- if ((srcptr = strchr(srcptr, '\n')) == NULL)
- {
- elog(LOG, "incomplete data in \"%s\": found only %d newlines while trying to add line %d",
- DIRECTORY_LOCK_FILE, lineno - 1, target_line);
- close(fd);
- return;
- }
- srcptr++;
+ char *eol = strchr(srcptr, '\n');
+
+ if (eol == NULL)
+ break; /* not enough lines in file yet */
+ srcptr = eol + 1;
}
memcpy(destbuffer, srcbuffer, srcptr - srcbuffer);
destptr = destbuffer + (srcptr - srcbuffer);
/*
+ * Fill in any missing lines before the target line, in case lines are
+ * added to the file out of order.
+ */
+ for (; lineno < target_line; lineno++)
+ {
+ if (destptr < destbuffer + sizeof(destbuffer))
+ *destptr++ = '\n';
+ }
+
+ /*
* Write or rewrite the target line.
*/
snprintf(destptr, destbuffer + sizeof(destbuffer) - destptr, "%s\n", str);