5a6,11 > # Look at http://bugs.python.org/issue17913 > # http://bugs.python.org/issue17924 > > # view Lib/stat.py @ 84234:f32dad3a243e > # http://hg.python.org/cpython/file/f32dad3a243e/Lib/stat.py > 22,24c28 < """Return the portion of the file's mode that can be set by < os.chmod(). < """ --- > """Return the portion of the file's mode that can be set by os.chmod().""" 28,30c32 < """Return the portion of the file's mode that describes the < file type. < """ --- > """Return the portion of the file's mode that describes the file type.""" 36,42c38,45 < S_IFDIR = 0o040000 # directory < S_IFCHR = 0o020000 # character device < S_IFBLK = 0o060000 # block device < S_IFREG = 0o100000 # regular file < S_IFIFO = 0o010000 # fifo (named pipe) < S_IFLNK = 0o120000 # symbolic link < S_IFSOCK = 0o140000 # socket file --- > S_IFIFO = 0o010000 # fifo (named pipe) > S_IFCHR = 0o020000 # character device > S_IFDIR = 0o040000 # directory > S_IFBLK = 0o060000 # block device > S_IFREG = 0o100000 # regular file > S_IFLNK = 0o120000 # symbolic link > S_IFSOCK = 0o140000 # socket file > S_IFGIT = 0o160000 # git link 73a77,80 > def S_ISGIT(mode): > """Return True if mode is from a GIT special file.""" > return S_IFMT(mode) == S_IFGIT > 76,94c83,101 < S_ISUID = 0o4000 # set UID bit < S_ISGID = 0o2000 # set GID bit < S_ENFMT = S_ISGID # file locking enforcement < S_ISVTX = 0o1000 # sticky bit < S_IREAD = 0o0400 # Unix V7 synonym for S_IRUSR < S_IWRITE = 0o0200 # Unix V7 synonym for S_IWUSR < S_IEXEC = 0o0100 # Unix V7 synonym for S_IXUSR < S_IRWXU = 0o0700 # mask for owner permissions < S_IRUSR = 0o0400 # read by owner < S_IWUSR = 0o0200 # write by owner < S_IXUSR = 0o0100 # execute by owner < S_IRWXG = 0o0070 # mask for group permissions < S_IRGRP = 0o0040 # read by group < S_IWGRP = 0o0020 # write by group < S_IXGRP = 0o0010 # execute by group < S_IRWXO = 0o0007 # mask for others (not in group) permissions < S_IROTH = 0o0004 # read by others < S_IWOTH = 0o0002 # write by others < S_IXOTH = 0o0001 # execute by others --- > S_ISUID = 0o4000 # set UID bit > S_ISGID = 0o2000 # set GID bit > S_ENFMT = S_ISGID # file locking enforcement > S_ISVTX = 0o1000 # sticky bit > S_IREAD = 0o0400 # Unix V7 synonym for S_IRUSR > S_IWRITE = 0o0200 # Unix V7 synonym for S_IWUSR > S_IEXEC = 0o0100 # Unix V7 synonym for S_IXUSR > S_IRWXU = 0o0700 # mask for owner permissions > S_IRUSR = 0o0400 # read by owner > S_IWUSR = 0o0200 # write by owner > S_IXUSR = 0o0100 # execute by owner > S_IRWXG = 0o0070 # mask for group permissions > S_IRGRP = 0o0040 # read by group > S_IWGRP = 0o0020 # write by group > S_IXGRP = 0o0010 # execute by group > S_IRWXO = 0o0007 # mask for others (not in group) permissions > S_IROTH = 0o0004 # read by others > S_IWOTH = 0o0002 # write by others > S_IXOTH = 0o0001 # execute by others 98,102c105,109 < UF_NODUMP = 0x00000001 # do not dump file < UF_IMMUTABLE = 0x00000002 # file may not be changed < UF_APPEND = 0x00000004 # file may only be appended to < UF_OPAQUE = 0x00000008 # directory is opaque when viewed through a union stack < UF_NOUNLINK = 0x00000010 # file may not be renamed or deleted --- > UF_NODUMP = 0x00000001 # do not dump file > UF_IMMUTABLE = 0x00000002 # file may not be changed > UF_APPEND = 0x00000004 # file may only be appended to > UF_OPAQUE = 0x00000008 # directory is opaque when viewed through a union stack > UF_NOUNLINK = 0x00000010 # file may not be renamed or deleted 104,149c111,264 < UF_HIDDEN = 0x00008000 # OS X: file should not be displayed < SF_ARCHIVED = 0x00010000 # file may be archived < SF_IMMUTABLE = 0x00020000 # file may not be changed < SF_APPEND = 0x00040000 # file may only be appended to < SF_NOUNLINK = 0x00100000 # file may not be renamed or deleted < SF_SNAPSHOT = 0x00200000 # file is a snapshot file < < < _filemode_table = ( < ((S_IFLNK, "l"), < (S_IFREG, "-"), < (S_IFBLK, "b"), < (S_IFDIR, "d"), < (S_IFCHR, "c"), < (S_IFIFO, "p")), < < ((S_IRUSR, "r"),), < ((S_IWUSR, "w"),), < ((S_IXUSR|S_ISUID, "s"), < (S_ISUID, "S"), < (S_IXUSR, "x")), < < ((S_IRGRP, "r"),), < ((S_IWGRP, "w"),), < ((S_IXGRP|S_ISGID, "s"), < (S_ISGID, "S"), < (S_IXGRP, "x")), < < ((S_IROTH, "r"),), < ((S_IWOTH, "w"),), < ((S_IXOTH|S_ISVTX, "t"), < (S_ISVTX, "T"), < (S_IXOTH, "x")) < ) < < def filemode(mode): < """Convert a file's mode to a string of the form '-rwxrwxrwx'.""" < perm = [] < for table in _filemode_table: < for bit, char in table: < if mode & bit == bit: < perm.append(char) < break < else: < perm.append("-") < return "".join(perm) --- > UF_HIDDEN = 0x00008000 # OS X: file should not be displayed > SF_ARCHIVED = 0x00010000 # file may be archived > SF_IMMUTABLE = 0x00020000 # file may not be changed > SF_APPEND = 0x00040000 # file may only be appended to > SF_NOUNLINK = 0x00100000 # file may not be renamed or deleted > SF_SNAPSHOT = 0x00200000 # file is a snapshot file > > # Functions and tables to convert a numeric file mode to the common unix > # symbolic string representation of the mode. > > __valid_ifmts = set([0]) > __mode2prefix = {} > __prefix2mode = { > 'g': S_IFGIT, > 's': S_IFSOCK, > 'l': S_IFLNK, > '-': S_IFREG, > 'b': S_IFBLK, > 'd': S_IFDIR, > 'c': S_IFCHR, > 'p': S_IFIFO, > } > def __create_mappings(): > # Create the lookup tables for chars to and from file mode numbers > check = set([]) > for char, mode in __prefix2mode.items(): > assert mode not in check > check.add(mode) > __mode2prefix[mode] = char > __valid_ifmts.add(mode >> (3*4)) > # Check that we have included all the file modes defined in this module. > defined = [v for k, v in globals().items() if k[:4] == 'S_IF' and > isinstance(v, int)] > assert set(defined) == check > __create_mappings() > > def is_mode_valid(mode): > """Test whether a given number is a valid file mode number.""" > ifmt = S_IFMT(mode) > check1 = 0 <= mode ^ ifmt <= 0o7777 > check2 = ifmt >> (3*4) in __valid_ifmts > return check1 and check2 > > def __perm_byte_to_str(byte): > assert 0 <= byte <= 0b111 > bits = [] > mask = 0b100 > for char in 'rwx': > bit = char if mask & byte else '-' > bits.append(bit) > mask >>= 1 > return bits > > def mode2str(mode): > """Return the standard unix permission string representation of a file > mode. > > >>> mode2str(0755) > '-rwxr-xr-x' > >>> mode2str(755) > '--wxrw--wt' > >>> mode2str(0120640) > 'lrw-r-----' > >>> mode2str(5806) > 'p-w-r-srwT' > """ > assert is_mode_valid(mode) > > filemode = S_IFMT(mode) > try: > prefix = '-' if not filemode else __mode2prefix[filemode] > except KeyError: > print 'Unrecognised file type/mode:', oct(filemode) > raise > prefix = '-' > > perm_bytes = [] > for i in xrange(4): > perm_bytes.append(__perm_byte_to_str(mode & 7)) > mode >>= 3 > > special = perm_bytes.pop() > perm_bytes.reverse() > > for i, attrs in enumerate(zip(special, 'sst')): > bit, char = attrs > if bit == '-': continue > if perm_bytes[i][2] == '-': > char = char.upper() > perm_bytes[i][2] = char > > perm_bytes = [''.join(b) for b in perm_bytes] > return prefix + ''.join(perm_bytes) > > def str2mode(str_mode): > """Return the numeric file mode of a unix file permission string. > > >>> str2mode('l-w-r-srwT') > 42670 > >>> oct(str2mode('lrw-r-----')) > '0120640' > """ > assert len(str_mode) == 10 > prefix = str_mode[0] > try: > file_mode = __prefix2mode[prefix] > except KeyError: > print "Unrecognised file mode prefix '%s'." % prefix > raise > file_mode = prefix_mode['-'] > > mode = 0 > factor = 2**8 > for i, char in enumerate(str_mode[1:]): > > if char == '-': > factor >>= 1 > continue > > if char in 'rwxst': > mode += factor > > low = char.lower() > if low == 's': > assert i in [2, 5] > if i == 2: > mode += S_ISUID > else: > mode += S_ISGID > elif low == 't': > mode += S_ISVTX > > factor >>= 1 > > assert 0 <= mode <= 0o7777 > assert factor == 0 > return file_mode + mode > > def __test_perm_bits(debug=False): > bases = [0] + sorted(__mode2prefix.keys()) > for b in bases: > for i in xrange(b, b + 0o7777 + 1): > oct_mode = oct(i).zfill(7) > str_mode = mode2str(i) > if debug: > print str(i).rjust(5)+':', oct(i).zfill(7), str_mode, > check = str2mode(str_mode) > if debug: print check > if i <= 0o7777: > check = S_IMODE(check) > assert check == i > > if __name__ == '__main__': > __test_perm_bits(debug=True)