Issue #8746: Correct faulty configure checks so that os.chflags() and

os.lchflags() are once again built on systems that support these
functions (*BSD and OS X).  Also add new stat file flags for OS X
(UF_HIDDEN and UF_COMPRESSED).  Also add additional tests for
os.chflags() and os.lchflags(). (Tests by Garrett Cooper)
This commit is contained in:
Ned Deily 2011-06-28 00:00:28 -07:00
parent 11f00f3b00
commit 3eb67d58d6
9 changed files with 85 additions and 26 deletions

View File

@ -989,6 +989,8 @@ Files and Directories
* :data:`stat.UF_APPEND` * :data:`stat.UF_APPEND`
* :data:`stat.UF_OPAQUE` * :data:`stat.UF_OPAQUE`
* :data:`stat.UF_NOUNLINK` * :data:`stat.UF_NOUNLINK`
* :data:`stat.UF_COMPRESSED`
* :data:`stat.UF_HIDDEN`
* :data:`stat.SF_ARCHIVED` * :data:`stat.SF_ARCHIVED`
* :data:`stat.SF_IMMUTABLE` * :data:`stat.SF_IMMUTABLE`
* :data:`stat.SF_APPEND` * :data:`stat.SF_APPEND`

View File

@ -307,13 +307,21 @@ The following flags can be used in the *flags* argument of :func:`os.chflags`:
The file may only be appended to. The file may only be appended to.
.. data:: UF_OPAQUE
The directory is opaque when viewed through a union stack.
.. data:: UF_NOUNLINK .. data:: UF_NOUNLINK
The file may not be renamed or deleted. The file may not be renamed or deleted.
.. data:: UF_OPAQUE .. data:: UF_COMPRESSED
The directory is opaque when viewed through a union stack. The file is stored compressed (Mac OS X 10.6+).
.. data:: UF_HIDDEN
The file should not be displayed in a GUI (Mac OS X 10.5+).
.. data:: SF_ARCHIVED .. data:: SF_ARCHIVED

View File

@ -87,6 +87,8 @@ UF_IMMUTABLE = 0x00000002
UF_APPEND = 0x00000004 UF_APPEND = 0x00000004
UF_OPAQUE = 0x00000008 UF_OPAQUE = 0x00000008
UF_NOUNLINK = 0x00000010 UF_NOUNLINK = 0x00000010
UF_COMPRESSED = 0x00000020 # OS X: file is hfs-compressed
UF_HIDDEN = 0x00008000 # OS X: file should not be displayed
SF_ARCHIVED = 0x00010000 SF_ARCHIVED = 0x00010000
SF_IMMUTABLE = 0x00020000 SF_IMMUTABLE = 0x00020000
SF_APPEND = 0x00040000 SF_APPEND = 0x00040000

View File

