/* * Find the conflict identified by "id"; the change between its * "preimage" (i.e. a previous contents with conflict markers) and its * "postimage" (i.e. the corresponding contents with conflicts * resolved) may apply cleanly to the contents stored in "path", i.e. * the conflict this time around. * * Returns 0 for successful replay of recorded resolution, or non-zero * for failure. */ static int merge(const struct rerere_id *id, const char *path) { FILE *f; int ret; mmfile_t cur = {NULL, 0}; mmbuffer_t result = {NULL, 0}; /* * Normalize the conflicts in path and write it out to * "thisimage" temporary file. */ if ((handle_file(path, NULL, rerere_path(id, "thisimage")) < 0) || read_mmfile(&cur, rerere_path(id, "thisimage"))) { ret = 1; goto out; } ret = try_merge(id, path, &cur, &result); if (ret) goto out; /* * A successful replay of recorded resolution. * Mark that "postimage" was used to help gc. */ if (utime(rerere_path(id, "postimage"), NULL) < 0) warning_errno("failed utime() on %s", rerere_path(id, "postimage")); /* Update "path" with the resolution */ f = fopen(path, "w"); if (!f) return error_errno("Could not open %s", path); if (fwrite(result.ptr, result.size, 1, f) != 1) error_errno("Could not write %s", path); if (fclose(f)) return error_errno("Writing %s failed", path); out: free(cur.ptr); free(result.ptr); return ret; }
/* * This does not play well with MPI_Comm_spawn. Probably Totalview does * not support such a usage model anyway. */ int tv_startup(int ntasks) { int rc; growstr_t *g; struct sockaddr_in tv_sockaddr; socklen_t tv_sockaddr_len = sizeof(tv_sockaddr); struct timespec ts = { 0, 20L * 1000 * 1000 }; /* 20 ms */ MPIR_proctable = Malloc(ntasks * sizeof(*MPIR_proctable)); /* Creating socket for pid exchange of remote processes */ tv_socket = socket(PF_INET, SOCK_STREAM, 0); if (tv_socket < 0) error_errno("%s: socket ", __func__); memset(&tv_sockaddr, 0, sizeof(tv_sockaddr)); tv_sockaddr.sin_family = AF_INET; tv_sockaddr.sin_addr = myaddr.sin_addr; rc = bind(tv_socket, (struct sockaddr *) &tv_sockaddr, tv_sockaddr_len); if (rc) error_errno("%s: bind", __func__); rc = getsockname(tv_socket, (struct sockaddr *) &tv_sockaddr, &tv_sockaddr_len); if (rc) error_errno("%s: getsockname", __func__); rc = listen(tv_socket, 32767); if (rc) error_errno("%s: listen", __func__); /* start totalview and tell it to attach to this mpiexec process */ g = growstr_init(); growstr_printf(g, "%s -e \"dattach mpiexec %d; dgo; " "dassign MPIR_being_debugged 1\" &", tvname, getpid()); system(g->s); growstr_free(g); /* wait for totalview to find us */ while (!MPIR_being_debugged) nanosleep(&ts, NULL); return ntohs(tv_sockaddr.sin_port); }
/* * Returns 0 if there was no previous error and gc can proceed, 1 if * gc should not proceed due to an error in the last run. Prints a * message and returns -1 if an error occured while reading gc.log */ static int report_last_gc_error(void) { struct strbuf sb = STRBUF_INIT; int ret = 0; ssize_t len; struct stat st; char *gc_log_path = git_pathdup("gc.log"); if (stat(gc_log_path, &st)) { if (errno == ENOENT) goto done; ret = error_errno(_("cannot stat '%s'"), gc_log_path); goto done; } if (st.st_mtime < gc_log_expire_time) goto done; len = strbuf_read_file(&sb, gc_log_path, 0); if (len < 0) ret = error_errno(_("cannot read '%s'"), gc_log_path); else if (len > 0) { /* * A previous gc failed. Report the error, and don't * bother with an automatic gc run since it is likely * to fail in the same way. */ warning(_("The last gc run reported the following. " "Please correct the root cause\n" "and remove %s.\n" "Automatic cleanup will not be performed " "until the file is removed.\n\n" "%s"), gc_log_path, sb.buf); ret = 1; } strbuf_release(&sb); done: free(gc_log_path); return ret; }
int verify_signed_buffer(const char *payload, size_t payload_size, const char *signature, size_t signature_size, struct strbuf *gpg_output, struct strbuf *gpg_status) { struct child_process gpg = CHILD_PROCESS_INIT; struct tempfile *temp; int ret; struct strbuf buf = STRBUF_INIT; temp = mks_tempfile_t(".git_vtag_tmpXXXXXX"); if (!temp) return error_errno(_("could not create temporary file")); if (write_in_full(temp->fd, signature, signature_size) < 0 || close_tempfile_gently(temp) < 0) { error_errno(_("failed writing detached signature to '%s'"), temp->filename.buf); delete_tempfile(&temp); return -1; } argv_array_pushl(&gpg.args, gpg_program, "--status-fd=1", "--keyid-format=long", "--verify", temp->filename.buf, "-", NULL); if (!gpg_status) gpg_status = &buf; sigchain_push(SIGPIPE, SIG_IGN); ret = pipe_command(&gpg, payload, payload_size, gpg_status, 0, gpg_output, 0); sigchain_pop(SIGPIPE); delete_tempfile(&temp); ret |= !strstr(gpg_status->buf, "\n[GNUPG:] GOODSIG "); strbuf_release(&buf); /* no matter it was used or not */ return ret; }
static struct sockaddr *get_socket_peer_address(int fd, struct error *err) { struct sockaddr_storage ss; socklen_t len = sizeof ss; if (getpeername(fd, (struct sockaddr *)&ss, &len) >= 0) return copy_sockaddr(&ss, len, err); error_errno(err, "getpeername"); return NULL; }
int read_mmfile(mmfile_t *ptr, const char *filename) { struct stat st; FILE *f; size_t sz; if (stat(filename, &st)) return error_errno("Could not stat %s", filename); if ((f = fopen(filename, "rb")) == NULL) return error_errno("Could not open %s", filename); sz = xsize_t(st.st_size); ptr->ptr = xmalloc(sz ? sz : 1); if (sz && fread(ptr->ptr, sz, 1, f) != 1) { fclose(f); return error("Could not read %s", filename); } fclose(f); ptr->size = sz; return 0; }
/* * Scan the path for conflicts, do the "handle_path()" thing above, and * return the number of conflict hunks found. */ static int handle_file(struct index_state *istate, const char *path, unsigned char *hash, const char *output) { int has_conflicts = 0; struct rerere_io_file io; int marker_size = ll_merge_marker_size(istate, path); memset(&io, 0, sizeof(io)); io.io.getline = rerere_file_getline; io.input = fopen(path, "r"); io.io.wrerror = 0; if (!io.input) return error_errno(_("could not open '%s'"), path); if (output) { io.io.output = fopen(output, "w"); if (!io.io.output) { error_errno(_("could not write '%s'"), output); fclose(io.input); return -1; } } has_conflicts = handle_path(hash, (struct rerere_io *)&io, marker_size); fclose(io.input); if (io.io.wrerror) error(_("there were errors while writing '%s' (%s)"), path, strerror(io.io.wrerror)); if (io.io.output && fclose(io.io.output)) io.io.wrerror = error_errno(_("failed to flush '%s'"), path); if (has_conflicts < 0) { if (output) unlink_or_warn(output); return error(_("could not parse conflict hunks in '%s'"), path); } if (io.io.wrerror) return -1; return has_conflicts; }
static int create_seq_dir(void) { if (file_exists(git_path_seq_dir())) { error(_("a cherry-pick or revert is already in progress")); advise(_("try \"git cherry-pick (--continue | --quit | --abort)\"")); return -1; } else if (mkdir(git_path_seq_dir(), 0777) < 0) return error_errno(_("could not create sequencer directory '%s'"), git_path_seq_dir()); return 0; }
int cmd_upload_archive(int argc, const char **argv, const char *prefix) { struct child_process writer = { argv }; /* * Set up sideband subprocess. * * We (parent) monitor and read from child, sending its fd#1 and fd#2 * multiplexed out to our fd#1. If the child dies, we tell the other * end over channel #3. */ argv[0] = "upload-archive--writer"; writer.out = writer.err = -1; writer.git_cmd = 1; if (start_command(&writer)) { int err = errno; packet_write_fmt(1, "NACK unable to spawn subprocess\n"); die("upload-archive: %s", strerror(err)); } packet_write_fmt(1, "ACK\n"); packet_flush(1); while (1) { struct pollfd pfd[2]; pfd[0].fd = writer.out; pfd[0].events = POLLIN; pfd[1].fd = writer.err; pfd[1].events = POLLIN; if (poll(pfd, 2, -1) < 0) { if (errno != EINTR) { error_errno("poll failed resuming"); sleep(1); } continue; } if (pfd[1].revents & POLLIN) /* Status stream ready */ if (process_input(pfd[1].fd, 2)) continue; if (pfd[0].revents & POLLIN) /* Data stream ready */ if (process_input(pfd[0].fd, 1)) continue; if (finish_command(&writer)) error_clnt("%s", deadchild); packet_flush(1); break; } return 0; }
static int file_skip(struct output_file *out, int64_t cnt) { off64_t ret; struct output_file_normal *outn = to_output_file_normal(out); ret = lseek64(outn->fd, cnt, SEEK_CUR); if (ret < 0) { error_errno("lseek64"); return -1; } return 0; }
static int gz_file_open(struct output_file *out, int fd) { struct output_file_gz *outgz = to_output_file_gz(out); outgz->gz_fd = gzdopen(fd, "wb9"); if (!outgz->gz_fd) { error_errno("gzopen"); return -errno; } return 0; }
static int make_listening_socket(int family, int socktype, struct error *err) { int fd = make_socket(family, socktype, err); if (fd >= 0 && listen(fd, SOMAXCONN) < 0) { error_errno(err, "listen"); close(fd); fd = -1; } return fd; }
static int gz_file_skip(struct output_file *out, int64_t cnt) { off64_t ret; struct output_file_gz *outgz = to_output_file_gz(out); ret = gzseek(outgz->gz_fd, cnt, SEEK_CUR); if (ret < 0) { error_errno("gzseek"); return -1; } return 0; }
/* this runs in the parent process */ static void child_err_spew(struct child_process *cmd, struct child_err *cerr) { static void (*old_errfn)(const char *err, va_list params); old_errfn = get_error_routine(); set_error_routine(fake_fatal); errno = cerr->syserr; switch (cerr->err) { case CHILD_ERR_CHDIR: error_errno("exec '%s': cd to '%s' failed", cmd->argv[0], cmd->dir); break; case CHILD_ERR_DUP2: error_errno("dup2() in child failed"); break; case CHILD_ERR_CLOSE: error_errno("close() in child failed"); break; case CHILD_ERR_SIGPROCMASK: error_errno("sigprocmask failed restoring signals"); break; case CHILD_ERR_ENOENT: error_errno("cannot run %s", cmd->argv[0]); break; case CHILD_ERR_SILENT: break; case CHILD_ERR_ERRNO: error_errno("cannot exec '%s'", cmd->argv[0]); break; } set_error_routine(old_errfn); }
/* * Scan the path for conflicts, do the "handle_path()" thing above, and * return the number of conflict hunks found. */ static int handle_file(const char *path, unsigned char *sha1, const char *output) { int hunk_no = 0; struct rerere_io_file io; int marker_size = ll_merge_marker_size(path); memset(&io, 0, sizeof(io)); io.io.getline = rerere_file_getline; io.input = fopen(path, "r"); io.io.wrerror = 0; if (!io.input) return error_errno("Could not open %s", path); if (output) { io.io.output = fopen(output, "w"); if (!io.io.output) { error_errno("Could not write %s", output); fclose(io.input); return -1; } } hunk_no = handle_path(sha1, (struct rerere_io *)&io, marker_size); fclose(io.input); if (io.io.wrerror) error("There were errors while writing %s (%s)", path, strerror(io.io.wrerror)); if (io.io.output && fclose(io.io.output)) io.io.wrerror = error_errno("Failed to flush %s", path); if (hunk_no < 0) { if (output) unlink_or_warn(output); return error("Could not parse conflict hunks in %s", path); } if (io.io.wrerror) return -1; return hunk_no; }
static int delete_git_dir(struct worktree *wt) { struct strbuf sb = STRBUF_INIT; int ret = 0; strbuf_addstr(&sb, git_common_path("worktrees/%s", wt->id)); if (remove_dir_recursively(&sb, 0)) { error_errno(_("failed to delete '%s'"), sb.buf); ret = -1; } strbuf_release(&sb); return ret; }
static int save_head(const char *head) { static struct lock_file head_lock; struct strbuf buf = STRBUF_INIT; int fd; fd = hold_lock_file_for_update(&head_lock, git_path_head_file(), 0); if (fd < 0) { rollback_lock_file(&head_lock); return error_errno(_("could not lock HEAD")); } strbuf_addf(&buf, "%s\n", head); if (write_in_full(fd, buf.buf, buf.len) < 0) { rollback_lock_file(&head_lock); return error_errno(_("could not write to '%s'"), git_path_head_file()); } if (commit_lock_file(&head_lock) < 0) { rollback_lock_file(&head_lock); return error(_("failed to finalize '%s'."), git_path_head_file()); } return 0; }
static int write_message(const void *buf, size_t len, const char *filename, int append_eol) { static struct lock_file msg_file; int msg_fd = hold_lock_file_for_update(&msg_file, filename, 0); if (msg_fd < 0) return error_errno(_("could not lock '%s'"), filename); if (write_in_full(msg_fd, buf, len) < 0) { rollback_lock_file(&msg_file); return error_errno(_("could not write to '%s'"), filename); } if (append_eol && write(msg_fd, "\n", 1) < 0) { rollback_lock_file(&msg_file); return error_errno(_("could not write eol to '%s'"), filename); } if (commit_lock_file(&msg_file) < 0) { rollback_lock_file(&msg_file); return error(_("failed to finalize '%s'."), filename); } return 0; }
static enum stream_result simple_socket_close_locked(struct simple_socket *s, struct error *e) { if (s->fd >= 0) { watched_fd_destroy(s->watched_fd); if (close(s->fd) < 0 && e) { error_errno(e, "close"); return STREAM_ERROR; } s->fd = -1; } return STREAM_OK; }
static int populate_from_stdin(struct diff_filespec *s) { struct strbuf buf = STRBUF_INIT; size_t size = 0; if (strbuf_read(&buf, 0, 0) < 0) return error_errno("error while reading from stdin"); s->should_munmap = 0; s->data = strbuf_detach(&buf, &size); s->size = size; s->should_free = 1; s->is_stdin = 1; return 0; }
static int gz_file_write(struct output_file *out, void *data, int len) { int ret; struct output_file_gz *outgz = to_output_file_gz(out); ret = gzwrite(outgz->gz_fd, data, len); if (ret < 0) { error_errno("gzwrite"); return -1; } else if (ret < len) { error("incomplete gzwrite"); return -1; } return 0; }
static int file_write(struct output_file *out, void *data, int len) { int ret; struct output_file_normal *outn = to_output_file_normal(out); ret = write(outn->fd, data, len); if (ret < 0) { error_errno("write"); return -1; } else if (ret < len) { error("incomplete write"); return -1; } return 0; }
int sequencer_rollback(struct replay_opts *opts) { FILE *f; unsigned char sha1[20]; struct strbuf buf = STRBUF_INIT; f = fopen(git_path_head_file(), "r"); if (!f && errno == ENOENT) { /* * There is no multiple-cherry-pick in progress. * If CHERRY_PICK_HEAD or REVERT_HEAD indicates * a single-cherry-pick in progress, abort that. */ return rollback_single_pick(); } if (!f) return error_errno(_("cannot open '%s'"), git_path_head_file()); if (strbuf_getline_lf(&buf, f)) { error(_("cannot read '%s': %s"), git_path_head_file(), ferror(f) ? strerror(errno) : _("unexpected end of file")); fclose(f); goto fail; } fclose(f); if (get_sha1_hex(buf.buf, sha1) || buf.buf[40] != '\0') { error(_("stored pre-cherry-pick HEAD file '%s' is corrupt"), git_path_head_file()); goto fail; } if (is_null_sha1(sha1)) { error(_("cannot abort from a branch yet to be born")); goto fail; } if (!rollback_is_safe()) { /* Do not error, just do not rollback */ warning(_("You seem to have moved HEAD. " "Not rewinding, check your HEAD!")); } else if (reset_for_rollback(sha1)) goto fail; strbuf_release(&buf); return sequencer_remove_state(opts); fail: strbuf_release(&buf); return -1; }
static int bisect_write(const char *state, const char *rev, const struct bisect_terms *terms, int nolog) { struct strbuf tag = STRBUF_INIT; struct object_id oid; struct commit *commit; FILE *fp = NULL; int retval = 0; if (!strcmp(state, terms->term_bad)) { strbuf_addf(&tag, "refs/bisect/%s", state); } else if (one_of(state, terms->term_good, "skip", NULL)) { strbuf_addf(&tag, "refs/bisect/%s-%s", state, rev); } else { retval = error(_("Bad bisect_write argument: %s"), state); goto finish; } if (get_oid(rev, &oid)) { retval = error(_("couldn't get the oid of the rev '%s'"), rev); goto finish; } if (update_ref(NULL, tag.buf, &oid, NULL, 0, UPDATE_REFS_MSG_ON_ERR)) { retval = -1; goto finish; } fp = fopen(git_path_bisect_log(), "a"); if (!fp) { retval = error_errno(_("couldn't open the file '%s'"), git_path_bisect_log()); goto finish; } commit = lookup_commit_reference(the_repository, &oid); log_commit(fp, "%s", state, commit); if (!nolog) fprintf(fp, "git bisect %s %s\n", state, rev); finish: if (fp) fclose(fp); strbuf_release(&tag); return retval; }
static void simple_server_socket_close_locked(struct simple_server_socket *s, struct error *e) { int i; for (i = 0; i < s->n_fds; i++) { int fd = s->fds[i].fd; if (fd >= 0) { watched_fd_destroy(s->fds[i].watched_fd); if (close(fd) < 0 && e) error_errno(e, "close"); } } free(s->fds); s->fds = NULL; }
/* * This is called once for each task startup. Wait until the started * task sends its pid, then enter that into the totalview table. It * might be better to do this in parallel with a service... handler * like some other libraries have, but since this is only for the * debugging case, maybe it is not too terrible to be slow. */ void tv_accept_one(int n) { int pid, ps1; char rpid[11]; ps1 = accept(tv_socket, 0, 0); if (ps1 < 0) error_errno("%s: accept totalview pid", __func__); read_full(ps1, rpid, 10); close(ps1); rpid[10] = '\0'; pid = atoi(rpid); MPIR_proctable[n].host_name = nodes[tasks[n].node].name; MPIR_proctable[n].executable_name = tasks[n].conf->exe; MPIR_proctable[n].pid = pid; MPIR_proctable_size++; }
static bool_t simple_socket_partial_close(struct socket *gs, bool_t read_else_write, struct error *e) { struct simple_socket *s = (struct simple_socket *)gs; bool_t res = TRUE; mutex_lock(&s->mutex); if (shutdown(s->fd, read_else_write ? SHUT_RD : SHUT_WR) < 0) { error_errno(e, "shutdown"); res = FALSE; } mutex_unlock(&s->mutex); return res; }
static void start_connecting(struct connector *c) { for (;;) { struct addrinfo *ai = c->next_addrinfo; if (!ai) break; /* If we have an existing connecting socket, dispose of it. */ connector_close(c); c->next_addrinfo = ai->ai_next; error_reset(&c->err); c->fd = make_socket(ai->ai_family, ai->ai_socktype, &c->err); if (c->fd < 0) continue; c->watched_fd = watched_fd_create(c->fd, connector_handle_events, c); if (connect(c->fd, ai->ai_addr, ai->ai_addrlen) >= 0) { /* Immediately connected. Not sure this can actually happen. */ wait_list_up(&c->connecting, 1); return; } else if (would_block()) { /* Writeability will indicate that the connection has * been established. */ if (!watched_fd_set_interest(c->watched_fd, WATCHED_FD_OUT, &c->err)) /* Give up and propagate the error */ break; return; } else { error_errno(&c->err, "connect"); } } /* Ran out of addresses to try, so we are done. We should have an error to report. */ assert(!error_ok(&c->err)); simple_socket_wake_all(&c->socket->base); }
static int wait_or_whine(pid_t pid, const char *argv0, int in_signal) { int status, code = -1; pid_t waiting; int failed_errno = 0; while ((waiting = waitpid(pid, &status, 0)) < 0 && errno == EINTR) ; /* nothing */ if (in_signal) return 0; if (waiting < 0) { failed_errno = errno; error_errno("waitpid for %s failed", argv0); } else if (waiting != pid) { error("waitpid is confused (%s)", argv0); } else if (WIFSIGNALED(status)) { code = WTERMSIG(status); if (code != SIGINT && code != SIGQUIT && code != SIGPIPE) error("%s died of signal %d", argv0, code); /* * This return value is chosen so that code & 0xff * mimics the exit code that a POSIX shell would report for * a program that died from this signal. */ code += 128; } else if (WIFEXITED(status)) { code = WEXITSTATUS(status); /* * Convert special exit code when execvp failed. */ if (code == 127) { code = -1; failed_errno = ENOENT; } } else { error("waitpid is confused (%s)", argv0); } clear_child_for_cleanup(pid); errno = failed_errno; return code; }
static int write_terms(const char *bad, const char *good) { FILE *fp = NULL; int res; if (!strcmp(bad, good)) return error(_("please use two different terms")); if (check_term_format(bad, "bad") || check_term_format(good, "good")) return -1; fp = fopen(git_path_bisect_terms(), "w"); if (!fp) return error_errno(_("could not open the file BISECT_TERMS")); res = fprintf(fp, "%s\n%s\n", bad, good); res |= fclose(fp); return (res < 0) ? -1 : 0; }