2018
SHA1_Final(sha1, &c);
2019
}
2020
2021
-/*
2022
- * Link the tempfile to the final place, possibly creating the
2023
- * last directory level as you do so.
2024
- *
2025
- * Returns the errno on failure, 0 on success.
2026
- */
2027
-static int link_temp_to_file(const char *tmpfile, const char *filename)
2028
-{
2029
- int ret;
2030
- char *dir;
2031
-
2032
- if (!link(tmpfile, filename))
2033
- return 0;
2034
-
2035
- /*
2036
- * Try to mkdir the last path component if that failed.
2037
- *
2038
- * Re-try the "link()" regardless of whether the mkdir
2039
- * succeeds, since a race might mean that somebody
2040
- * else succeeded.
2041
- */
2042
- ret = errno;
2043
- dir = strrchr(filename, '/');
2044
- if (dir) {
2045
- *dir = 0;
2046
- if (!mkdir(filename, 0777) && adjust_shared_perm(filename)) {
2047
- *dir = '/';
2048
- return -2;
2049
- }
2050
- *dir = '/';
2051
- if (!link(tmpfile, filename))
2052
- return 0;
2053
- ret = errno;
2054
- }
2055
- return ret;
2056
-}
2057
-
2021
/*
2022
* Move the just written object into its final resting place
2023
*/
2024
int move_temp_to_file(const char *tmpfile, const char *filename)
2025
{
2063
- int ret = link_temp_to_file(tmpfile, filename);
2026
+ int ret = link(tmpfile, filename);
2027
2028
/*
2029
* Coda hack - coda doesn't like cross-directory links,
2077
die("unable to write sha1 file");
2078
}
2079
2080
+/* Size of directory component, including the ending '/' */
2081
+static inline int directory_size(const char *filename)
2082
+{
2083
+ const char *s = strrchr(filename, '/');
2084
+ if (!s)
2085
+ return 0;
2086
+ return s - filename + 1;
2087
+}
2088
+
2089
+/*
2090
+ * This creates a temporary file in the same directory as the final
2091
+ * 'filename'
2092
+ *
2093
+ * We want to avoid cross-directory filename renames, because those
2094
+ * can have problems on various filesystems (FAT, NFS, Coda).
2095
+ */
2096
+static int create_tmpfile(char *buffer, size_t bufsiz, const char *filename)
2097
+{
2098
+ int fd, dirlen = directory_size(filename);
2099
+
2100
+ if (dirlen + 20 > bufsiz) {
2101
+ errno = ENAMETOOLONG;
2102
+ return -1;
2103
+ }
2104
+ memcpy(buffer, filename, dirlen);
2105
+ strcpy(buffer + dirlen, "tmp_obj_XXXXXX");
2106
+ fd = mkstemp(buffer);
2107
+ if (fd < 0 && dirlen) {
2108
+ /* Make sure the directory exists */
2109
+ buffer[dirlen-1] = 0;
2110
+ if (mkdir(buffer, 0777) && adjust_shared_perm(buffer))
2111
+ return -1;
2112
+
2113
+ /* Try again */
2114
+ strcpy(buffer + dirlen - 1, "/tmp_obj_XXXXXX");
2115
+ fd = mkstemp(buffer);
2116
+ }
2117
+ return fd;
2118
+}
2119
+
2120
static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
2121
void *buf, unsigned long len, time_t mtime)
2122
{
2141
return error("sha1 file %s: %s\n", filename, strerror(errno));
2142
}
2143
2141
- snprintf(tmpfile, sizeof(tmpfile), "%s/tmp_obj_XXXXXX", get_object_directory());
2142
-
2143
- fd = mkstemp(tmpfile);
2144
+ fd = create_tmpfile(tmpfile, sizeof(tmpfile), filename);
2145
if (fd < 0) {
2146
if (errno == EPERM)
2147
return error("insufficient permission for adding an object to repository database %s\n", get_object_directory());