int git_futils_writebuffer( const git_buf *buf, const char *path, int flags, mode_t mode) { int fd, error = 0; if (flags <= 0) flags = O_CREAT | O_TRUNC | O_WRONLY; if (!mode) mode = GIT_FILEMODE_BLOB; if ((fd = p_open(path, flags, mode)) < 0) { giterr_set(GITERR_OS, "Could not open '%s' for writing", path); return fd; } if ((error = p_write(fd, git_buf_cstr(buf), git_buf_len(buf))) < 0) { giterr_set(GITERR_OS, "Could not write to '%s'", path); (void)p_close(fd); return error; } if ((error = p_close(fd)) < 0) giterr_set(GITERR_OS, "Error while closing '%s'", path); return error; }
int git_futils_readbuffer_updated(git_fbuffer *obj, const char *path, time_t *mtime, int *updated) { git_file fd; size_t len; struct stat st; unsigned char *buff; assert(obj && path && *path); if (updated != NULL) *updated = 0; if (p_stat(path, &st) < 0) return git__throw(GIT_ENOTFOUND, "Failed to stat file %s", path); if (S_ISDIR(st.st_mode)) return git__throw(GIT_ERROR, "Can't read a dir into a buffer"); /* * If we were given a time, we only want to read the file if it * has been modified. */ if (mtime != NULL && *mtime >= st.st_mtime) return GIT_SUCCESS; if (mtime != NULL) *mtime = st.st_mtime; if (!git__is_sizet(st.st_size+1)) return git__throw(GIT_ERROR, "Failed to read file `%s`. An error occured while calculating its size", path); len = (size_t) st.st_size; if ((fd = p_open(path, O_RDONLY)) < 0) return git__throw(GIT_EOSERR, "Failed to open %s for reading", path); if ((buff = git__malloc(len + 1)) == NULL) { p_close(fd); return GIT_ENOMEM; } if (p_read(fd, buff, len) < 0) { p_close(fd); free(buff); return git__throw(GIT_ERROR, "Failed to read file `%s`", path); } buff[len] = '\0'; p_close(fd); if (mtime != NULL) *mtime = st.st_mtime; if (updated != NULL) *updated = 1; obj->data = buff; obj->len = len; return GIT_SUCCESS; }
int git_futils_readbuffer_updated( git_buf *buf, const char *path, time_t *mtime, size_t *size, int *updated) { git_file fd; struct stat st; bool changed = false; assert(buf && path && *path); if (updated != NULL) *updated = 0; if ((fd = git_futils_open_ro(path)) < 0) return fd; if (p_fstat(fd, &st) < 0 || S_ISDIR(st.st_mode) || !git__is_sizet(st.st_size+1)) { p_close(fd); giterr_set(GITERR_OS, "Invalid regular file stat for '%s'", path); return -1; } /* * If we were given a time and/or a size, we only want to read the file * if it has been modified. */ if (size && *size != (size_t)st.st_size) changed = true; if (mtime && *mtime != st.st_mtime) changed = true; if (!size && !mtime) changed = true; if (!changed) { p_close(fd); return 0; } if (mtime != NULL) *mtime = st.st_mtime; if (size != NULL) *size = (size_t)st.st_size; if (git_futils_readbuffer_fd(buf, fd, (size_t)st.st_size) < 0) { p_close(fd); return -1; } p_close(fd); if (updated != NULL) *updated = 1; return 0; }
int main(int argc, char *argv[]) { // Stack variables const char *file = "./hello_task.elf"; const char *func = "main"; int status, i, all, nargs = 1; const char *args[nargs]; char argbuf[20]; // References as opaque structures p_dev_t dev0; p_prog_t prog0; p_team_t team0; p_mem_t mem[4]; // Execution setup dev0 = p_init(P_DEV_DEMO, 0); // initialize device and team prog0 = p_load(dev0, file, func, 0); // load a program from file system all = p_query(dev0, P_PROP_NODES); // find number of nodes in system team0 = p_open(dev0, 0, all); // create a team // Running program for (i = 0; i < all; i++) { sprintf(argbuf, "%d", i); // string args needed to run main asis args[0] = argbuf; status = p_run(prog0, team0, i, 1, nargs, args, 0); } p_wait(team0); // not needed p_close(team0); // close team p_finalize(dev0); // finalize memory return 0; }
static int repo_write_template( const char *git_dir, const char *file, mode_t mode, const char *content) { git_buf path = GIT_BUF_INIT; int fd, error = 0; if (git_buf_joinpath(&path, git_dir, file) < 0) return -1; fd = p_open(git_buf_cstr(&path), O_WRONLY | O_CREAT | O_EXCL, mode); if (fd >= 0) { error = p_write(fd, content, strlen(content)); p_close(fd); } else if (errno != EEXIST) error = fd; git_buf_free(&path); if (error) giterr_set(GITERR_OS, "Failed to initialize repository with template '%s'", file); return error; }
static int read_header_loose(git_rawobj *out, git_buf *loc) { unsigned char obj[1024]; int fd, obj_len, error; assert(out && loc); if (git_buf_oom(loc)) return -1; out->data = NULL; if ((error = fd = git_futils_open_ro(loc->ptr)) < 0 || (error = obj_len = p_read(fd, obj, sizeof(obj))) < 0) goto done; if (!is_zlib_compressed_data(obj, (size_t)obj_len)) error = read_header_loose_packlike(out, obj, (size_t)obj_len); else error = read_header_loose_standard(out, obj, (size_t)obj_len); if (!error && !git_object_typeisloose(out->type)) { giterr_set(GITERR_ZLIB, "failed to read loose object header"); error = -1; goto done; } done: if (fd >= 0) p_close(fd); return error; }
void git_filebuf_cleanup(git_filebuf *file) { if (file->fd_is_open && file->fd >= 0) p_close(file->fd); if (file->fd_is_open && file->path_lock && git_path_exists(file->path_lock)) p_unlink(file->path_lock); if (file->digest) git_hash_free_ctx(file->digest); if (file->buffer) git__free(file->buffer); /* use the presence of z_buf to decide if we need to deflateEnd */ if (file->z_buf) { git__free(file->z_buf); deflateEnd(&file->zs); } if (file->path_original) git__free(file->path_original); if (file->path_lock) git__free(file->path_lock); memset(file, 0x0, sizeof(git_filebuf)); file->fd = -1; }
void test_core_filebuf__rename_error(void) { git_filebuf file = GIT_FILEBUF_INIT; char *dir = "subdir", *test = "subdir/test", *test_lock = "subdir/test.lock"; int fd; #ifndef GIT_WIN32 cl_skip(); #endif cl_git_pass(p_mkdir(dir, 0666)); cl_git_mkfile(test, "dummy content"); fd = p_open(test, O_RDONLY); cl_assert(fd > 0); cl_git_pass(git_filebuf_open(&file, test, 0, 0666)); cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks")); cl_assert_equal_i(true, git_path_exists(test_lock)); cl_git_fail(git_filebuf_commit(&file)); p_close(fd); git_filebuf_cleanup(&file); cl_assert_equal_i(false, git_path_exists(test_lock)); }
static int write_file_stream( git_oid *oid, git_odb *odb, const char *path, git_off_t file_size) { int fd, error; char buffer[4096]; git_odb_stream *stream = NULL; ssize_t read_len = -1, written = 0; if ((error = git_odb_open_wstream( &stream, odb, (size_t)file_size, GIT_OBJ_BLOB)) < 0) return error; if ((fd = git_futils_open_ro(path)) < 0) { git_odb_stream_free(stream); return -1; } while (!error && (read_len = p_read(fd, buffer, sizeof(buffer))) > 0) { error = git_odb_stream_write(stream, buffer, read_len); written += read_len; } p_close(fd); if (written != file_size || read_len < 0) { giterr_set(GITERR_OS, "Failed to read file into stream"); error = -1; } if (!error) error = git_odb_stream_finalize_write(oid, stream); git_odb_stream_free(stream); return error; }
int git_futils_mmap_ro_file(git_map *out, const char *path) { git_file fd = git_futils_open_ro(path); git_off_t len; int result; if (fd < 0) return fd; if ((len = git_futils_filesize(fd)) < 0) { result = -1; goto out; } if (!git__is_sizet(len)) { giterr_set(GITERR_OS, "file `%s` too large to mmap", path); result = -1; goto out; } result = git_futils_mmap_ro(out, fd, 0, (size_t)len); out: p_close(fd); return result; }
static int buffer_to_file( git_buf *buffer, const char *path, mode_t dir_mode, int file_open_flags, mode_t file_mode) { int fd, error, error_close; if ((error = git_futils_mkpath2file(path, dir_mode)) < 0) return error; if ((fd = p_open(path, file_open_flags, file_mode)) < 0) return fd; error = p_write(fd, git_buf_cstr(buffer), git_buf_len(buffer)); error_close = p_close(fd); if (!error) error = error_close; if (!error && (file_mode & 0100) != 0 && (error = p_chmod(path, file_mode)) < 0) giterr_set(GITERR_OS, "Failed to set permissions on '%s'", path); return error; }
static int diff_file_content_load_workdir_file( git_diff_file_content *fc, git_buf *path, git_diff_options *diff_opts) { int error = 0; git_filter_list *fl = NULL; git_file fd = git_futils_open_ro(git_buf_cstr(path)); git_buf raw = GIT_BUF_INIT; if (fd < 0) return fd; if (!fc->file->size && !(fc->file->size = git_futils_filesize(fd))) goto cleanup; if ((diff_opts->flags & GIT_DIFF_SHOW_BINARY) == 0 && diff_file_content_binary_by_size(fc)) goto cleanup; if ((error = git_filter_list_load( &fl, fc->repo, NULL, fc->file->path, GIT_FILTER_TO_ODB, GIT_FILTER_ALLOW_UNSAFE)) < 0) goto cleanup; /* if there are no filters, try to mmap the file */ if (fl == NULL) { if (!(error = git_futils_mmap_ro( &fc->map, fd, 0, (size_t)fc->file->size))) { fc->flags |= GIT_DIFF_FLAG__UNMAP_DATA; goto cleanup; } /* if mmap failed, fall through to try readbuffer below */ giterr_clear(); } if (!(error = git_futils_readbuffer_fd(&raw, fd, (size_t)fc->file->size))) { git_buf out = GIT_BUF_INIT; error = git_filter_list_apply_to_data(&out, fl, &raw); if (out.ptr != raw.ptr) git_buf_dispose(&raw); if (!error) { fc->map.len = out.size; fc->map.data = out.ptr; fc->flags |= GIT_DIFF_FLAG__FREE_DATA; } } cleanup: git_filter_list_free(fl); p_close(fd); return error; }
static void file_create(const char *filename, const char *content) { int fd = p_creat(filename, 0644); cl_assert(fd >= 0); cl_must_pass(p_write(fd, content, strlen(content))); cl_must_pass(p_close(fd)); }
int git_odb_hashfile(git_oid *out, const char *path, git_otype type) { git_off_t size; int result, fd = git_futils_open_ro(path); if (fd < 0) return fd; if ((size = git_futils_filesize(fd)) < 0 || !git__is_sizet(size)) { giterr_set(GITERR_OS, "File size overflow for 32-bit systems"); p_close(fd); return -1; } result = git_odb__hashfd(out, fd, (size_t)size, type); p_close(fd); return result; }
static int diff_file_content_load_workdir_file( git_diff_file_content *fc, git_buf *path) { int error = 0; git_vector filters = GIT_VECTOR_INIT; git_buf raw = GIT_BUF_INIT, filtered = GIT_BUF_INIT; git_file fd = git_futils_open_ro(git_buf_cstr(path)); if (fd < 0) return fd; if (!fc->file->size && !(fc->file->size = git_futils_filesize(fd))) goto cleanup; if (diff_file_content_binary_by_size(fc)) goto cleanup; if ((error = git_filters_load( &filters, fc->repo, fc->file->path, GIT_FILTER_TO_ODB)) < 0) goto cleanup; /* error >= is a filter count */ if (error == 0) { if (!(error = git_futils_mmap_ro( &fc->map, fd, 0, (size_t)fc->file->size))) fc->flags |= GIT_DIFF_FLAG__UNMAP_DATA; else /* fall through to try readbuffer below */ giterr_clear(); } if (error != 0) { error = git_futils_readbuffer_fd(&raw, fd, (size_t)fc->file->size); if (error < 0) goto cleanup; if (!filters.length) git_buf_swap(&filtered, &raw); else error = git_filters_apply(&filtered, &raw, &filters); if (!error) { fc->map.len = git_buf_len(&filtered); fc->map.data = git_buf_detach(&filtered); fc->flags |= GIT_DIFF_FLAG__FREE_DATA; } git_buf_free(&raw); git_buf_free(&filtered); } cleanup: git_filters_free(&filters); p_close(fd); return error; }
void clar__assert_equal_file( const char *expected_data, size_t expected_bytes, int ignore_cr, const char *path, const char *file, int line) { char buf[4000]; ssize_t bytes, total_bytes = 0; int fd = p_open(path, O_RDONLY | O_BINARY); cl_assert(fd >= 0); if (expected_data && !expected_bytes) expected_bytes = strlen(expected_data); while ((bytes = p_read(fd, buf, sizeof(buf))) != 0) { clar__assert( bytes > 0, file, line, "error reading from file", path, 1); if (ignore_cr) bytes = strip_cr_from_buf(buf, bytes); if (memcmp(expected_data, buf, bytes) != 0) { int pos; for (pos = 0; pos < bytes && expected_data[pos] == buf[pos]; ++pos) /* find differing byte offset */; p_snprintf( buf, sizeof(buf), "file content mismatch at byte %"PRIdZ, (ssize_t)(total_bytes + pos)); p_close(fd); clar__fail(file, line, path, buf, 1); } expected_data += bytes; total_bytes += bytes; } p_close(fd); clar__assert(!bytes, file, line, "error reading from file", path, 1); clar__assert_equal(file, line, "mismatched file length", 1, "%"PRIuZ, (size_t)expected_bytes, (size_t)total_bytes); }
void cl_git_write2file( const char *filename, const char *new_content, int flags, unsigned int mode) { int fd = p_open(filename, flags, mode); cl_assert(fd >= 0); if (!new_content) new_content = "\n"; cl_must_pass(p_write(fd, new_content, strlen(new_content))); cl_must_pass(p_close(fd)); }
int git_futils_writebuffer( const git_buf *buf, const char *path, int flags, mode_t mode) { int fd, do_fsync = 0, error = 0; if (!flags) flags = O_CREAT | O_TRUNC | O_WRONLY; if ((flags & O_FSYNC) != 0) do_fsync = 1; flags &= ~O_FSYNC; if (!mode) mode = GIT_FILEMODE_BLOB; if ((fd = p_open(path, flags, mode)) < 0) { giterr_set(GITERR_OS, "could not open '%s' for writing", path); return fd; } if ((error = p_write(fd, git_buf_cstr(buf), git_buf_len(buf))) < 0) { giterr_set(GITERR_OS, "could not write to '%s'", path); (void)p_close(fd); return error; } if (do_fsync && (error = p_fsync(fd)) < 0) { giterr_set(GITERR_OS, "could not fsync '%s'", path); p_close(fd); return error; } if ((error = p_close(fd)) < 0) { giterr_set(GITERR_OS, "error while closing '%s'", path); return error; } if (do_fsync && (flags & O_CREAT)) error = git_futils_fsync_parent(path); return error; }
static int lock_file(git_filebuf *file, int flags) { if (git_path_exists(file->path_lock) == true) { if (flags & GIT_FILEBUF_FORCE) p_unlink(file->path_lock); else { giterr_clear(); /* actual OS error code just confuses */ giterr_set(GITERR_OS, "Failed to lock file '%s' for writing", file->path_lock); return -1; } } /* create path to the file buffer is required */ if (flags & GIT_FILEBUF_FORCE) { /* XXX: Should dirmode here be configurable? Or is 0777 always fine? */ file->fd = git_futils_creat_locked_withpath(file->path_lock, 0777, GIT_LOCK_FILE_MODE); } else { file->fd = git_futils_creat_locked(file->path_lock, GIT_LOCK_FILE_MODE); } if (file->fd < 0) return -1; file->fd_is_open = true; if ((flags & GIT_FILEBUF_APPEND) && git_path_exists(file->path_original) == true) { git_file source; char buffer[2048]; ssize_t read_bytes; source = p_open(file->path_original, O_RDONLY); if (source < 0) { giterr_set(GITERR_OS, "Failed to open file '%s' for reading", file->path_original); return -1; } while ((read_bytes = p_read(source, buffer, sizeof(buffer))) > 0) { p_write(file->fd, buffer, read_bytes); if (file->digest) git_hash_update(file->digest, buffer, read_bytes); } p_close(source); if (read_bytes < 0) { giterr_set(GITERR_OS, "Failed to read file '%s'", file->path_original); return -1; } } return 0; }
static void write_object_files(object_data *d) { int fd; if (p_mkdir(d->dir, GIT_OBJECT_DIR_MODE) < 0) cl_assert(errno == EEXIST); cl_assert((fd = p_creat(d->file, S_IREAD | S_IWRITE)) >= 0); cl_must_pass(p_write(fd, d->bytes, d->blen)); p_close(fd); }
void cl_git_write2file( const char *path, const char *content, size_t content_len, int flags, unsigned int mode) { int fd; cl_assert(path && content); cl_assert((fd = p_open(path, flags, mode)) >= 0); if (!content_len) content_len = strlen(content); cl_must_pass(p_write(fd, content, content_len)); cl_must_pass(p_close(fd)); }
int git_indexer_new( git_indexer **out, const char *prefix, unsigned int mode, git_odb *odb, git_transfer_progress_cb progress_cb, void *progress_payload) { git_indexer *idx; git_buf path = GIT_BUF_INIT, tmp_path = GIT_BUF_INIT; static const char suff[] = "/pack"; int error, fd = -1; idx = (git_indexer *) git__calloc(1, sizeof(git_indexer)); GITERR_CHECK_ALLOC(idx); idx->odb = odb; idx->progress_cb = progress_cb; idx->progress_payload = progress_payload; idx->mode = mode ? mode : GIT_PACK_FILE_MODE; git_hash_ctx_init(&idx->hash_ctx); git_hash_ctx_init(&idx->trailer); error = git_buf_joinpath(&path, prefix, suff); if (error < 0) goto cleanup; fd = git_futils_mktmp(&tmp_path, git_buf_cstr(&path), idx->mode); git_buf_free(&path); if (fd < 0) goto cleanup; error = git_packfile_alloc(&idx->pack, git_buf_cstr(&tmp_path)); git_buf_free(&tmp_path); if (error < 0) goto cleanup; idx->pack->mwf.fd = fd; if ((error = git_mwindow_file_register(&idx->pack->mwf)) < 0) goto cleanup; *out = idx; return 0; cleanup: if (fd != -1) p_close(fd); git_buf_free(&path); git_buf_free(&tmp_path); git__free(idx); return -1; }
static int file_create(const char *filename, const char *content) { int fd; fd = p_creat(filename, 0666); if (fd == 0) return GIT_ERROR; if (p_write(fd, content, strlen(content)) != 0) return GIT_ERROR; if (p_close(fd) != 0) return GIT_ERROR; return GIT_SUCCESS; }
void test_core_posix__utimes(void) { struct timeval times[2]; struct stat st; time_t curtime; int fd; /* test p_utimes */ times[0].tv_sec = 1234567890; times[0].tv_usec = 0; times[1].tv_sec = 1234567890; times[1].tv_usec = 0; cl_git_mkfile("foo", "Dummy file."); cl_must_pass(p_utimes("foo", times)); p_stat("foo", &st); cl_assert_equal_i(1234567890, st.st_atime); cl_assert_equal_i(1234567890, st.st_mtime); /* test p_futimes */ times[0].tv_sec = 1414141414; times[0].tv_usec = 0; times[1].tv_sec = 1414141414; times[1].tv_usec = 0; cl_must_pass(fd = p_open("foo", O_RDWR)); cl_must_pass(p_futimes(fd, times)); p_close(fd); p_stat("foo", &st); cl_assert_equal_i(1414141414, st.st_atime); cl_assert_equal_i(1414141414, st.st_mtime); /* test p_utimes with current time, assume that * it takes < 5 seconds to get the time...! */ cl_must_pass(p_utimes("foo", NULL)); curtime = time(NULL); p_stat("foo", &st); cl_assert((st.st_atime - curtime) < 5); cl_assert((st.st_mtime - curtime) < 5); p_unlink("foo"); }
static void write_file(const char *path, const char *content) { git_file file; int error; if (git_path_exists(path)) { cl_git_pass(p_unlink(path)); } file = git_futils_creat_withpath(path, 0777, 0666); cl_assert(file >= 0); error = p_write(file, content, strlen(content) * sizeof(char)); p_close(file); cl_git_pass(error); }
void cl_git_mkfile(const char *filename, const char *content) { int fd; fd = p_creat(filename, 0666); cl_assert(fd != 0); if (content) { cl_must_pass(p_write(fd, content, strlen(content))); } else { cl_must_pass(p_write(fd, filename, strlen(filename))); cl_must_pass(p_write(fd, "\n", 1)); } cl_must_pass(p_close(fd)); }
static int create_empty_file(const char *path, mode_t mode) { int fd; if ((fd = p_creat(path, mode)) < 0) { giterr_set(GITERR_OS, "Error while creating '%s'", path); return -1; } if (p_close(fd) < 0) { giterr_set(GITERR_OS, "Error while closing '%s'", path); return -1; } return 0; }
static void test_file_contents(const char *path, const char *expectedcontents) { int fd; char buffer[1024] = {0}; size_t expectedlen, actuallen; fd = p_open(path, O_RDONLY); cl_assert(fd >= 0); expectedlen = strlen(expectedcontents); actuallen = p_read(fd, buffer, 1024); cl_git_pass(p_close(fd)); cl_assert_equal_sz(actuallen, expectedlen); cl_assert_equal_s(buffer, expectedcontents); }
/* make sure git_filebuf_open doesn't delete an existing lock */ void test_core_filebuf__0(void) { git_filebuf file = GIT_FILEBUF_INIT; int fd; char test[] = "test", testlock[] = "test.lock"; fd = p_creat(testlock, 0744); //-V536 cl_must_pass(fd); cl_must_pass(p_close(fd)); cl_git_fail(git_filebuf_open(&file, test, 0, 0666)); cl_assert(git_path_exists(testlock)); cl_must_pass(p_unlink(testlock)); }
/* make sure git_filebuf_open doesn't delete an existing lock */ void test_core_filebuf__0(void) { git_filebuf file; int fd; char test[] = "test", testlock[] = "test.lock"; fd = p_creat(testlock, 0744); cl_must_pass(fd); cl_must_pass(p_close(fd)); cl_git_fail(git_filebuf_open(&file, test, 0)); cl_git_pass(git_futils_exists(testlock)); cl_must_pass(p_unlink(testlock)); }