@ -15,6 +15,7 @@ import stat
import unittest import unittest
import warnings import warnings
_DUMMY_SYMLINK = '%s/dummy-symlink' % os.getenv('TMPDIR', '/tmp')
class PosixTester(unittest.TestCase): class PosixTester(unittest.TestCase):
@ -22,13 +23,15 @@ class PosixTester(unittest.TestCase):
# create empty file # create empty file
fp = open(support.TESTFN, 'w+') fp = open(support.TESTFN, 'w+')
fp.close() fp.close()
self.teardown_files = [ support.TESTFN ]
self._warnings_manager = support.check_warnings() self._warnings_manager = support.check_warnings()
self._warnings_manager.__enter__() self._warnings_manager.__enter__()
warnings.filterwarnings('ignore', '.* potential security risk .*', warnings.filterwarnings('ignore', '.* potential security risk .*',
RuntimeWarning) RuntimeWarning)
def tearDown(self): def tearDown(self):
support.unlink(support.TESTFN) for teardown_file in self.teardown_files:
support.unlink(teardown_file)
self._warnings_manager.__exit__(None, None, None) self._warnings_manager.__exit__(None, None, None)
def testNoArgFunctions(self): def testNoArgFunctions(self):
@ -268,7 +271,7 @@ class PosixTester(unittest.TestCase):
def test_lchown(self): def test_lchown(self):
os.unlink(support.TESTFN) os.unlink(support.TESTFN)
# create a symlink # create a symlink
os.symlink('/tmp/dummy-symlink-target', support.TESTFN) os.symlink(_DUMMY_SYMLINK, support.TESTFN)
self._test_all_chown_common(posix.lchown, support.TESTFN) self._test_all_chown_common(posix.lchown, support.TESTFN)
def test_chdir(self): def test_chdir(self):
@ -315,17 +318,49 @@ class PosixTester(unittest.TestCase):
posix.utime(support.TESTFN, (int(now), int(now))) posix.utime(support.TESTFN, (int(now), int(now)))
posix.utime(support.TESTFN, (now, now)) posix.utime(support.TESTFN, (now, now))
def test_chflags(self): def _test_chflags_regular_file(self, chflags_func, target_file):
if hasattr(posix, 'chflags'): st = os.stat(target_file)
st = os.stat(support.TESTFN) self.assertTrue(hasattr(st, 'st_flags'))
if hasattr(st, 'st_flags'): chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
posix.chflags(support.TESTFN, st.st_flags) try:
new_st = os.stat(target_file)
self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
try:
fd = open(target_file, 'w+')
except IOError as e:
self.assertEqual(e.errno, errno.EPERM)
finally:
posix.chflags(target_file, st.st_flags)
def test_lchflags(self): @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
if hasattr(posix, 'lchflags'): def test_chflags(self):
st = os.stat(support.TESTFN) self._test_chflags_regular_file(posix.chflags, support.TESTFN)
if hasattr(st, 'st_flags'):
posix.lchflags(support.TESTFN, st.st_flags) @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
def test_lchflags_regular_file(self):
self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
@unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
def test_lchflags_symlink(self):
testfn_st = os.stat(support.TESTFN)
self.assertTrue(hasattr(testfn_st, 'st_flags'))
os.symlink(support.TESTFN, _DUMMY_SYMLINK)
self.teardown_files.append(_DUMMY_SYMLINK)
dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
posix.lchflags(_DUMMY_SYMLINK,
dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
try:
new_testfn_st = os.stat(support.TESTFN)
new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
new_dummy_symlink_st.st_flags)
finally:
posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
def test_environ(self): def test_environ(self):
if os.name == "nt": if os.name == "nt":

View File

@ -181,6 +181,7 @@ Juan José Conti
Matt Conway Matt Conway
David M. Cooke David M. Cooke
Jason R. Coombs Jason R. Coombs
Garrett Cooper
Greg Copeland Greg Copeland
Aldo Cortesi Aldo Cortesi
David Costanzo David Costanzo

View File

@ -99,6 +99,11 @@ Extension Modules
Build Build
----- -----
- Issue #8746: Correct faulty configure checks so that os.chflags() and
os.lchflags() are once again built on systems that support these
functions (*BSD and OS X). Also add new stat file flags for OS X
(UF_HIDDEN and UF_COMPRESSED).
- Issue #11217: For 64-bit/32-bit Mac OS X universal framework builds, - Issue #11217: For 64-bit/32-bit Mac OS X universal framework builds,
ensure "make install" creates symlinks in --prefix bin for the "-32" ensure "make install" creates symlinks in --prefix bin for the "-32"
files in the framework bin directory like the installer does. files in the framework bin directory like the installer does.
@ -106,6 +111,9 @@ Build
Tests Tests
----- -----
- Issue #8746: Add additional tests for os.chflags() and os.lchflags().
Patch by Garrett Cooper.
- Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9 - Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9
on Mac OS X. (Patch by Ronald Oussoren) on Mac OS X. (Patch by Ronald Oussoren)

8
configure vendored
View File

@ -9877,7 +9877,7 @@ else
else else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */ /* end confdefs.h. */
[
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
int main(int argc, char*argv[]) int main(int argc, char*argv[])
@ -9886,7 +9886,7 @@ int main(int argc, char*argv[])
return 1; return 1;
return 0; return 0;
} }
]
_ACEOF _ACEOF
if ac_fn_c_try_run "$LINENO"; then : if ac_fn_c_try_run "$LINENO"; then :
ac_cv_have_chflags=yes ac_cv_have_chflags=yes
@ -9926,7 +9926,7 @@ else
else else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */ /* end confdefs.h. */
[
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
int main(int argc, char*argv[]) int main(int argc, char*argv[])
@ -9935,7 +9935,7 @@ int main(int argc, char*argv[])
return 1; return 1;
return 0; return 0;
} }
]
_ACEOF _ACEOF
if ac_fn_c_try_run "$LINENO"; then : if ac_fn_c_try_run "$LINENO"; then :
ac_cv_have_lchflags=yes ac_cv_have_lchflags=yes

View File

