author | Lars Hjemli <hjemli@gmail.com> | 2008-05-18 21:59:11 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2008-05-18 21:59:11 (UTC) |
commit | af2e75616d1bfb7dc79d299d10ae0bd39bef47bc (patch) (unidiff) | |
tree | 6330a6f9bc1b2b16434df055ee48129e2e3b827e | |
parent | cdc6b2f8e7a8d43dcfe0475a9d3498333ea686b8 (diff) | |
download | cgit-af2e75616d1bfb7dc79d299d10ae0bd39bef47bc.zip cgit-af2e75616d1bfb7dc79d299d10ae0bd39bef47bc.tar.gz cgit-af2e75616d1bfb7dc79d299d10ae0bd39bef47bc.tar.bz2 |
cache.c: do not ignore errors from print_slot()
If print_slot() fails, the client will be served an inferior response.
This patch makes sure that such an error will be returned to main(), which
in turn will try to inform about the error in the response itself.
The error is also printed to the cache_log, i.e. stderr, which will make
the error message appear in error_log (atleast when httpd==apache).
Noticed-by: Jim Meyering <jim@meyering.net>
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
-rw-r--r-- | cache.c | 16 | ||||
-rw-r--r-- | cgit.c | 4 |
2 files changed, 15 insertions, 5 deletions
@@ -243,27 +243,32 @@ static int process_slot(struct cache_slot *slot) | |||
243 | * lazy and just ignore the new file. | 243 | * lazy and just ignore the new file. |
244 | */ | 244 | */ |
245 | if (is_modified(slot) || fill_slot(slot)) { | 245 | if (is_modified(slot) || fill_slot(slot)) { |
246 | unlock_slot(slot, 0); | 246 | unlock_slot(slot, 0); |
247 | close_lock(slot); | 247 | close_lock(slot); |
248 | } else { | 248 | } else { |
249 | close_slot(slot); | 249 | close_slot(slot); |
250 | unlock_slot(slot, 1); | 250 | unlock_slot(slot, 1); |
251 | slot->cache_fd = slot->lock_fd; | 251 | slot->cache_fd = slot->lock_fd; |
252 | } | 252 | } |
253 | } | 253 | } |
254 | } | 254 | } |
255 | print_slot(slot); | 255 | if ((err = print_slot(slot)) != 0) { |
256 | cache_log("[cgit] error printing cache %s: %s (%d)\n", | ||
257 | slot->cache_name, | ||
258 | strerror(err), | ||
259 | err); | ||
260 | } | ||
256 | close_slot(slot); | 261 | close_slot(slot); |
257 | return 0; | 262 | return err; |
258 | } | 263 | } |
259 | 264 | ||
260 | /* If the cache slot does not exist (or its key doesn't match the | 265 | /* If the cache slot does not exist (or its key doesn't match the |
261 | * current key), lets try to create a new cache slot for this | 266 | * current key), lets try to create a new cache slot for this |
262 | * request. If this fails (for whatever reason), lets just generate | 267 | * request. If this fails (for whatever reason), lets just generate |
263 | * the content without caching it and fool the caller to belive | 268 | * the content without caching it and fool the caller to belive |
264 | * everything worked out (but print a warning on stdout). | 269 | * everything worked out (but print a warning on stdout). |
265 | */ | 270 | */ |
266 | 271 | ||
267 | close_slot(slot); | 272 | close_slot(slot); |
268 | if ((err = lock_slot(slot)) != 0) { | 273 | if ((err = lock_slot(slot)) != 0) { |
269 | cache_log("[cgit] Unable to lock slot %s: %s (%d)\n", | 274 | cache_log("[cgit] Unable to lock slot %s: %s (%d)\n", |
@@ -280,25 +285,30 @@ static int process_slot(struct cache_slot *slot) | |||
280 | slot->fn(slot->cbdata); | 285 | slot->fn(slot->cbdata); |
281 | return 0; | 286 | return 0; |
282 | } | 287 | } |
283 | // We've got a valid cache slot in the lock file, which | 288 | // We've got a valid cache slot in the lock file, which |
284 | // is about to replace the old cache slot. But if we | 289 | // is about to replace the old cache slot. But if we |
285 | // release the lockfile and then try to open the new cache | 290 | // release the lockfile and then try to open the new cache |
286 | // slot, we might get a race condition with a concurrent | 291 | // slot, we might get a race condition with a concurrent |
287 | // writer for the same cache slot (with a different key). | 292 | // writer for the same cache slot (with a different key). |
288 | // Lets avoid such a race by just printing the content of | 293 | // Lets avoid such a race by just printing the content of |
289 | // the lock file. | 294 | // the lock file. |
290 | slot->cache_fd = slot->lock_fd; | 295 | slot->cache_fd = slot->lock_fd; |
291 | unlock_slot(slot, 1); | 296 | unlock_slot(slot, 1); |
292 | err = print_slot(slot); | 297 | if ((err = print_slot(slot)) != 0) { |
298 | cache_log("[cgit] error printing cache %s: %s (%d)\n", | ||
299 | slot->cache_name, | ||
300 | strerror(err), | ||
301 | err); | ||
302 | } | ||
293 | close_slot(slot); | 303 | close_slot(slot); |
294 | return err; | 304 | return err; |
295 | } | 305 | } |
296 | 306 | ||
297 | /* Print cached content to stdout, generate the content if necessary. */ | 307 | /* Print cached content to stdout, generate the content if necessary. */ |
298 | int cache_process(int size, const char *path, const char *key, int ttl, | 308 | int cache_process(int size, const char *path, const char *key, int ttl, |
299 | cache_fill_fn fn, void *cbdata) | 309 | cache_fill_fn fn, void *cbdata) |
300 | { | 310 | { |
301 | unsigned long hash; | 311 | unsigned long hash; |
302 | int len, i; | 312 | int len, i; |
303 | char filename[1024]; | 313 | char filename[1024]; |
304 | char lockname[1024 + 5]; /* 5 = ".lock" */ | 314 | char lockname[1024 + 5]; /* 5 = ".lock" */ |
@@ -371,16 +371,16 @@ int main(int argc, const char **argv) | |||
371 | if (getenv("QUERY_STRING")) | 371 | if (getenv("QUERY_STRING")) |
372 | ctx.qry.raw = xstrdup(getenv("QUERY_STRING")); | 372 | ctx.qry.raw = xstrdup(getenv("QUERY_STRING")); |
373 | cgit_parse_args(argc, argv); | 373 | cgit_parse_args(argc, argv); |
374 | http_parse_querystring(ctx.qry.raw, querystring_cb); | 374 | http_parse_querystring(ctx.qry.raw, querystring_cb); |
375 | 375 | ||
376 | ttl = calc_ttl(); | 376 | ttl = calc_ttl(); |
377 | ctx.page.expires += ttl*60; | 377 | ctx.page.expires += ttl*60; |
378 | if (ctx.cfg.nocache) | 378 | if (ctx.cfg.nocache) |
379 | ctx.cfg.cache_size = 0; | 379 | ctx.cfg.cache_size = 0; |
380 | err = cache_process(ctx.cfg.cache_size, ctx.cfg.cache_root, | 380 | err = cache_process(ctx.cfg.cache_size, ctx.cfg.cache_root, |
381 | ctx.qry.raw, ttl, process_request, &ctx); | 381 | ctx.qry.raw, ttl, process_request, &ctx); |
382 | if (err) | 382 | if (err) |
383 | cache_log("[cgit] error %d - %s\n", | 383 | cgit_print_error(fmt("Error processing page: %s (%d)", |
384 | err, strerror(err)); | 384 | strerror(err), err)); |
385 | return err; | 385 | return err; |
386 | } | 386 | } |