diff options
Diffstat (limited to 'src/backend/utils/init/miscinit.c')
-rw-r--r-- | src/backend/utils/init/miscinit.c | 29 |
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); |