#define ce_size(ce) cache_entry_size(ce_namelen(ce))
#define ce_stage(ce) ((CE_STAGEMASK & ntohs((ce)->ce_flags)) >> CE_STAGESHIFT)
+#define ce_permissions(mode) (((mode) & 0100) ? 0755 : 0644)
+#define create_ce_mode(mode) htonl(S_IFREG | ce_permissions(mode))
+
#define cache_entry_size(len) ((offsetof(struct cache_entry,name) + (len) + 8) & ~7)
const char *sha1_file_directory;
static int create_file(const char *path, unsigned int mode)
{
- int fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
+ int fd;
+
+ mode = (mode & 0100) ? 777 : 666;
+ fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
if (fd < 0) {
if (errno == ENOENT) {
create_directories(path);
- fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
+ fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
}
}
if (fd >= 0)
fprintf(stderr, "checkout-cache: %s already exists\n", ce->name);
return 0;
}
+
+ /*
+ * We unlink the old file, to get the new one with the
+ * right permissions (including umask, which is nasty
+ * to emulate by hand - much easier to let the system
+ * just do the right thing)
+ */
+ unlink(ce->name);
}
return write_entry(ce);
}
if (ce->ce_uid != htonl(st->st_uid) ||
ce->ce_gid != htonl(st->st_gid))
changed |= OWNER_CHANGED;
- if (ce->ce_mode != htonl(st->st_mode))
+ /* We consider only the owner x bit to be relevant for "mode changes" */
+ if (0100 & (ntohs(ce->ce_mode) ^ st->st_mode))
changed |= MODE_CHANGED;
if (ce->ce_dev != htonl(st->st_dev) ||
ce->ce_ino != htonl(st->st_ino))
memset(ce, 0, size);
- ce->ce_mode = htonl(mode);
+ ce->ce_mode = create_ce_mode(mode);
ce->ce_flags = create_ce_flags(baselen + len, stage);
memcpy(ce->name, base, baselen);
memcpy(ce->name + baselen, pathname, len+1);
memset(ce, 0, size);
memcpy(ce->name, path, namelen);
fill_stat_cache_info(ce, &st);
- ce->ce_mode = htonl(st.st_mode);
+ ce->ce_mode = create_ce_mode(st.st_mode);
ce->ce_flags = htons(namelen);
if (index_fd(path, namelen, ce, fd, &st) < 0)
memcpy(ce->sha1, sha1, 20);
memcpy(ce->name, arg3, len);
ce->ce_flags = htons(len);
- ce->ce_mode = htonl(mode);
+ ce->ce_mode = create_ce_mode(mode);
return add_cache_entry(ce, allow_add);
}