improve error handling for gw_get_clone_url()
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
diff --git a/gotweb/gotweb.c b/gotweb/gotweb.c
index f6c445d..5a0d7c2 100644
--- a/gotweb/gotweb.c
+++ b/gotweb/gotweb.c
@@ -172,7 +172,7 @@ static char *gw_get_diff(struct gw_trans *,
static char *gw_get_repo_tags(struct gw_trans *,
struct gw_header *, int, int);
static char *gw_get_repo_heads(struct gw_trans *);
-static char *gw_get_clone_url(struct gw_trans *, char *);
+static const struct got_error *gw_get_clone_url(char **, struct gw_trans *, char *);
static char *gw_get_got_link(struct gw_trans *);
static char *gw_get_site_link(struct gw_trans *);
static char *gw_html_escape(const char *);
@@ -1052,8 +1052,7 @@ done:
"refs/heads", TM_DIFF);
if (error)
goto errored;
- gw_dir->url = gw_get_clone_url(gw_trans, gw_dir->path);
-
+ error = gw_get_clone_url(&gw_dir->url, gw_trans, gw_dir->path);
errored:
free(dir_test);
if (opened)
@@ -1806,36 +1805,55 @@ err:
return strdup("");
}
-static char *
-gw_get_clone_url(struct gw_trans *gw_trans, char *dir)
+static const struct got_error *
+gw_get_clone_url(char **url, struct gw_trans *gw_trans, char *dir)
{
+ const struct got_error *error = NULL;
FILE *f;
- char *url = NULL, *d_file = NULL;
+ char *d_file = NULL;
unsigned int len;
+ size_t n;
+
+ *url = NULL;
if (asprintf(&d_file, "%s/cloneurl", dir) == -1)
- return NULL;
+ return got_error_from_errno("asprintf");
- if ((f = fopen(d_file, "r")) == NULL)
- return NULL;
+ f = fopen(d_file, "r");
+ if (f == NULL) {
+ if (errno != ENOENT && errno != EACCES)
+ error = got_error_from_errno2("fopen", d_file);
+ goto done;
+ }
- if (fseek(f, 0, SEEK_END) == -1)
- return NULL;
- len = ftell(f) + 1;
- if (ferror(f))
- return NULL;
- if (fseek(f, 0, SEEK_SET) == -1)
- return NULL;
+ if (fseek(f, 0, SEEK_END) == -1) {
+ error = got_ferror(f, GOT_ERR_IO);
+ goto done;
+ }
+ len = ftell(f);
+ if (len == -1) {
+ error = got_ferror(f, GOT_ERR_IO);
+ goto done;
+ }
+ if (fseek(f, 0, SEEK_SET) == -1) {
+ error = got_ferror(f, GOT_ERR_IO);
+ goto done;
+ }
- if ((url = calloc(len, sizeof(char *))) == NULL)
- return NULL;
+ *url = calloc(len + 1, sizeof(**url));
+ if (*url == NULL) {
+ error = got_error_from_errno("calloc");
+ goto done;
+ }
- fread(url, 1, len, f);
- if (ferror(f))
- return NULL;
- fclose(f);
+ n = fread(*url, 1, len, f);
+ if (n == 0 && ferror(f))
+ error = got_ferror(f, GOT_ERR_IO);
+done:
+ if (f && fclose(f) == -1 && error == NULL)
+ error = got_error_from_errno("fclose");
free(d_file);
- return url;
+ return NULL;
}
static char *