343 if r: |
343 if r: |
344 raise error.Abort("%s: %r" % (r, path)) |
344 raise error.Abort("%s: %r" % (r, path)) |
345 self.audit(path, mode=mode) |
345 self.audit(path, mode=mode) |
346 |
346 |
347 def __call__(self, path, mode="r", atomictemp=False, notindexed=False, |
347 def __call__(self, path, mode="r", atomictemp=False, notindexed=False, |
348 backgroundclose=False, checkambig=False, auditpath=True): |
348 backgroundclose=False, checkambig=False, auditpath=True, |
|
349 makeparentdirs=True): |
349 '''Open ``path`` file, which is relative to vfs root. |
350 '''Open ``path`` file, which is relative to vfs root. |
350 |
351 |
351 Newly created directories are marked as "not to be indexed by |
352 By default, parent directories are created as needed. Newly created |
352 the content indexing service", if ``notindexed`` is specified |
353 directories are marked as "not to be indexed by the content indexing |
353 for "write" mode access. |
354 service", if ``notindexed`` is specified for "write" mode access. |
|
355 Set ``makeparentdirs=False`` to not create directories implicitly. |
354 |
356 |
355 If ``backgroundclose`` is passed, the file may be closed asynchronously. |
357 If ``backgroundclose`` is passed, the file may be closed asynchronously. |
356 It can only be used if the ``self.backgroundclosing()`` context manager |
358 It can only be used if the ``self.backgroundclosing()`` context manager |
357 is active. This should only be specified if the following criteria hold: |
359 is active. This should only be specified if the following criteria hold: |
358 |
360 |
387 dirname, basename = util.split(f) |
389 dirname, basename = util.split(f) |
388 # If basename is empty, then the path is malformed because it points |
390 # If basename is empty, then the path is malformed because it points |
389 # to a directory. Let the posixfile() call below raise IOError. |
391 # to a directory. Let the posixfile() call below raise IOError. |
390 if basename: |
392 if basename: |
391 if atomictemp: |
393 if atomictemp: |
392 util.makedirs(dirname, self.createmode, notindexed) |
394 if makeparentdirs: |
|
395 util.makedirs(dirname, self.createmode, notindexed) |
393 return util.atomictempfile(f, mode, self.createmode, |
396 return util.atomictempfile(f, mode, self.createmode, |
394 checkambig=checkambig) |
397 checkambig=checkambig) |
395 try: |
398 try: |
396 if 'w' in mode: |
399 if 'w' in mode: |
397 util.unlink(f) |
400 util.unlink(f) |
405 nlink = 2 # force mktempcopy (issue1922) |
408 nlink = 2 # force mktempcopy (issue1922) |
406 except (OSError, IOError) as e: |
409 except (OSError, IOError) as e: |
407 if e.errno != errno.ENOENT: |
410 if e.errno != errno.ENOENT: |
408 raise |
411 raise |
409 nlink = 0 |
412 nlink = 0 |
410 util.makedirs(dirname, self.createmode, notindexed) |
413 if makeparentdirs: |
|
414 util.makedirs(dirname, self.createmode, notindexed) |
411 if nlink > 0: |
415 if nlink > 0: |
412 if self._trustnlink is None: |
416 if self._trustnlink is None: |
413 self._trustnlink = nlink > 1 or util.checknlink(f) |
417 self._trustnlink = nlink > 1 or util.checknlink(f) |
414 if nlink > 1 or not self._trustnlink: |
418 if nlink > 1 or not self._trustnlink: |
415 util.rename(util.mktempcopy(f), f) |
419 util.rename(util.mktempcopy(f), f) |