Skip to content

Commit 43e1054

Browse files
committed
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)
1 parent 64e5995 commit 43e1054

9 files changed

Lines changed: 89 additions & 26 deletions

File tree

Doc/library/os.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,8 @@ Files and Directories
10141014
* :data:`stat.UF_APPEND`
10151015
* :data:`stat.UF_OPAQUE`
10161016
* :data:`stat.UF_NOUNLINK`
1017+
* :data:`stat.UF_COMPRESSED`
1018+
* :data:`stat.UF_HIDDEN`
10171019
* :data:`stat.SF_ARCHIVED`
10181020
* :data:`stat.SF_IMMUTABLE`
10191021
* :data:`stat.SF_APPEND`

Doc/library/stat.rst

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,13 +304,21 @@ The following flags can be used in the *flags* argument of :func:`os.chflags`:
304304

305305
The file may only be appended to.
306306

307+
.. data:: UF_OPAQUE
308+
309+
The directory is opaque when viewed through a union stack.
310+
307311
.. data:: UF_NOUNLINK
308312

309313
The file may not be renamed or deleted.
310314

311-
.. data:: UF_OPAQUE
315+
.. data:: UF_COMPRESSED
312316

313-
The directory is opaque when viewed through a union stack.
317+
The file is stored compressed (Mac OS X 10.6+).
318+
319+
.. data:: UF_HIDDEN
320+
321+
The file should not be displayed in a GUI (Mac OS X 10.5+).
314322

315323
.. data:: SF_ARCHIVED
316324

Lib/stat.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ def S_ISSOCK(mode):
8787
UF_APPEND = 0x00000004
8888
UF_OPAQUE = 0x00000008
8989
UF_NOUNLINK = 0x00000010
90+
UF_COMPRESSED = 0x00000020 # OS X: file is hfs-compressed
91+
UF_HIDDEN = 0x00008000 # OS X: file should not be displayed
9092
SF_ARCHIVED = 0x00010000
9193
SF_IMMUTABLE = 0x00020000
9294
SF_APPEND = 0x00040000

Lib/test/test_posix.py

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
import os
1212
import pwd
1313
import shutil
14+
import stat
1415
import sys
1516
import unittest
1617
import warnings
1718

19+
_DUMMY_SYMLINK = '%s/dummy-symlink' % os.getenv('TMPDIR', '/tmp')
1820

1921
warnings.filterwarnings('ignore', '.* potential security risk .*',
2022
RuntimeWarning)
@@ -25,9 +27,11 @@ def setUp(self):
2527
# create empty file
2628
fp = open(test_support.TESTFN, 'w+')
2729
fp.close()
30+
self.teardown_files = [ test_support.TESTFN ]
2831

2932
def tearDown(self):
30-
os.unlink(test_support.TESTFN)
33+
for teardown_file in self.teardown_files:
34+
os.unlink(teardown_file)
3135

3236
def testNoArgFunctions(self):
3337
# test posix functions which take no arguments and have
@@ -258,7 +262,7 @@ def test_fchown(self):
258262
def test_lchown(self):
259263
os.unlink(test_support.TESTFN)
260264
# create a symlink
261-
os.symlink('/tmp/dummy-symlink-target', test_support.TESTFN)
265+
os.symlink(_DUMMY_SYMLINK, test_support.TESTFN)
262266
self._test_all_chown_common(posix.lchown, test_support.TESTFN)
263267

264268
def test_chdir(self):
@@ -315,17 +319,49 @@ def test_utime(self):
315319
posix.utime(test_support.TESTFN, (int(now), int(now)))
316320
posix.utime(test_support.TESTFN, (now, now))
317321

