* Add (or replace) a line in the data directory lock file. * The given string should not include a trailing newline. * * 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. While we could fix that by adding a truncate call, that would make * the file update non-atomic, which we'd rather avo
| 1445 | * should endeavor never to shorten a line once it's been written. |
| 1446 | */ |
| 1447 | void |
| 1448 | AddToDataDirLockFile(int target_line, const char *str) |
| 1449 | { |
| 1450 | int fd; |
| 1451 | int len; |
| 1452 | int lineno; |
| 1453 | char *srcptr; |
| 1454 | char *destptr; |
| 1455 | char srcbuffer[BLCKSZ]; |
| 1456 | char destbuffer[BLCKSZ]; |
| 1457 | |
| 1458 | fd = open(DIRECTORY_LOCK_FILE, O_RDWR | PG_BINARY, 0); |
| 1459 | if (fd < 0) |
| 1460 | { |
| 1461 | ereport(LOG, |
| 1462 | (errcode_for_file_access(), |
| 1463 | errmsg("could not open file \"%s\": %m", |
| 1464 | DIRECTORY_LOCK_FILE))); |
| 1465 | return; |
| 1466 | } |
| 1467 | pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ); |
| 1468 | len = read(fd, srcbuffer, sizeof(srcbuffer) - 1); |
| 1469 | pgstat_report_wait_end(); |
| 1470 | if (len < 0) |
| 1471 | { |
| 1472 | ereport(LOG, |
| 1473 | (errcode_for_file_access(), |
| 1474 | errmsg("could not read from file \"%s\": %m", |
| 1475 | DIRECTORY_LOCK_FILE))); |
| 1476 | close(fd); |
| 1477 | return; |
| 1478 | } |
| 1479 | srcbuffer[len] = '\0'; |
| 1480 | |
| 1481 | /* |
| 1482 | * Advance over lines we are not supposed to rewrite, then copy them to |
| 1483 | * destbuffer. |
| 1484 | */ |
| 1485 | srcptr = srcbuffer; |
| 1486 | for (lineno = 1; lineno < target_line; lineno++) |
| 1487 | { |
| 1488 | char *eol = strchr(srcptr, '\n'); |
| 1489 | |
| 1490 | if (eol == NULL) |
| 1491 | break; /* not enough lines in file yet */ |
| 1492 | srcptr = eol + 1; |
| 1493 | } |
| 1494 | memcpy(destbuffer, srcbuffer, srcptr - srcbuffer); |
| 1495 | destptr = destbuffer + (srcptr - srcbuffer); |
| 1496 | |
| 1497 | /* |
| 1498 | * Fill in any missing lines before the target line, in case lines are |
| 1499 | * added to the file out of order. |
| 1500 | */ |
| 1501 | for (; lineno < target_line; lineno++) |
| 1502 | { |
| 1503 | if (destptr < destbuffer + sizeof(destbuffer)) |
| 1504 | *destptr++ = '\n'; |
no test coverage detected