static int write_deflate(git_filebuf *file, const void *source, size_t len) { int result = Z_OK; z_stream *zs = &file->zs; if (len > 0 || file->flush_mode == Z_FINISH) { zs->next_in = (void *)source; zs->avail_in = len; do { int have; zs->next_out = file->z_buf; zs->avail_out = file->buf_size; result = deflate(zs, file->flush_mode); assert(result != Z_STREAM_ERROR); have = file->buf_size - zs->avail_out; if (gitfo_write(file->fd, file->z_buf, have) < GIT_SUCCESS) return git__throw(GIT_EOSERR, "Failed to write to file"); } while (zs->avail_out == 0); assert(zs->avail_in == 0); if (file->digest) git_hash_update(file->digest, source, len); } return GIT_SUCCESS; }
int gitfo_write_cached(gitfo_cache *ioc, void *buff, size_t len) { unsigned char *buf = buff; for (;;) { size_t space_left = ioc->cache_size - ioc->pos; /* cache if it's small */ if (space_left > len) { gitfo_add_to_cache(ioc, buf, len); return GIT_SUCCESS; } /* flush the cache if it doesn't fit */ if (ioc->pos) { int rc; gitfo_add_to_cache(ioc, buf, space_left); rc = gitfo_flush_cached(ioc); if (rc < 0) return rc; len -= space_left; buf += space_left; } /* write too-large chunks immediately */ if (len > ioc->cache_size) return gitfo_write(ioc->fd, buf, len); } }
int git_filebuf_write(git_filebuf *file, void *buff, size_t len) { int error; unsigned char *buf = buff; for (;;) { size_t space_left = file->buf_size - file->buf_pos; /* cache if it's small */ if (space_left > len) { add_to_cache(file, buf, len); return GIT_SUCCESS; } /* flush the cache if it doesn't fit */ if (file->buf_pos > 0) { add_to_cache(file, buf, space_left); if ((error = flush_buffer(file)) < GIT_SUCCESS) return error; len -= space_left; buf += space_left; } /* write too-large chunks immediately */ if (len > file->buf_size) { error = gitfo_write(file->fd, buf, len); if (file->digest) git_hash_update(file->digest, buf, len); } } }
int gitfo_flush_cached(gitfo_cache *ioc) { int result = GIT_SUCCESS; if (ioc->pos) { result = gitfo_write(ioc->fd, ioc->cache, ioc->pos); ioc->pos = 0; } return result; }
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; }
static int write_normal(git_filebuf *file, const void *source, size_t len) { int result = 0; if (len > 0) { result = gitfo_write(file->fd, (void *)source, len); if (file->digest) git_hash_update(file->digest, source, len); } return result; }
static int flush_buffer(git_filebuf *file) { int result = GIT_SUCCESS; if (file->buf_pos > 0) { result = gitfo_write(file->fd, file->buffer, file->buf_pos); if (file->digest) git_hash_update(file->digest, file->buffer, file->buf_pos); file->buf_pos = 0; } return result; }
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; }
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; }
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; }