322+
def _test_chflags_regular_file(self, chflags_func, target_file):
323+
st = os.stat(target_file)
324+
self.assertTrue(hasattr(st, 'st_flags'))
325+
chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
326+
try:
327+
new_st = os.stat(target_file)
328+
self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
329+
try:
330+
fd = open(target_file, 'w+')
331+
except IOError as e:
332+
self.assertEqual(e.errno, errno.EPERM)
333+
finally:
334+
posix.chflags(target_file, st.st_flags)
335+
336+
@unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
318337
def test_chflags(self):
319-
if hasattr(posix, 'chflags'):
320-
st = os.stat(test_support.TESTFN)
321-
if hasattr(st, 'st_flags'):
322-
posix.chflags(test_support.TESTFN, st.st_flags)
323-
324-
def test_lchflags(self):
325-
if hasattr(posix, 'lchflags'):
326-
st = os.stat(test_support.TESTFN)
327-
if hasattr(st, 'st_flags'):
328-
posix.lchflags(test_support.TESTFN, st.st_flags)
338+
self._test_chflags_regular_file(posix.chflags, test_support.TESTFN)
339+
340+
@unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
341+
def test_lchflags_regular_file(self):
342+
self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN)
343+
344+
@unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
345+
def test_lchflags_symlink(self):
346+
testfn_st = os.stat(test_support.TESTFN)
347+
348+
self.assertTrue(hasattr(testfn_st, 'st_flags'))
349+
350+
os.symlink(test_support.TESTFN, _DUMMY_SYMLINK)
351+
self.teardown_files.append(_DUMMY_SYMLINK)
352+
dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
353+
354+
posix.lchflags(_DUMMY_SYMLINK,
355+
dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
356+
try:
357+
new_testfn_st = os.stat(test_support.TESTFN)
358+
new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
359+
360+
self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
361+
self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
362+
new_dummy_symlink_st.st_flags)
363+
finally:
364+
posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
329365

330366
def test_getcwd_long_pathnames(self):
331367
if hasattr(posix, 'getcwd'):

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ Geremy Condra
162162
Juan José Conti
163163
Matt Conway
164164
David M. Cooke
165+
Garrett Cooper
165166
Greg Copeland
166167
Aldo Cortesi
167168
David Costanzo

Misc/NEWS

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,20 @@ Library
5353
constructor has failed, e.g. because of an undeclared keyword argument. Patch
5454
written by Oleg Oshmyan.
5555

56+
Build
57+
-----
58+
59+
- Issue #8746: Correct faulty configure checks so that os.chflags() and
60+
os.lchflags() are once again built on systems that support these
61+
functions (*BSD and OS X). Also add new stat file flags for OS X
62+
(UF_HIDDEN and UF_COMPRESSED).
63+
5664
Tests
5765
-----
5866

67+
- Issue #8746: Add additional tests for os.chflags() and os.lchflags().
68+
Patch by Garrett Cooper.
69+
5970
- Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9
6071
on Mac OS X. (Patch by Ronald Oussoren)
6172

configure

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10073,7 +10073,7 @@ else
1007310073
else
1007410074
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
1007510075
/* end confdefs.h. */
10076-
[
10076+
1007710077
#include <sys/stat.h>
1007810078
#include <unistd.h>
1007910079
int main(int argc, char*argv[])
@@ -10082,7 +10082,7 @@ int main(int argc, char*argv[])
1008210082
return 1;
1008310083
return 0;
1008410084
}
10085-
]
10085+
1008610086
_ACEOF
1008710087
if ac_fn_c_try_run "$LINENO"; then :
1008810088
ac_cv_have_chflags=yes
@@ -10122,7 +10122,7 @@ else
1012210122
else
1012310123
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
1012410124
/* end confdefs.h. */
10125-
[
10125+
1012610126
#include <sys/stat.h>
1012710127
#include <unistd.h>
1012810128
int main(int argc, char*argv[])
@@ -10131,7 +10131,7 @@ int main(int argc, char*argv[])
1013110131
return 1;
1013210132
return 0;
1013310133
}
10134-
]
10134+
1013510135
_ACEOF
1013610136
if ac_fn_c_try_run "$LINENO"; then :
1013710137
ac_cv_have_lchflags=yes

