~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/local.py

MergeĀ fromĀ test-tweaks

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
import os
23
23
import shutil
24
24
import sys
25
 
from stat import ST_MODE, S_ISDIR, ST_SIZE
 
25
from stat import ST_MODE, S_ISDIR, ST_SIZE, S_IMODE
26
26
import tempfile
27
27
 
28
 
from bzrlib.osutils import (abspath, realpath, normpath, pathjoin, rename, 
 
28
from bzrlib import (
 
29
    osutils,
 
30
    urlutils,
 
31
    )
 
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
 
37
 
 
38
 
 
39
_append_flags = os.O_CREAT | os.O_APPEND | os.O_WRONLY | osutils.O_BINARY
34
40
 
35
41
 
36
42
class LocalTransport(Transport):
51
57
            base = base + '/'
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)
55
60
 
56
61
    def should_cache(self):
57
62
        return False
162
167
        """Create a directory at the given path."""
163
168
        path = relpath
164
169
        try:
 
170
            if mode is None:
 
171
                # os.mkdir() will filter through umask
 
172
                local_mode = 0777
 
173
            else:
 
174
                local_mode = mode
165
175
            path = self._abspath(relpath)
166
 
            os.mkdir(path)
 
176
            os.mkdir(path, local_mode)
167
177
            if mode is not None:
 
178
                # It is probably faster to just do the chmod, rather than
 
179
                # doing a stat, and then trying to compare
168
180
                os.chmod(path, mode)
169
181
        except (IOError, OSError),e:
170
182
            self._translate_error(e, path)
172
184
    def append(self, relpath, f, mode=None):
173
185
        """Append the text in the file-like object into the final location."""
174
186
        abspath = self._abspath(relpath)
175
 
        fp = None
176
 
        try:
177
 
            try:
178
 
                fp = open(abspath, 'ab')
179
 
                # FIXME should we really be chmodding every time ? RBC 20060523
180
 
                if mode is not None:
181
 
                    os.chmod(abspath, mode)
182
 
            except (IOError, OSError),e:
183
 
                self._translate_error(e, relpath)
184
 
            # win32 workaround (tell on an unwritten file returns 0)
185
 
            fp.seek(0, 2)
186
 
            result = fp.tell()
187
 
            self._pump(f, fp)
 
187
        if mode is None:
 
188
            # os.open() will automatically use the umask
 
189
            local_mode = 0666
 
190
        else:
 
191
            local_mode = mode
 
192
        try:
 
193
            fd = os.open(abspath, _append_flags, local_mode)
 
194
        except (IOError, OSError),e:
 
195
            self._translate_error(e, relpath)
 
196
        try:
 
197
            st = os.fstat(fd)
 
198
            result = st.st_size
 
199
            if mode is not None and mode != S_IMODE(st.st_mode):
 
200
                # Because of umask, we may still need to chmod the file.
 
201
                # But in the general case, we won't have to
 
202
                os.chmod(abspath, mode)
 
203
            self._pump_to_fd(f, fd)
188
204
        finally:
189
 
            if fp is not None:
190
 
                fp.close()
 
205
            os.close(fd)
191
206
        return result
192
207
 
 
208
    def _pump_to_fd(self, fromfile, to_fd):
 
209
        """Copy contents of one file to another."""
 
210
        BUFSIZE = 32768
 
211
        while True:
 
212
            b = fromfile.read(BUFSIZE)
 
213
            if not b:
 
214
                break
 
215
            os.write(to_fd, b)
 
216
 
193
217
    def copy(self, rel_from, rel_to):
194
218
        """Copy the item at rel_from to the location at rel_to"""
195
219
        path_from = self._abspath(rel_from)