Mercurial > public > mercurial-scm > hg
comparison mercurial/pure/osutil.py @ 32512:0e8b0b9a7acc
cffi: split modules from pure
The copyright lines are updated per change history.
cffi/osutil.py isn't tested since I have no access to OS X machine right now,
sorry.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Tue, 02 May 2017 21:15:31 +0900 |
parents | 2dcb3d52ef41 |
children | 75979c8d4572 |
comparison
equal
deleted
inserted
replaced
32511:2e431fb98c6b | 32512:0e8b0b9a7acc |
---|---|
12 import os | 12 import os |
13 import socket | 13 import socket |
14 import stat as statmod | 14 import stat as statmod |
15 | 15 |
16 from .. import ( | 16 from .. import ( |
17 policy, | |
18 pycompat, | 17 pycompat, |
19 ) | 18 ) |
20 | |
21 modulepolicy = policy.policy | |
22 policynocffi = policy.policynocffi | |
23 | 19 |
24 def _mode_to_kind(mode): | 20 def _mode_to_kind(mode): |
25 if statmod.S_ISREG(mode): | 21 if statmod.S_ISREG(mode): |
26 return statmod.S_IFREG | 22 return statmod.S_IFREG |
27 if statmod.S_ISDIR(mode): | 23 if statmod.S_ISDIR(mode): |
36 return statmod.S_IFIFO | 32 return statmod.S_IFIFO |
37 if statmod.S_ISSOCK(mode): | 33 if statmod.S_ISSOCK(mode): |
38 return statmod.S_IFSOCK | 34 return statmod.S_IFSOCK |
39 return mode | 35 return mode |
40 | 36 |
41 def listdirpure(path, stat=False, skip=None): | 37 def listdir(path, stat=False, skip=None): |
42 '''listdir(path, stat=False) -> list_of_tuples | 38 '''listdir(path, stat=False) -> list_of_tuples |
43 | 39 |
44 Return a sorted list containing information about the entries | 40 Return a sorted list containing information about the entries |
45 in the directory. | 41 in the directory. |
46 | 42 |
65 if stat: | 61 if stat: |
66 result.append((fn, _mode_to_kind(st.st_mode), st)) | 62 result.append((fn, _mode_to_kind(st.st_mode), st)) |
67 else: | 63 else: |
68 result.append((fn, _mode_to_kind(st.st_mode))) | 64 result.append((fn, _mode_to_kind(st.st_mode))) |
69 return result | 65 return result |
70 | |
71 ffi = None | |
72 if modulepolicy not in policynocffi and pycompat.sysplatform == 'darwin': | |
73 try: | |
74 from ..cffi._osutil import ffi, lib | |
75 except ImportError: | |
76 if modulepolicy == 'cffi': # strict cffi import | |
77 raise | |
78 | |
79 if pycompat.sysplatform == 'darwin' and ffi is not None: | |
80 listdir_batch_size = 4096 | |
81 # tweakable number, only affects performance, which chunks | |
82 # of bytes do we get back from getattrlistbulk | |
83 | |
84 attrkinds = [None] * 20 # we need the max no for enum VXXX, 20 is plenty | |
85 | |
86 attrkinds[lib.VREG] = statmod.S_IFREG | |
87 attrkinds[lib.VDIR] = statmod.S_IFDIR | |
88 attrkinds[lib.VLNK] = statmod.S_IFLNK | |
89 attrkinds[lib.VBLK] = statmod.S_IFBLK | |
90 attrkinds[lib.VCHR] = statmod.S_IFCHR | |
91 attrkinds[lib.VFIFO] = statmod.S_IFIFO | |
92 attrkinds[lib.VSOCK] = statmod.S_IFSOCK | |
93 | |
94 class stat_res(object): | |
95 def __init__(self, st_mode, st_mtime, st_size): | |
96 self.st_mode = st_mode | |
97 self.st_mtime = st_mtime | |
98 self.st_size = st_size | |
99 | |
100 tv_sec_ofs = ffi.offsetof("struct timespec", "tv_sec") | |
101 buf = ffi.new("char[]", listdir_batch_size) | |
102 | |
103 def listdirinternal(dfd, req, stat, skip): | |
104 ret = [] | |
105 while True: | |
106 r = lib.getattrlistbulk(dfd, req, buf, listdir_batch_size, 0) | |
107 if r == 0: | |
108 break | |
109 if r == -1: | |
110 raise OSError(ffi.errno, os.strerror(ffi.errno)) | |
111 cur = ffi.cast("val_attrs_t*", buf) | |
112 for i in range(r): | |
113 lgt = cur.length | |
114 assert lgt == ffi.cast('uint32_t*', cur)[0] | |
115 ofs = cur.name_info.attr_dataoffset | |
116 str_lgt = cur.name_info.attr_length | |
117 base_ofs = ffi.offsetof('val_attrs_t', 'name_info') | |
118 name = str(ffi.buffer(ffi.cast("char*", cur) + base_ofs + ofs, | |
119 str_lgt - 1)) | |
120 tp = attrkinds[cur.obj_type] | |
121 if name == "." or name == "..": | |
122 continue | |
123 if skip == name and tp == statmod.S_ISDIR: | |
124 return [] | |
125 if stat: | |
126 mtime = cur.mtime.tv_sec | |
127 mode = (cur.accessmask & ~lib.S_IFMT)| tp | |
128 ret.append((name, tp, stat_res(st_mode=mode, st_mtime=mtime, | |
129 st_size=cur.datalength))) | |
130 else: | |
131 ret.append((name, tp)) | |
132 cur = ffi.cast("val_attrs_t*", int(ffi.cast("intptr_t", cur)) | |
133 + lgt) | |
134 return ret | |
135 | |
136 def listdir(path, stat=False, skip=None): | |
137 req = ffi.new("struct attrlist*") | |
138 req.bitmapcount = lib.ATTR_BIT_MAP_COUNT | |
139 req.commonattr = (lib.ATTR_CMN_RETURNED_ATTRS | | |
140 lib.ATTR_CMN_NAME | | |
141 lib.ATTR_CMN_OBJTYPE | | |
142 lib.ATTR_CMN_ACCESSMASK | | |
143 lib.ATTR_CMN_MODTIME) | |
144 req.fileattr = lib.ATTR_FILE_DATALENGTH | |
145 dfd = lib.open(path, lib.O_RDONLY, 0) | |
146 if dfd == -1: | |
147 raise OSError(ffi.errno, os.strerror(ffi.errno)) | |
148 | |
149 try: | |
150 ret = listdirinternal(dfd, req, stat, skip) | |
151 finally: | |
152 try: | |
153 lib.close(dfd) | |
154 except BaseException: | |
155 pass # we ignore all the errors from closing, not | |
156 # much we can do about that | |
157 return ret | |
158 else: | |
159 listdir = listdirpure | |
160 | 66 |
161 if pycompat.osname != 'nt': | 67 if pycompat.osname != 'nt': |
162 posixfile = open | 68 posixfile = open |
163 | 69 |
164 _SCM_RIGHTS = 0x01 | 70 _SCM_RIGHTS = 0x01 |