static void pack_dec(git_pack *p) { int need_free; gitlck_lock(&p->lock); need_free = !--p->refcnt; gitlck_unlock(&p->lock); if (need_free) { if (p->idx_search) { gitfo_free_map(&p->idx_map); gitfo_close(p->idx_fd); free(p->im_fanout); free(p->im_off_idx); free(p->im_off_next); if (p->pack_fd != -1) { gitfo_close(p->pack_fd); gitfo_free_map(&p->pack_map); } } gitlck_free(&p->lock); free(p); } }
int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path) { int error, fd; char full_path[GIT_PATH_MAX]; char buffer[2048]; git_off_t size; git_odb_stream *stream; if (repo->path_workdir == NULL) return GIT_ENOTFOUND; git__joinpath(full_path, repo->path_workdir, path); if ((fd = gitfo_open(full_path, O_RDONLY)) < 0) return GIT_ENOTFOUND; if ((size = gitfo_size(fd)) < 0 || !git__is_sizet(size)) { gitfo_close(fd); return GIT_EOSERR; } if ((error = git_odb_open_wstream(&stream, repo->db, (size_t)size, GIT_OBJ_BLOB)) < GIT_SUCCESS) { gitfo_close(fd); return error; } while (size > 0) { ssize_t read_len; read_len = read(fd, buffer, sizeof(buffer)); if (read_len < 0) { gitfo_close(fd); stream->free(stream); return GIT_EOSERR; } stream->write(stream, buffer, read_len); size -= read_len; } error = stream->finalize_write(oid, stream); stream->free(stream); return error; }
int write_object_data(char *file, void *data, size_t len) { git_file fd; int ret; if ((fd = gitfo_creat(file, S_IREAD | S_IWRITE)) < 0) return -1; ret = gitfo_write(fd, data, len); gitfo_close(fd); return ret; }
int gitfo_close_cached(gitfo_cache *ioc) { git_file fd; if (gitfo_flush_cached(ioc) < GIT_SUCCESS) return GIT_ERROR; fd = ioc->fd; free(ioc->cache); free(ioc); return gitfo_close(fd); }
int gitfo_read_file(gitfo_buf *obj, const char *path) { git_file fd; size_t len; git_off_t size; unsigned char *buff; assert(obj && path && *path); if ((fd = gitfo_open(path, O_RDONLY)) < 0) return GIT_ERROR; if (((size = gitfo_size(fd)) < 0) || !git__is_sizet(size+1)) { gitfo_close(fd); return GIT_ERROR; } len = (size_t) size; if ((buff = git__malloc(len + 1)) == NULL) { gitfo_close(fd); return GIT_ERROR; } if (gitfo_read(fd, buff, len) < 0) { gitfo_close(fd); free(buff); return GIT_ERROR; } buff[len] = '\0'; gitfo_close(fd); obj->data = buff; obj->len = len; return GIT_SUCCESS; }
static int repo_init_createhead(const char *head_path) { git_file fd; int error = GIT_SUCCESS; char head_symlink[50]; sprintf(head_symlink, "%s %s%s\n", GIT_SYMREF, GIT_REFS_HEADS_DIR, GIT_BRANCH_MASTER); if ((fd = gitfo_creat(head_path, S_IREAD | S_IWRITE)) < GIT_SUCCESS) return GIT_ERROR; error = gitfo_write(fd, (void*)head_symlink, strlen(head_symlink)); gitfo_close(fd); return error; }
int git_filebuf_commit(git_filebuf *file) { int error; if ((error = flush_buffer(file)) < GIT_SUCCESS) goto cleanup; gitfo_close(file->fd); file->fd = -1; error = gitfo_move_file(file->path_lock, file->path_original); cleanup: git_filebuf_cleanup(file); return error; }
void git_filebuf_cleanup(git_filebuf *file) { if (file->fd >= 0) gitfo_close(file->fd); if (file->fd >= 0 && file->path_lock && gitfo_exists(file->path_lock) == GIT_SUCCESS) gitfo_unlink(file->path_lock); if (file->digest) git_hash_free_ctx(file->digest); free(file->buffer); free(file->z_buf); deflateEnd(&file->zs); free(file->path_original); free(file->path_lock); }
void git_filebuf_cleanup(git_filebuf *file) { if (file->fd >= 0) gitfo_close(file->fd); if (gitfo_exists(file->path_lock) == GIT_SUCCESS) gitfo_unlink(file->path_lock); if (file->digest) git_hash_free_ctx(file->digest); free(file->buffer); #ifdef GIT_FILEBUF_THREADS free(file->buffer_back); #endif free(file->path_original); free(file->path_lock); }
static int lock_file(git_filebuf *file, int flags) { if (gitfo_exists(file->path_lock) == 0) { if (flags & GIT_FILEBUF_FORCE) gitfo_unlink(file->path_lock); else return git__throw(GIT_EOSERR, "Failed to lock file"); } /* create path to the file buffer is required */ if (flags & GIT_FILEBUF_FORCE) { file->fd = gitfo_creat_locked_force(file->path_lock, 0644); } else { file->fd = gitfo_creat_locked(file->path_lock, 0644); } if (file->fd < 0) return git__throw(GIT_EOSERR, "Failed to create lock"); if ((flags & GIT_FILEBUF_APPEND) && gitfo_exists(file->path_original) == 0) { git_file source; char buffer[2048]; size_t read_bytes; source = gitfo_open(file->path_original, O_RDONLY); if (source < 0) return git__throw(GIT_EOSERR, "Failed to lock file. Could not open %s", file->path_original); while ((read_bytes = gitfo_read(source, buffer, 2048)) > 0) { gitfo_write(file->fd, buffer, read_bytes); if (file->digest) git_hash_update(file->digest, buffer, read_bytes); } gitfo_close(source); } return GIT_SUCCESS; }
int git_filebuf_commit(git_filebuf *file) { int error; /* temporary files cannot be committed */ assert(file && file->path_original); file->flush_mode = Z_FINISH; if ((error = flush_buffer(file)) < GIT_SUCCESS) goto cleanup; gitfo_close(file->fd); file->fd = -1; error = gitfo_mv(file->path_lock, file->path_original); cleanup: git_filebuf_cleanup(file); if (error < GIT_SUCCESS) return git__rethrow(error, "Failed to commit locked file from buffer"); return GIT_SUCCESS; }
static int pack_openidx_map(git_pack *p) { char pb[GIT_PATH_MAX]; off_t len; if (git__fmt(pb, sizeof(pb), "%s/pack/%s.idx", p->backend->objects_dir, p->pack_name) < 0) return GIT_ERROR; if ((p->idx_fd = gitfo_open(pb, O_RDONLY)) < 0) return GIT_ERROR; if ((len = gitfo_size(p->idx_fd)) < 0 || !git__is_sizet(len) || gitfo_map_ro(&p->idx_map, p->idx_fd, 0, (size_t)len)) { gitfo_close(p->idx_fd); return GIT_ERROR; } return GIT_SUCCESS; }
static int open_pack(git_pack *p) { char pb[GIT_PATH_MAX]; struct stat sb; if (p->pack_fd != -1) return GIT_SUCCESS; if (git__fmt(pb, sizeof(pb), "%s/pack/%s.pack", p->backend->objects_dir, p->pack_name) < 0) return GIT_ERROR; if (pack_openidx(p)) return GIT_ERROR; if ((p->pack_fd = gitfo_open(pb, O_RDONLY)) < 0) goto error_cleanup; if (gitfo_fstat(p->pack_fd, &sb) || !S_ISREG(sb.st_mode) || p->pack_size != sb.st_size || check_pack_hdr(p) || check_pack_sha1(p)) goto error_cleanup; if (!git__is_sizet(p->pack_size) || gitfo_map_ro(&p->pack_map, p->pack_fd, 0, (size_t)p->pack_size) < 0) goto error_cleanup; pack_decidx(p); return GIT_SUCCESS; error_cleanup: gitfo_close(p->pack_fd); p->pack_fd = -1; pack_decidx(p); return GIT_ERROR; }
static int lock_file(git_filebuf *file, int flags) { if (gitfo_exists(file->path_lock) == 0) { if (flags & GIT_FILEBUF_FORCE) gitfo_unlink(file->path_lock); else return GIT_EOSERR; } file->fd = gitfo_creat(file->path_lock, 0644); if (file->fd < 0) return GIT_EOSERR; /* TODO: do a flock() in the descriptor file_lock */ if ((flags & GIT_FILEBUF_APPEND) && gitfo_exists(file->path_original) == 0) { git_file source; char buffer[2048]; size_t read_bytes; source = gitfo_open(file->path_original, O_RDONLY); if (source < 0) return GIT_EOSERR; while ((read_bytes = gitfo_read(source, buffer, 2048)) > 0) { gitfo_write(file->fd, buffer, read_bytes); if (file->digest) git_hash_update(file->digest, buffer, read_bytes); } gitfo_close(source); } return GIT_SUCCESS; }