make protocol dial helpers return struct got_error style errors
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
diff --git a/include/got_error.h b/include/got_error.h
index 71d6431..303c590 100644
--- a/include/got_error.h
+++ b/include/got_error.h
@@ -135,6 +135,7 @@
#define GOT_ERR_REBASE_OUT_OF_DATE 118
#define GOT_ERR_CACHE_DUP_ENTRY 119
#define GOT_ERR_QUERYSTRING 120
+#define GOT_ERR_ADDRINFO 121
static const struct got_error {
int code;
@@ -276,6 +277,7 @@ static const struct got_error {
{ GOT_ERR_FETCH_FAILED, "fetch failed" },
{ GOT_ERR_PARSE_URI, "failed to parse uri" },
{ GOT_ERR_BAD_PROTO, "unknown protocol" },
+ { GOT_ERR_ADDRINFO, "getaddrinfo failed" },
};
/*
diff --git a/lib/fetch.c b/lib/fetch.c
index 8276f9a..4dec035 100644
--- a/lib/fetch.c
+++ b/lib/fetch.c
@@ -25,6 +25,7 @@
#include <sys/socket.h>
#include <errno.h>
+#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
@@ -135,42 +136,58 @@ grab(char *dst, int n, char *p, char *e)
return strlcpy(dst, p, l + 1);
}
-static int
-got_dial_ssh(char *host, char *port, char *path, char *direction)
+static const struct got_error *
+dial_ssh(int *fetchfd, char *host, char *port, char *path, char *direction)
{
+ const struct got_error *error = NULL;
int pid, pfd[2];
char cmd[64];
+ *fetchfd = -1;
+
if (pipe(pfd) == -1)
- return -1;
+ return got_error_from_errno("pipe");
+
pid = fork();
- if (pid == -1)
- return -1;
- if (pid == 0) {
+ if (pid == -1) {
+ error = got_error_from_errno("fork");
+ close(pfd[0]);
+ close(pfd[1]);
+ return error;
+ } else if (pid == 0) {
+ int n;
close(pfd[1]);
dup2(pfd[0], 0);
dup2(pfd[0], 1);
- snprintf(cmd, sizeof(cmd), "git-%s-pack", direction);
- execlp("ssh", "ssh", host, cmd, path, NULL);
- abort();
- }else{
+ n = snprintf(cmd, sizeof(cmd), "git-%s-pack", direction);
+ if (n < 0 || n >= sizeof(cmd))
+ err(1, "snprintf");
+ if (execlp("ssh", "ssh", host, cmd, path, NULL) == -1)
+ err(1, "execlp");
+ abort(); /* not reached */
+ } else {
close(pfd[0]);
- return pfd[1];
+ *fetchfd = pfd[1];
+ return NULL;
}
}
-static int
-got_dial_git(char *host, char *port, char *path, char *direction)
+static const struct got_error *
+dial_git(int *fetchfd, char *host, char *port, char *path, char *direction)
{
+ const struct got_error *err = NULL;
struct addrinfo hints, *servinfo, *p;
- char *cmd, *pkt;
- int fd, l, r;
+ char *cmd = NULL, *pkt = NULL;
+ int fd = -1, l, r, eaicode;
+
+ *fetchfd = -1;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
- if (getaddrinfo(host, port, &hints, &servinfo) != 0)
- return -1;
+ eaicode = getaddrinfo(host, port, &hints, &servinfo);
+ if (eaicode)
+ return got_error_msg(GOT_ERR_ADDRINFO, gai_strerror(eaicode));
for (p = servinfo; p != NULL; p = p->ai_next) {
if ((fd = socket(p->ai_family, p->ai_socktype,
@@ -178,23 +195,32 @@ got_dial_git(char *host, char *port, char *path, char *direction)
continue;
if (connect(fd, p->ai_addr, p->ai_addrlen) == 0)
break;
+ err = got_error_from_errno("connect");
close(fd);
}
if (p == NULL)
- return -1;
+ goto done;
- if ((l = asprintf(&cmd, "git-%s-pack %s\n", direction, path)) == -1)
- return -1;
- if ((l = asprintf(&pkt, "%04x%s", l+4, cmd)) == -1)
- return -1;
+ if ((l = asprintf(&cmd, "git-%s-pack %s\n", direction, path)) == -1) {
+ err = got_error_from_errno("asprintf");
+ goto done;
+ }
+ if ((l = asprintf(&pkt, "%04x%s", l + 4, cmd)) == -1) {
+ err = got_error_from_errno("asprintf");
+ goto done;
+ }
r = write(fd, pkt, l);
+ if (r == -1)
+ err = got_error_from_errno("write");
+done:
free(cmd);
free(pkt);
- if (r == -1) {
- close(fd);
- return -1;
- }
- return fd;
+ if (err) {
+ if (fd != -1)
+ close(fd);
+ } else
+ *fetchfd = fd;
+ return err;
}
int
@@ -291,9 +317,9 @@ got_fetch(char *uri, char *branch_filter, char *destdir)
return got_error_from_errno("dup");
if (strcmp(proto, "ssh") == 0 || strcmp(proto, "git+ssh") == 0)
- fetchfd = got_dial_ssh(host, port, path, "upload");
+ err = dial_ssh(&fetchfd, host, port, path, "upload");
else if (strcmp(proto, "git") == 0)
- fetchfd = got_dial_git(host, port, path, "upload");
+ err = dial_git(&fetchfd, host, port, path, "upload");
else if (strcmp(proto, "http") == 0 || strcmp(proto, "git+http") == 0)
err = got_error(GOT_ERR_BAD_PROTO);
else