buglvl = atoi(os.environ.get('BUP_DEBUG', 0))
+try:
+ _fdatasync = os.fdatasync
+except AttributeError:
+ _fdatasync = os.fsync
+
if sys.platform.startswith('darwin'):
- # Apparently fsync on OS X doesn't guarantee to sync all the way down
+ # Apparently os.fsync on OS X doesn't guarantee to sync all the way down
import fcntl
- fdatasync = lambda fd : fcntl.fcntl(fd, fcntl.F_FULLFSYNC)
-else: # If the platform doesn't have fdatasync, fall back to fsync
- try:
- fdatasync = os.fdatasync
- except AttributeError:
- fdatasync = os.fsync
+ def fdatasync(fd):
+ try:
+ return fcntl.fcntl(fd, fcntl.F_FULLFSYNC)
+ except IOError as e:
+ # Fallback for file systems (SMB) that do not support F_FULLFSYNC
+ if e.errno == errno.ENOTSUP:
+ return _fdatasync(fd)
+ else:
+ raise
+else:
+ fdatasync = _fdatasync
# Write (blockingly) to sockets that may or may not be in blocking mode.
raise
-def readpipe(argv, preexec_fn=None):
+def readpipe(argv, preexec_fn=None, shell=False):
"""Run a subprocess and return its output."""
- p = subprocess.Popen(argv, stdout=subprocess.PIPE, preexec_fn=preexec_fn)
+ p = subprocess.Popen(argv, stdout=subprocess.PIPE, preexec_fn=preexec_fn,
+ shell=shell)
out, err = p.communicate()
if p.returncode != 0:
raise Exception('subprocess %r failed with status %d'
return time.strftime('%z', localtime(t))
def to_py_time(x):
return x
+
+
+_some_invalid_save_parts_rx = re.compile(r'[[ ~^:?*\\]|\.\.|//|@{')
+
+def valid_save_name(name):
+ # Enforce a superset of the restrictions in git-check-ref-format(1)
+ if name == '@' \
+ or name.startswith('/') or name.endswith('/') \
+ or name.endswith('.'):
+ return False
+ if _some_invalid_save_parts_rx.search(name):
+ return False
+ for c in name:
+ if ord(c) < 0x20 or ord(c) == 0x7f:
+ return False
+ for part in name.split('/'):
+ if part.startswith('.') or part.endswith('.lock'):
+ return False
+ return True