Message136431
diff --git a/Doc/library/os.rst b/Doc/library/os.rst
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -810,6 +810,35 @@
Availability: Unix, and Windows.
+.. function:: fullfsync(fd)
+
+ The POSIX standart requires that :c:func:`fsync` must transfer the buffered
+ data to the storage device, not that the data is actually written by the
+ device itself. It explicitely leaves it up to operating system implementors
+ whether users are given stronger guarantees on data integrity or not. Some
+ systems also offer special functions which overtake the part of making such
+ stronger guarantees, i.e., Mac OS X and NetBSD.
+
+ This non-standart function is *optionally* made available to access such
+ special functionality when feasible. It will force write of file buffers to
+ disk and the flush of disk caches of the file given by file descriptor *fd*.
+ To strive for best-possible data integrity, the following can be done::
+
+ # Force writeout of local buffer modifications
+ f.flush()
+ # Then synchronize the changes to physical backing store
+ if hasattr(os, 'fullfsync'):
+ os.fullfsync(f.fileno())
+ elif hasattr(os, 'fsync'):
+ os.fsync(f.fileno())
+
+ ..note::
+ Calling this function may take a long time, since it may block
+ until the disk reports that the transfer has been completed.
+
+ Availability: Unix.
+
+
.. function:: ftruncate(fd, length)
Truncate the file corresponding to file descriptor *fd*, so that it is at most
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -835,12 +835,12 @@
class TestInvalidFD(unittest.TestCase):
singles = ["fchdir", "dup", "fdopen", "fdatasync", "fstat",
- "fstatvfs", "fsync", "tcgetpgrp", "ttyname"]
+ "fstatvfs", "fsync", "fullfsync", "tcgetpgrp", "ttyname"]
#singles.append("close")
- #We omit close because it doesn'r raise an exception on some platforms
+ # We omit close because it doesn't raise an exception on some platforms
def get_single(f):
def helper(self):
- if hasattr(os, f):
+ if hasattr(os, f):
self.check(getattr(os, f))
return helper
for f in singles:
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -174,6 +174,11 @@
#endif /* ! __IBMC__ */
#ifndef _MSC_VER
+ /* os.fullfsync()? */
+# if (defined HAVE_FSYNC && ((defined __APPLE__ && defined F_FULLFSYNC) || \
+ (defined __NetBSD__ && defined FDISKSYNC)))
+# define PROVIDE_FULLFSYNC
+# endif
#if defined(__sgi)&&_COMPILER_VERSION>=700
/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
@@ -2129,6 +2134,41 @@
{
return posix_fildes(fdobj, fsync);
}
+
+# ifdef PROVIDE_FULLFSYNC
+PyDoc_STRVAR(fullfsync__doc__,
+"fullfsync(fd)\n\n"
+"force write of file buffers to disk, and the flush of disk caches\n"
+"of the file given by file descriptor fd.");
+
+static PyObject *
+fullfsync(PyObject *self, PyObject *fdobj)
+{
+ /* See issue 11877 discussion */
+ int res, fd = PyObject_AsFileDescriptor(fdobj);
+ if (fd < 0)
+ return NULL;
+ if (!_PyVerify_fd(fd))
+ return posix_error();
+
+ Py_BEGIN_ALLOW_THREADS
+# if defined __APPLE__
+ /* F_FULLFSYNC is not supported for all types of FDs/FSYSs;
+ * be on the safe side and test for inappropriate ioctl errors */
+ res = fcntl(fd, F_FULLFSYNC);
+ if (res < 0 && errno == ENOTTY)
+ res = fsync(fd);
+# elif defined __NetBSD__
+ res = fsync_range(fd, FFILESYNC | FDISKSYNC, 0, 0);
+# endif
+ Py_END_ALLOW_THREADS
+
+ if (res < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+# endif /* PROVIDE_FULLFSYNC */
#endif /* HAVE_FSYNC */
#ifdef HAVE_SYNC
@@ -9473,6 +9513,9 @@
#endif
#ifdef HAVE_FSYNC
{"fsync", posix_fsync, METH_O, posix_fsync__doc__},
+# ifdef PROVIDE_FULLFSYNC
+ {"fullfsync", fullfsync, METH_O, fullfsync__doc__},
+# endif
#endif
#ifdef HAVE_SYNC
{"sync", posix_sync, METH_NOARGS, posix_sync__doc__}, |
|
Date |
User |
Action |
Args |
2011-05-21 12:22:58 | sdaoden | set | recipients:
+ sdaoden, ronaldoussoren, pitrou, vstinner, nadeem.vawda, neologix, santoso.wijaya |
2011-05-21 12:22:52 | sdaoden | link | issue11877 messages |
2011-05-21 12:22:51 | sdaoden | create | |
|