src/backend/utils/init/miscinit.c
/*
 * 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.  We don't ever actually do that, so not worth adding another kernel
 * call to cover the possibility.
 */
Add (or replace) a line in the data directory lock file.
The given string should not include a trailing newline.

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.
Add ( or replace ) a line in the data directory lock file . The given string should not include a trailing newline . 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 .
void
AddToDataDirLockFile(int target_line, const char *str)
{
	int			fd;
	int			len;
	int			lineno;
	char	   *srcptr;
	char	   *destptr;
	char		srcbuffer[BLCKSZ];
	char		destbuffer[BLCKSZ];
	fd = open(DIRECTORY_LOCK_FILE, O_RDWR | PG_BINARY, 0);
	if (fd < 0)
	{
		ereport(LOG,
				(errcode_for_file_access(),
				 errmsg("could not open file \"%s\": %m",
						DIRECTORY_LOCK_FILE)));
		return;
	}
	len = read(fd, srcbuffer, sizeof(srcbuffer) - 1);
	if (len < 0)
	{
		ereport(LOG,
				(errcode_for_file_access(),
				 errmsg("could not read from file \"%s\": %m",
						DIRECTORY_LOCK_FILE)));
		close(fd);
		return;
	}
	srcbuffer[len] = '\0';
	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++;
	}
	memcpy(destbuffer, srcbuffer, srcptr - srcbuffer);
	destptr = destbuffer + (srcptr - srcbuffer);
	snprintf(destptr, destbuffer + sizeof(destbuffer) - destptr, "%s\n", str);
	destptr += strlen(destptr);
	if ((srcptr = strchr(srcptr, '\n')) != NULL)
	{
		srcptr++;
		snprintf(destptr, destbuffer + sizeof(destbuffer) - destptr, "%s",
				 srcptr);
	}
	len = strlen(destbuffer);
	errno = 0;
	if (lseek(fd, (off_t) 0, SEEK_SET) != 0 ||
		(int) write(fd, destbuffer, len) != len)
	{
		if (errno == 0)
			errno = ENOSPC;
		ereport(LOG,
				(errcode_for_file_access(),
				 errmsg("could not write to file \"%s\": %m",
						DIRECTORY_LOCK_FILE)));
		close(fd);
		return;
	}
	if (pg_fsync(fd) != 0)
	{
		ereport(LOG,
				(errcode_for_file_access(),
				 errmsg("could not write to file \"%s\": %m",
						DIRECTORY_LOCK_FILE)));
	}
	if (close(fd) != 0)
	{
		ereport(LOG,
				(errcode_for_file_access(),
				 errmsg("could not write to file \"%s\": %m",
						DIRECTORY_LOCK_FILE)));
	}
}
void AddToDataDirLockFile ( int target_line , const char * str ) { int fd ; int len ; int lineno ; char * srcptr ; char * destptr ; char srcbuffer [ BLCKSZ ] ; char destbuffer [ BLCKSZ ] ; fd = open ( DIRECTORY_LOCK_FILE , O_RDWR | PG_BINARY , 0 ) ; if ( fd < 0 ) { ereport ( LOG , ( errcode_for_file_access ( ) , errmsg ( " \" \" " , DIRECTORY_LOCK_FILE ) ) ) ; return ; } len = read ( fd , srcbuffer , sizeof ( srcbuffer ) - 1 ) ; if ( len < 0 ) { ereport ( LOG , ( errcode_for_file_access ( ) , errmsg ( " \" \" " , DIRECTORY_LOCK_FILE ) ) ) ; close ( fd ) ; return ; } srcbuffer [ len ] = ' \0 ' ; srcptr = srcbuffer ; for ( lineno = 1 ; lineno < target_line ; lineno ++ ) { if ( ( srcptr = strchr ( srcptr , ' \n ' ) ) == NULL ) { elog ( LOG , " \" \" " , DIRECTORY_LOCK_FILE , lineno - 1 , target_line ) ; close ( fd ) ; return ; } srcptr ++ ; } memcpy ( destbuffer , srcbuffer , srcptr - srcbuffer ) ; destptr = destbuffer + ( srcptr - srcbuffer ) ; snprintf ( destptr , destbuffer + sizeof ( destbuffer ) - destptr , " \n " , str ) ; destptr += strlen ( destptr ) ; if ( ( srcptr = strchr ( srcptr , ' \n ' ) ) != NULL ) { srcptr ++ ; snprintf ( destptr , destbuffer + sizeof ( destbuffer ) - destptr , " " , srcptr ) ; } len = strlen ( destbuffer ) ; errno = 0 ; if ( lseek ( fd , ( off_t ) 0 , SEEK_SET ) != 0 || ( int ) write ( fd , destbuffer , len ) != len ) { if ( errno == 0 ) errno = ENOSPC ; ereport ( LOG , ( errcode_for_file_access ( ) , errmsg ( " \" \" " , DIRECTORY_LOCK_FILE ) ) ) ; close ( fd ) ; return ; } if ( pg_fsync ( fd ) != 0 ) { ereport ( LOG , ( errcode_for_file_access ( ) , errmsg ( " \" \" " , DIRECTORY_LOCK_FILE ) ) ) ; } if ( close ( fd ) != 0 ) { ereport ( LOG , ( errcode_for_file_access ( ) , errmsg ( " \" \" " , DIRECTORY_LOCK_FILE ) ) ) ; } }
Add (or replace) a line in the data directory lock file.
Add ( or replace ) a line in the data directory lock file .
/*
	 * Advance over lines we are not supposed to rewrite, then copy them to
	 * destbuffer.
	 */ /*
	 * Write or rewrite the target line.
	 */ /*
	 * If there are more lines in the old file, append them to destbuffer.
	 */ /*
	 * And rewrite the data.  Since we write in a single kernel call, this
	 * update should appear atomic to onlookers.
	 */ /* if write didn't set errno, assume problem is no disk space */