@ -2689,7 +2689,7 @@ AC_CHECK_LIB(c, inet_aton, [$ac_cv_prog_TRUE],
# On Tru64, chflags seems to be present, but calling it will # On Tru64, chflags seems to be present, but calling it will
# exit Python # exit Python
AC_CACHE_CHECK([for chflags], [ac_cv_have_chflags], [dnl AC_CACHE_CHECK([for chflags], [ac_cv_have_chflags], [dnl
AC_RUN_IFELSE([AC_LANG_SOURCE([[[ AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
int main(int argc, char*argv[]) int main(int argc, char*argv[])
@ -2698,7 +2698,7 @@ int main(int argc, char*argv[])
return 1; return 1;
return 0; return 0;
} }
]]])], ]])],
[ac_cv_have_chflags=yes], [ac_cv_have_chflags=yes],
[ac_cv_have_chflags=no], [ac_cv_have_chflags=no],
[ac_cv_have_chflags=cross]) [ac_cv_have_chflags=cross])
@ -2707,11 +2707,11 @@ if test "$ac_cv_have_chflags" = cross ; then
AC_CHECK_FUNC([chflags], [ac_cv_have_chflags="yes"], [ac_cv_have_chflags="no"]) AC_CHECK_FUNC([chflags], [ac_cv_have_chflags="yes"], [ac_cv_have_chflags="no"])
fi fi
if test "$ac_cv_have_chflags" = yes ; then if test "$ac_cv_have_chflags" = yes ; then
AC_DEFINE(HAVE_CHFLAGS, 1, [Define to 1 if you have the `chflags' function.]) AC_DEFINE(HAVE_CHFLAGS, 1, [Define to 1 if you have the 'chflags' function.])
fi fi
AC_CACHE_CHECK([for lchflags], [ac_cv_have_lchflags], [dnl AC_CACHE_CHECK([for lchflags], [ac_cv_have_lchflags], [dnl
AC_RUN_IFELSE([AC_LANG_SOURCE([[[ AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
int main(int argc, char*argv[]) int main(int argc, char*argv[])
@ -2720,13 +2720,13 @@ int main(int argc, char*argv[])
return 1; return 1;
return 0; return 0;
} }
]]])],[ac_cv_have_lchflags=yes],[ac_cv_have_lchflags=no],[ac_cv_have_lchflags=cross]) ]])],[ac_cv_have_lchflags=yes],[ac_cv_have_lchflags=no],[ac_cv_have_lchflags=cross])
]) ])
if test "$ac_cv_have_lchflags" = cross ; then if test "$ac_cv_have_lchflags" = cross ; then
AC_CHECK_FUNC([lchflags], [ac_cv_have_lchflags="yes"], [ac_cv_have_lchflags="no"]) AC_CHECK_FUNC([lchflags], [ac_cv_have_lchflags="yes"], [ac_cv_have_lchflags="no"])
fi fi
if test "$ac_cv_have_lchflags" = yes ; then if test "$ac_cv_have_lchflags" = yes ; then
AC_DEFINE(HAVE_LCHFLAGS, 1, [Define to 1 if you have the `lchflags' function.]) AC_DEFINE(HAVE_LCHFLAGS, 1, [Define to 1 if you have the 'lchflags' function.])
fi fi
dnl Check if system zlib has *Copy() functions dnl Check if system zlib has *Copy() functions

View File

@ -101,7 +101,7 @@
/* Define this if you have the type _Bool. */ /* Define this if you have the type _Bool. */
#undef HAVE_C99_BOOL #undef HAVE_C99_BOOL
/* Define to 1 if you have the `chflags' function. */ /* Define to 1 if you have the 'chflags' function. */
#undef HAVE_CHFLAGS #undef HAVE_CHFLAGS
/* Define to 1 if you have the `chown' function. */ /* Define to 1 if you have the `chown' function. */
@ -395,7 +395,7 @@
Solaris and Linux, the necessary defines are already defined.) */ Solaris and Linux, the necessary defines are already defined.) */
#undef HAVE_LARGEFILE_SUPPORT #undef HAVE_LARGEFILE_SUPPORT
/* Define to 1 if you have the `lchflags' function. */ /* Define to 1 if you have the 'lchflags' function. */
#undef HAVE_LCHFLAGS #undef HAVE_LCHFLAGS
/* Define to 1 if you have the `lchmod' function. */ /* Define to 1 if you have the `lchmod' function. */
@ -1152,6 +1152,9 @@
/* This must be defined on some systems to enable large file support. */ /* This must be defined on some systems to enable large file support. */
#undef _LARGEFILE_SOURCE #undef _LARGEFILE_SOURCE
/* This must be defined on AIX systems to enable large file support. */
#undef _LARGE_FILES
/* Define to 1 if on MINIX. */ /* Define to 1 if on MINIX. */
#undef _MINIX #undef _MINIX