configure.in

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2839,7 +2839,7 @@ AC_CHECK_LIB(c, inet_aton, [$ac_cv_prog_TRUE],
28392839
# On Tru64, chflags seems to be present, but calling it will
28402840
# exit Python
28412841
AC_CACHE_CHECK([for chflags], [ac_cv_have_chflags], [dnl
2842-
AC_RUN_IFELSE([AC_LANG_SOURCE([[[
2842+
AC_RUN_IFELSE([AC_LANG_SOURCE([[
28432843
#include <sys/stat.h>
28442844
#include <unistd.h>
28452845
int main(int argc, char*argv[])
@@ -2848,7 +2848,7 @@ int main(int argc, char*argv[])
28482848
return 1;
28492849
return 0;
28502850
}
2851-
]]])],
2851+
]])],
28522852
[ac_cv_have_chflags=yes],
28532853
[ac_cv_have_chflags=no],
28542854
[ac_cv_have_chflags=cross])
@@ -2857,11 +2857,11 @@ if test "$ac_cv_have_chflags" = cross ; then
28572857
AC_CHECK_FUNC([chflags], [ac_cv_have_chflags="yes"], [ac_cv_have_chflags="no"])
28582858
fi
28592859
if test "$ac_cv_have_chflags" = yes ; then
2860-
AC_DEFINE(HAVE_CHFLAGS, 1, [Define to 1 if you have the `chflags' function.])
2860+
AC_DEFINE(HAVE_CHFLAGS, 1, [Define to 1 if you have the 'chflags' function.])
28612861
fi
28622862

28632863
AC_CACHE_CHECK([for lchflags], [ac_cv_have_lchflags], [dnl
2864-
AC_RUN_IFELSE([AC_LANG_SOURCE([[[
2864+
AC_RUN_IFELSE([AC_LANG_SOURCE([[
28652865
#include <sys/stat.h>
28662866
#include <unistd.h>
28672867
int main(int argc, char*argv[])
@@ -2870,13 +2870,13 @@ int main(int argc, char*argv[])
28702870
return 1;
28712871
return 0;
28722872
}
2873-
]]])],[ac_cv_have_lchflags=yes],[ac_cv_have_lchflags=no],[ac_cv_have_lchflags=cross])
2873+
]])],[ac_cv_have_lchflags=yes],[ac_cv_have_lchflags=no],[ac_cv_have_lchflags=cross])
28742874
])
28752875
if test "$ac_cv_have_lchflags" = cross ; then
28762876
AC_CHECK_FUNC([lchflags], [ac_cv_have_lchflags="yes"], [ac_cv_have_lchflags="no"])
28772877
fi
28782878
if test "$ac_cv_have_lchflags" = yes ; then
2879-
AC_DEFINE(HAVE_LCHFLAGS, 1, [Define to 1 if you have the `lchflags' function.])
2879+
AC_DEFINE(HAVE_LCHFLAGS, 1, [Define to 1 if you have the 'lchflags' function.])
28802880
fi
28812881

28822882
dnl Check if system zlib has *Copy() functions

pyconfig.h.in

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
/* Define this if you have the type _Bool. */
101101
#undef HAVE_C99_BOOL
102102

103-
/* Define to 1 if you have the `chflags' function. */
103+
/* Define to 1 if you have the 'chflags' function. */
104104
#undef HAVE_CHFLAGS
105105

106106
/* Define to 1 if you have the `chown' function. */
@@ -391,7 +391,7 @@
391391
Solaris and Linux, the necessary defines are already defined.) */
392392
#undef HAVE_LARGEFILE_SUPPORT
393393

394-
/* Define to 1 if you have the `lchflags' function. */
394+
/* Define to 1 if you have the 'lchflags' function. */
395395
#undef HAVE_LCHFLAGS
396396

397397
/* Define to 1 if you have the `lchmod' function. */
@@ -1137,6 +1137,9 @@
11371137
/* This must be defined on some systems to enable large file support. */
11381138
#undef _LARGEFILE_SOURCE
11391139

1140+
/* This must be defined on AIX systems to enable large file support. */
1141+
#undef _LARGE_FILES
1142+
11401143
/* Define to 1 if on MINIX. */
11411144
#undef _MINIX
11421145

0 commit comments

Comments
 (0)