1007 |
1007 |
1008 def mktempcopy(name): |
1008 def mktempcopy(name): |
1009 d, fn = os.path.split(name) |
1009 d, fn = os.path.split(name) |
1010 fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, dir=d) |
1010 fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, dir=d) |
1011 os.close(fd) |
1011 os.close(fd) |
1012 ofp = posixfile(temp, "wb") |
1012 # Temporary files are created with mode 0600, which is usually not |
|
1013 # what we want. If the original file already exists, just copy |
|
1014 # its mode. Otherwise, manually obey umask. |
|
1015 try: |
|
1016 st_mode = os.lstat(name).st_mode |
|
1017 except OSError, inst: |
|
1018 if inst.errno != errno.ENOENT: |
|
1019 raise |
|
1020 st_mode = 0666 & ~_umask |
|
1021 os.chmod(temp, st_mode) |
1013 try: |
1022 try: |
1014 try: |
1023 try: |
1015 ifp = posixfile(name, "rb") |
1024 ifp = posixfile(name, "rb") |
1016 except IOError, inst: |
1025 except IOError, inst: |
|
1026 if inst.errno == errno.ENOENT: |
|
1027 return temp |
1017 if not getattr(inst, 'filename', None): |
1028 if not getattr(inst, 'filename', None): |
1018 inst.filename = name |
1029 inst.filename = name |
1019 raise |
1030 raise |
|
1031 ofp = posixfile(temp, "wb") |
1020 for chunk in filechunkiter(ifp): |
1032 for chunk in filechunkiter(ifp): |
1021 ofp.write(chunk) |
1033 ofp.write(chunk) |
1022 ifp.close() |
1034 ifp.close() |
1023 ofp.close() |
1035 ofp.close() |
1024 except: |
1036 except: |
1025 try: os.unlink(temp) |
1037 try: os.unlink(temp) |
1026 except: pass |
1038 except: pass |
1027 raise |
1039 raise |
1028 st = os.lstat(name) |
|
1029 os.chmod(temp, st.st_mode) |
|
1030 return temp |
1040 return temp |
1031 |
1041 |
1032 class atomictempfile(posixfile): |
1042 class atomictempfile(posixfile): |
1033 """the file will only be copied when rename is called""" |
1043 """the file will only be copied when rename is called""" |
1034 def __init__(self, name, mode): |
1044 def __init__(self, name, mode): |
1065 |
1075 |
1066 if mode[0] != "r": |
1076 if mode[0] != "r": |
1067 try: |
1077 try: |
1068 nlink = nlinks(f) |
1078 nlink = nlinks(f) |
1069 except OSError: |
1079 except OSError: |
|
1080 nlink = 0 |
1070 d = os.path.dirname(f) |
1081 d = os.path.dirname(f) |
1071 if not os.path.isdir(d): |
1082 if not os.path.isdir(d): |
1072 os.makedirs(d) |
1083 os.makedirs(d) |
1073 else: |
1084 if atomic: |
1074 if atomic: |
1085 return atomicfile(f, mode) |
1075 return atomicfile(f, mode) |
1086 elif atomictemp: |
1076 elif atomictemp: |
1087 return atomictempfile(f, mode) |
1077 return atomictempfile(f, mode) |
1088 if nlink > 1: |
1078 if nlink > 1: |
1089 rename(mktempcopy(f), f) |
1079 rename(mktempcopy(f), f) |
|
1080 return posixfile(f, mode) |
1090 return posixfile(f, mode) |
1081 |
1091 |
1082 return o |
1092 return o |
1083 |
1093 |
1084 class chunkbuffer(object): |
1094 class chunkbuffer(object): |