commit 9c52365fc3a72b4e0add781c388032869c081473 from: Stefan Sperling date: Sat Mar 21 10:37:19 2020 UTC properly terminate the ssh process after fetching via SSH commit - 41b0de1256a7a8a9ed3d4c0d66809ebfcbf1a58d commit + 9c52365fc3a72b4e0add781c388032869c081473 blob - a1aea8a8405c27c3618d0bb30e4faaf8d51d9c7a blob + 983a4a7e129892c9da794a8688598423712f4eb2 --- got/got.c +++ got/got.c @@ -940,7 +940,8 @@ cmd_clone(int argc, char *argv[]) struct got_pathlist_head refs, symrefs, wanted_branches; struct got_pathlist_entry *pe; struct got_object_id *pack_hash = NULL; - int ch, fetchfd = -1; + int ch, fetchfd = -1, fetchstatus; + pid_t fetchpid = -1; struct got_fetch_progress_arg fpa; char *git_url = NULL; char *gitconfig_path = NULL; @@ -1077,8 +1078,8 @@ cmd_clone(int argc, char *argv[]) if (error) goto done; - error = got_fetch_connect(&fetchfd, proto, host, port, server_path, - verbosity); + error = got_fetch_connect(&fetchpid, &fetchfd, proto, host, port, + server_path, verbosity); if (error) goto done; @@ -1266,6 +1267,12 @@ cmd_clone(int argc, char *argv[]) printf("Created %s repository '%s'\n", mirror_references ? "mirrored" : "cloned", repo_path); done: + if (fetchpid > 0) { + if (kill(fetchpid, SIGTERM) == -1) + error = got_error_from_errno("kill"); + if (waitpid(fetchpid, &fetchstatus, 0) == -1 && error == NULL) + error = got_error_from_errno("waitpid"); + } if (fetchfd != -1 && close(fetchfd) == -1 && error == NULL) error = got_error_from_errno("close"); if (gitconfig_file && fclose(gitconfig_file) == EOF && error == NULL) @@ -1387,7 +1394,8 @@ cmd_fetch(int argc, char *argv[]) struct got_pathlist_head refs, symrefs, wanted_branches; struct got_pathlist_entry *pe; struct got_object_id *pack_hash = NULL; - int i, ch, fetchfd = -1; + int i, ch, fetchfd = -1, fetchstatus; + pid_t fetchpid = -1; struct got_fetch_progress_arg fpa; int verbosity = 0, fetch_all_branches = 0, list_refs_only = 0; @@ -1532,8 +1540,8 @@ cmd_fetch(int argc, char *argv[]) if (error) goto done; - error = got_fetch_connect(&fetchfd, proto, host, port, server_path, - verbosity); + error = got_fetch_connect(&fetchpid, &fetchfd, proto, host, port, + server_path, verbosity); if (error) goto done; @@ -1634,6 +1642,12 @@ cmd_fetch(int argc, char *argv[]) id_str = NULL; } done: + if (fetchpid > 0) { + if (kill(fetchpid, SIGTERM) == -1) + error = got_error_from_errno("kill"); + if (waitpid(fetchpid, &fetchstatus, 0) == -1 && error == NULL) + error = got_error_from_errno("waitpid"); + } if (fetchfd != -1 && close(fetchfd) == -1 && error == NULL) error = got_error_from_errno("close"); if (repo) blob - 9e26b62a0b5d1a4848d98980cd9a7b5bc73fd1aa blob + a44351f480e1428d56be5b712a963cf8137f1686 --- include/got_fetch.h +++ include/got_fetch.h @@ -43,11 +43,16 @@ const struct got_error *got_fetch_parse_uri(char **, c * A verbosity level can be specified; it currently controls the amount * of -v options passed to ssh(1). If the level is -1 ssh(1) will be run * with the -q option. + * * If successful return an open file descriptor for the connection which can * be passed to other functions below, and must be disposed of with close(2). + * + * If an ssh(1) process was started return its PID as well, in which case + * the caller should eventually send SIGTERM to the procress and wait for + * the process to exit with waitpid(2). Otherwise, return PID -1. */ -const struct got_error *got_fetch_connect(int *, const char *, const char *, - const char *, const char *, int); +const struct got_error *got_fetch_connect(pid_t *, int *, const char *, + const char *, const char *, const char *, int); /* A callback function which gets invoked with progress information to print. */ typedef const struct got_error *(*got_fetch_progress_cb)(void *, blob - fcd9bb07bd25aa7e1ed09ad450f14bebbaf623b4 blob + 1cdd3ca72ccdaa921a1b2f3222aca79c7e483b50 --- lib/fetch.c +++ lib/fetch.c @@ -83,8 +83,8 @@ hassuffix(char *base, char *suf) } static const struct got_error * -dial_ssh(int *fetchfd, const char *host, const char *port, const char *path, - const char *direction, int verbosity) +dial_ssh(pid_t *fetchpid, int *fetchfd, const char *host, const char *port, + const char *path, const char *direction, int verbosity) { const struct got_error *error = NULL; int pid, pfd[2]; @@ -92,6 +92,7 @@ dial_ssh(int *fetchfd, const char *host, const char *p char *argv[11]; int i = 0; + *fetchpid = -1; *fetchfd = -1; if (port == NULL) @@ -135,6 +136,7 @@ dial_ssh(int *fetchfd, const char *host, const char *p abort(); /* not reached */ } else { close(pfd[0]); + *fetchpid = pid; *fetchfd = pfd[1]; return NULL; } @@ -212,16 +214,17 @@ done: } const struct got_error * -got_fetch_connect(int *fetchfd, const char *proto, const char *host, - const char *port, const char *server_path, int verbosity) +got_fetch_connect(pid_t *fetchpid, int *fetchfd, const char *proto, + const char *host, const char *port, const char *server_path, int verbosity) { const struct got_error *err = NULL; + *fetchpid = -1; *fetchfd = -1; if (strcmp(proto, "ssh") == 0 || strcmp(proto, "git+ssh") == 0) - err = dial_ssh(fetchfd, host, port, server_path, "upload", - verbosity); + err = dial_ssh(fetchpid, fetchfd, host, port, server_path, + "upload", verbosity); else if (strcmp(proto, "git") == 0) err = dial_git(fetchfd, host, port, server_path, "upload"); else if (strcmp(proto, "http") == 0 || strcmp(proto, "git+http") == 0)