25
from stat import ST_MODE, S_ISDIR, ST_SIZE
25
from stat import ST_MODE, S_ISDIR, ST_SIZE, S_IMODE
28
from bzrlib.osutils import (abspath, realpath, normpath, pathjoin, rename,
32
from bzrlib.osutils import (abspath, realpath, normpath, pathjoin, rename,
29
33
check_legal_path, rmtree)
30
34
from bzrlib.symbol_versioning import warn
31
35
from bzrlib.trace import mutter
32
36
from bzrlib.transport import Transport, Server
33
import bzrlib.urlutils as urlutils
39
_append_flags = os.O_CREAT | os.O_APPEND | os.O_WRONLY | osutils.O_BINARY
36
42
class LocalTransport(Transport):
52
58
super(LocalTransport, self).__init__(base)
53
59
self._local_base = urlutils.local_path_from_url(base)
54
## mutter("_local_base: %r => %r", base, self._local_base)
60
self._get_default_modes()
62
def _get_default_modes(self):
63
"""Figure out what the default file and directory modes are"""
64
umask = osutils.get_umask()
65
self._default_file_mode = 0666 & ~umask
66
self._default_dir_mode = 0777 & ~umask
56
68
def should_cache(self):
125
137
except (IOError, OSError),e:
126
138
self._translate_error(e, path)
128
def put(self, relpath, f, mode=0666):
140
def put(self, relpath, f, mode=None):
129
141
"""Copy the file-like or string object into the location.
131
143
:param relpath: Location to put the contents, relative to base.
164
176
"""Create a directory at the given path."""
180
local_mode = self._default_dir_mode
167
183
path = self._abspath(relpath)
184
os.mkdir(path, local_mode)
169
185
if mode is not None:
186
# It is probably faster to just do the chmod, rather than
187
# doing a stat, and then trying to compare
170
188
os.chmod(path, mode)
171
189
except (IOError, OSError),e:
172
190
self._translate_error(e, path)
174
def append(self, relpath, f, mode=0666):
192
def append(self, relpath, f, mode=None):
175
193
"""Append the text in the file-like object into the final location."""
176
194
abspath = self._abspath(relpath)
196
local_mode = self._default_file_mode
180
fd = os.open(abspath, os.O_CREAT | os.O_APPEND | os.O_WRONLY, mode)
200
fd = os.open(abspath, _append_flags, local_mode)
181
201
except (IOError, OSError),e:
182
202
self._translate_error(e, relpath)
184
result = os.lseek(fd, 0, 2)
206
if mode is not None and mode != S_IMODE(st.st_mode):
207
# Because of umask, we may still need to chmod the file.
208
# But in the general case, we won't have to
209
os.chmod(abspath, mode)
185
210
# TODO: make a raw FD version of _pump ?
186
211
self._pump_to_fd(f, fd)