diff -crNB upstream/postgresql-8.4.8//src/backend/access/transam/slru.c trunk//src/backend/access/transam/slru.c
*** upstream/postgresql-8.4.8//src/backend/access/transam/slru.c	2011-04-15 13:17:14.000000000 +1000
--- trunk//src/backend/access/transam/slru.c	2011-09-07 11:53:32.000000000 +1000
***************
*** 56,61 ****
--- 56,62 ----
  #include "access/xlog.h"
  #include "storage/fd.h"
  #include "storage/shmem.h"
+ #include "storage/write.h"
  #include "miscadmin.h"
  
  
***************
*** 785,791 ****
  	}
  
  	errno = 0;
! 	if (write(fd, shared->page_buffer[slotno], BLCKSZ) != BLCKSZ)
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
--- 786,792 ----
  	}
  
  	errno = 0;
! 	if (WriteAll(fd, shared->page_buffer[slotno], BLCKSZ) != BLCKSZ)
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
diff -crNB upstream/postgresql-8.4.8//src/backend/access/transam/twophase.c trunk//src/backend/access/transam/twophase.c
*** upstream/postgresql-8.4.8//src/backend/access/transam/twophase.c	2011-04-15 13:17:14.000000000 +1000
--- trunk//src/backend/access/transam/twophase.c	2011-09-07 11:54:19.000000000 +1000
***************
*** 58,63 ****
--- 58,64 ----
  #include "storage/fd.h"
  #include "storage/procarray.h"
  #include "storage/smgr.h"
+ #include "storage/write.h"
  #include "utils/builtins.h"
  #include "utils/memutils.h"
  
***************
*** 941,947 ****
  	for (record = records.head; record != NULL; record = record->next)
  	{
  		COMP_CRC32(statefile_crc, record->data, record->len);
! 		if ((write(fd, record->data, record->len)) != record->len)
  		{
  			close(fd);
  			ereport(ERROR,
--- 942,948 ----
  	for (record = records.head; record != NULL; record = record->next)
  	{
  		COMP_CRC32(statefile_crc, record->data, record->len);
! 		if ((WriteAll(fd, record->data, record->len)) != record->len)
  		{
  			close(fd);
  			ereport(ERROR,
***************
*** 958,964 ****
  	 */
  	bogus_crc = ~statefile_crc;
  
! 	if ((write(fd, &bogus_crc, sizeof(pg_crc32))) != sizeof(pg_crc32))
  	{
  		close(fd);
  		ereport(ERROR,
--- 959,965 ----
  	 */
  	bogus_crc = ~statefile_crc;
  
! 	if ((WriteAll(fd, &bogus_crc, sizeof(pg_crc32))) != sizeof(pg_crc32))
  	{
  		close(fd);
  		ereport(ERROR,
***************
*** 1007,1013 ****
  	/* If we crash now, we have prepared: WAL replay will fix things */
  
  	/* write correct CRC and close file */
! 	if ((write(fd, &statefile_crc, sizeof(pg_crc32))) != sizeof(pg_crc32))
  	{
  		close(fd);
  		ereport(ERROR,
--- 1008,1014 ----
  	/* If we crash now, we have prepared: WAL replay will fix things */
  
  	/* write correct CRC and close file */
! 	if ((WriteAll(fd, &statefile_crc, sizeof(pg_crc32))) != sizeof(pg_crc32))
  	{
  		close(fd);
  		ereport(ERROR,
***************
*** 1371,1384 ****
  						path)));
  
  	/* Write content and CRC */
! 	if (write(fd, content, len) != len)
  	{
  		close(fd);
  		ereport(ERROR,
  				(errcode_for_file_access(),
  				 errmsg("could not write two-phase state file: %m")));
  	}
! 	if (write(fd, &statefile_crc, sizeof(pg_crc32)) != sizeof(pg_crc32))
  	{
  		close(fd);
  		ereport(ERROR,
--- 1372,1385 ----
  						path)));
  
  	/* Write content and CRC */
! 	if (WriteAll(fd, content, len) != len)
  	{
  		close(fd);
  		ereport(ERROR,
  				(errcode_for_file_access(),
  				 errmsg("could not write two-phase state file: %m")));
  	}
! 	if (WriteAll(fd, &statefile_crc, sizeof(pg_crc32)) != sizeof(pg_crc32))
  	{
  		close(fd);
  		ereport(ERROR,
diff -crNB upstream/postgresql-8.4.8//src/backend/access/transam/xlog.c trunk//src/backend/access/transam/xlog.c
*** upstream/postgresql-8.4.8//src/backend/access/transam/xlog.c	2011-04-15 13:17:14.000000000 +1000
--- trunk//src/backend/access/transam/xlog.c	2011-09-07 11:55:22.000000000 +1000
***************
*** 47,52 ****
--- 47,53 ----
  #include "storage/procarray.h"
  #include "storage/smgr.h"
  #include "storage/spin.h"
+ #include "storage/write.h"
  #include "utils/builtins.h"
  #include "utils/flatfiles.h"
  #include "utils/guc.h"
***************
*** 1644,1650 ****
  			from = XLogCtl->pages + startidx * (Size) XLOG_BLCKSZ;
  			nbytes = npages * (Size) XLOG_BLCKSZ;
  			errno = 0;
! 			if (write(openLogFile, from, nbytes) != nbytes)
  			{
  				/* if write didn't set errno, assume no disk space */
  				if (errno == 0)
--- 1645,1651 ----
  			from = XLogCtl->pages + startidx * (Size) XLOG_BLCKSZ;
  			nbytes = npages * (Size) XLOG_BLCKSZ;
  			errno = 0;
! 			if (WriteAll(openLogFile, from, nbytes) != nbytes)
  			{
  				/* if write didn't set errno, assume no disk space */
  				if (errno == 0)
***************
*** 2231,2237 ****
  	for (nbytes = 0; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ)
  	{
  		errno = 0;
! 		if ((int) write(fd, zbuffer, XLOG_BLCKSZ) != (int) XLOG_BLCKSZ)
  		{
  			int			save_errno = errno;
  
--- 2232,2238 ----
  	for (nbytes = 0; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ)
  	{
  		errno = 0;
! 		if ((int) WriteAll(fd, zbuffer, XLOG_BLCKSZ) != (int) XLOG_BLCKSZ)
  		{
  			int			save_errno = errno;
  
***************
*** 2364,2370 ****
  						(errmsg("not enough data in file \"%s\"", path)));
  		}
  		errno = 0;
! 		if ((int) write(fd, buffer, sizeof(buffer)) != (int) sizeof(buffer))
  		{
  			int			save_errno = errno;
  
--- 2365,2371 ----
  						(errmsg("not enough data in file \"%s\"", path)));
  		}
  		errno = 0;
! 		if ((int) WriteAll(fd, buffer, sizeof(buffer)) != (int) sizeof(buffer))
  		{
  			int			save_errno = errno;
  
***************
*** 4122,4128 ****
  			if (nbytes == 0)
  				break;
  			errno = 0;
! 			if ((int) write(fd, buffer, nbytes) != nbytes)
  			{
  				int			save_errno = errno;
  
--- 4123,4129 ----
  			if (nbytes == 0)
  				break;
  			errno = 0;
! 			if ((int) WriteAll(fd, buffer, nbytes) != nbytes)
  			{
  				int			save_errno = errno;
  
***************
*** 4164,4170 ****
  
  	nbytes = strlen(buffer);
  	errno = 0;
! 	if ((int) write(fd, buffer, nbytes) != nbytes)
  	{
  		int			save_errno = errno;
  
--- 4165,4171 ----
  
  	nbytes = strlen(buffer);
  	errno = 0;
! 	if ((int) WriteAll(fd, buffer, nbytes) != nbytes)
  	{
  		int			save_errno = errno;
  
***************
*** 4298,4304 ****
  						XLOG_CONTROL_FILE)));
  
  	errno = 0;
! 	if (write(fd, buffer, PG_CONTROL_SIZE) != PG_CONTROL_SIZE)
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
--- 4299,4305 ----
  						XLOG_CONTROL_FILE)));
  
  	errno = 0;
! 	if (WriteAll(fd, buffer, PG_CONTROL_SIZE) != PG_CONTROL_SIZE)
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
***************
*** 4523,4529 ****
  						XLOG_CONTROL_FILE)));
  
  	errno = 0;
! 	if (write(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
--- 4524,4530 ----
  						XLOG_CONTROL_FILE)));
  
  	errno = 0;
! 	if (WriteAll(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
***************
*** 4718,4724 ****
  
  	/* Write the first page with the initial record */
  	errno = 0;
! 	if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
--- 4719,4725 ----
  
  	/* Write the first page with the initial record */
  	errno = 0;
! 	if (WriteAll(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ)
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
diff -crNB upstream/postgresql-8.4.8//src/backend/storage/file/copydir.c trunk//src/backend/storage/file/copydir.c
*** upstream/postgresql-8.4.8//src/backend/storage/file/copydir.c	2011-04-15 13:17:14.000000000 +1000
--- trunk//src/backend/storage/file/copydir.c	2011-09-07 11:58:04.000000000 +1000
***************
*** 23,28 ****
--- 23,29 ----
  #include <sys/stat.h>
  
  #include "storage/fd.h"
+ #include "storage/write.h"
  #include "miscadmin.h"
  
  /*
***************
*** 145,151 ****
  		if (nbytes == 0)
  			break;
  		errno = 0;
! 		if ((int) write(dstfd, buffer, nbytes) != nbytes)
  		{
  			/* if write didn't set errno, assume problem is no disk space */
  			if (errno == 0)
--- 146,152 ----
  		if (nbytes == 0)
  			break;
  		errno = 0;
! 		if ((int) WriteAll(dstfd, buffer, nbytes) != nbytes)
  		{
  			/* if write didn't set errno, assume problem is no disk space */
  			if (errno == 0)
diff -crNB upstream/postgresql-8.4.8//src/backend/storage/file/fd.c trunk//src/backend/storage/file/fd.c
*** upstream/postgresql-8.4.8//src/backend/storage/file/fd.c	2011-04-15 13:17:14.000000000 +1000
--- trunk//src/backend/storage/file/fd.c	2011-09-07 11:59:33.000000000 +1000
***************
*** 54,59 ****
--- 54,60 ----
  #include "catalog/pg_tablespace.h"
  #include "storage/fd.h"
  #include "storage/ipc.h"
+ #include "storage/write.h"
  #include "utils/guc.h"
  #include "utils/resowner.h"
  
***************
*** 1204,1210 ****
  
  retry:
  	errno = 0;
! 	returnCode = write(VfdCache[file].fd, buffer, amount);
  
  	/* if write didn't set errno, assume problem is no disk space */
  	if (returnCode != amount && errno == 0)
--- 1205,1211 ----
  
  retry:
  	errno = 0;
! 	returnCode = WriteAll(VfdCache[file].fd, buffer, amount);
  
  	/* if write didn't set errno, assume problem is no disk space */
  	if (returnCode != amount && errno == 0)
diff -crNB upstream/postgresql-8.4.8//src/backend/storage/file/Makefile trunk//src/backend/storage/file/Makefile
*** upstream/postgresql-8.4.8//src/backend/storage/file/Makefile	2011-04-15 13:17:14.000000000 +1000
--- trunk//src/backend/storage/file/Makefile	2011-09-07 11:57:25.000000000 +1000
***************
*** 12,17 ****
  top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = fd.o buffile.o copydir.o
  
  include $(top_srcdir)/src/backend/common.mk
--- 12,17 ----
  top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = fd.o buffile.o copydir.o write.o
  
  include $(top_srcdir)/src/backend/common.mk
diff -crNB upstream/postgresql-8.4.8//src/backend/storage/file/write.c trunk//src/backend/storage/file/write.c
*** upstream/postgresql-8.4.8//src/backend/storage/file/write.c	1970-01-01 10:00:00.000000000 +1000
--- trunk//src/backend/storage/file/write.c	2011-09-07 11:57:45.000000000 +1000
***************
*** 0 ****
--- 1,46 ----
+ /*-------------------------------------------------------------------------
+  *
+  * write.h
+  *        write wrapper public interface declarations.
+  *
+  *
+  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * $ver:$
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #include "postgres.h"
+ #include "storage/write.h"
+ 
+ #include <unistd.h>
+ 
+ int WriteAll(int fd, const void *bytes, Size amount)
+ {
+ 	int returnCode;
+ 	int written;
+ 	
+ 	written = 0;
+ 
+ 	while (amount > 0)
+ 	{
+ 		returnCode = write(fd, bytes, amount);
+ 		if (returnCode < 0)
+ 			return -1;
+ 
+ 		/* Catche the case where theres no diskspace */
+ 		if (returnCode == 0 && errno == 0)
+ 		{
+ 			errno = ENOSPC;
+ 			return 0;
+ 		}
+ 
+ 		bytes = ConstPtrOffset(bytes, returnCode);
+ 		amount -= returnCode;
+ 		written += returnCode;
+ 	}
+ 
+ 	return written;
+ }
diff -crNB upstream/postgresql-8.4.8//src/backend/utils/init/miscinit.c trunk//src/backend/utils/init/miscinit.c
*** upstream/postgresql-8.4.8//src/backend/utils/init/miscinit.c	2011-04-15 13:17:14.000000000 +1000
--- trunk//src/backend/utils/init/miscinit.c	2011-09-07 12:06:00.000000000 +1000
***************
*** 38,43 ****
--- 38,44 ----
  #include "storage/pg_shmem.h"
  #include "storage/proc.h"
  #include "storage/procarray.h"
+ #include "storage/write.h"
  #include "utils/builtins.h"
  #include "utils/guc.h"
  #include "utils/syscache.h"
***************
*** 933,939 ****
  			 amPostmaster ? (int) my_pid : -((int) my_pid),
  			 DataDir);
  	errno = 0;
! 	if (write(fd, buffer, strlen(buffer)) != strlen(buffer))
  	{
  		int			save_errno = errno;
  
--- 934,940 ----
  			 amPostmaster ? (int) my_pid : -((int) my_pid),
  			 DataDir);
  	errno = 0;
! 	if (WriteAll(fd, buffer, strlen(buffer)) != strlen(buffer))
  	{
  		int			save_errno = errno;
  
***************
*** 1105,1111 ****
  	len = strlen(buffer);
  	errno = 0;
  	if (lseek(fd, (off_t) 0, SEEK_SET) != 0 ||
! 		(int) write(fd, buffer, len) != len)
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
--- 1106,1112 ----
  	len = strlen(buffer);
  	errno = 0;
  	if (lseek(fd, (off_t) 0, SEEK_SET) != 0 ||
! 		(int) WriteAll(fd, buffer, len) != len)
  	{
  		/* if write didn't set errno, assume problem is no disk space */
  		if (errno == 0)
diff -crNB upstream/postgresql-8.4.8//src/include/c.h trunk//src/include/c.h
*** upstream/postgresql-8.4.8//src/include/c.h	2011-04-15 13:17:14.000000000 +1000
--- trunk//src/include/c.h	2011-09-05 13:27:40.000000000 +1000
***************
*** 742,747 ****
--- 742,749 ----
  #define PG_TEXTDOMAIN(domain) (domain "-" PG_MAJORVERSION)
  #endif
  
+ /* Pointer increment macros for WriteAll */
+ #define ConstPtrOffset(ptr, amt) ((const void *) (((const unsigned char *) (ptr)) + (amt)))
  
  /* ----------------------------------------------------------------
   *				Section 8: system-specific hacks
diff -crNB upstream/postgresql-8.4.8//src/include/storage/write.h trunk//src/include/storage/write.h
*** upstream/postgresql-8.4.8//src/include/storage/write.h	1970-01-01 10:00:00.000000000 +1000
--- trunk//src/include/storage/write.h	2011-09-07 12:09:07.000000000 +1000
***************
*** 0 ****
--- 1,32 ----
+ /*-------------------------------------------------------------------------
+  *
+  * write.h
+  *        write wrapper public interface declarations.
+  *
+  *
+  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * $ver:$
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #ifndef WRITE_H
+ #define WRITE_H
+ 
+ #include "postgres.h"
+ #include "storage/write.h"
+ 
+ /*
+  * GNU libc will generally write all data when a write() is called.  According
+  * to the docs, this is not always the case as write() may return without 
+  * writing all data.  In this case, the return value will be the amount written.
+  * The remaining data should be written in a further write call.
+  *
+  * It is required to wrap write()s in a loop to ensure all data is correctly
+  * write.
+  */ 
+ int WriteAll(int fd, const void *bytes, Size amount);
+ 
+ #endif
