aboutsummaryrefslogtreecommitdiff
path: root/cache.c
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
Diffstat (limited to 'cache.c')
-rw-r--r--cache.c124
1 files changed, 39 insertions, 85 deletions
diff --git a/cache.c b/cache.c
index e70af13..fa83ddc 100644
--- a/cache.c
+++ b/cache.c
@@ -16,24 +16,22 @@
#include "cgit.h"
#include "cache.h"
#include "html.h"
-#ifdef HAVE_LINUX_SENDFILE
-#include <sys/sendfile.h>
-#endif
#define CACHE_BUFSIZE (1024 * 4)
struct cache_slot {
const char *key;
- size_t keylen;
+ int keylen;
int ttl;
cache_fill_fn fn;
+ void *cbdata;
int cache_fd;
int lock_fd;
- int stdout_fd;
const char *cache_name;
const char *lock_name;
int match;
struct stat cache_st;
+ struct stat lock_st;
int bufsize;
char buf[CACHE_BUFSIZE];
};
@@ -45,7 +43,7 @@ struct cache_slot {
static int open_slot(struct cache_slot *slot)
{
char *bufz;
- ssize_t bufkeylen = -1;
+ int bufkeylen = -1;
slot->cache_fd = open(slot->cache_name, O_RDONLY);
if (slot->cache_fd == -1)
@@ -62,9 +60,8 @@ static int open_slot(struct cache_slot *slot)
if (bufz)
bufkeylen = bufz - slot->buf;
- if (slot->key)
- slot->match = bufkeylen == slot->keylen &&
- !memcmp(slot->key, slot->buf, bufkeylen + 1);
+ slot->match = bufkeylen == slot->keylen &&
+ !memcmp(slot->key, slot->buf, bufkeylen + 1);
return 0;
}
@@ -85,45 +82,22 @@ static int close_slot(struct cache_slot *slot)
/* Print the content of the active cache slot (but skip the key). */
static int print_slot(struct cache_slot *slot)
{
- off_t off;
-#ifdef HAVE_LINUX_SENDFILE
- off_t size;
-#endif
+ ssize_t i, j;
- off = slot->keylen + 1;
-
-#ifdef HAVE_LINUX_SENDFILE
- size = slot->cache_st.st_size;
+ i = lseek(slot->cache_fd, slot->keylen + 1, SEEK_SET);
+ if (i != slot->keylen + 1)
+ return errno;
do {
- ssize_t ret;
- ret = sendfile(STDOUT_FILENO, slot->cache_fd, &off, size - off);
- if (ret < 0) {
- if (errno == EAGAIN || errno == EINTR)
- continue;
- /* Fall back to read/write on EINVAL or ENOSYS */
- if (errno == EINVAL || errno == ENOSYS)
- break;
- return errno;
- }
- if (off == size)
- return 0;
- } while (1);
-#endif
+ i = j = xread(slot->cache_fd, slot->buf, sizeof(slot->buf));
+ if (i > 0)
+ j = xwrite(STDOUT_FILENO, slot->buf, i);
+ } while (i > 0 && j == i);
- if (lseek(slot->cache_fd, off, SEEK_SET) != off)
+ if (i < 0 || j != i)
return errno;
-
- do {
- ssize_t ret;
- ret = xread(slot->cache_fd, slot->buf, sizeof(slot->buf));
- if (ret < 0)
- return errno;
- if (ret == 0)
- return 0;
- if (write_in_full(STDOUT_FILENO, slot->buf, ret) < 0)
- return errno;
- } while (1);
+ else
+ return 0;
}
/* Check if the slot has expired */
@@ -168,25 +142,10 @@ static int close_lock(struct cache_slot *slot)
*/
static int lock_slot(struct cache_slot *slot)
{
- struct flock lock = {
- .l_type = F_WRLCK,
- .l_whence = SEEK_SET,
- .l_start = 0,
- .l_len = 0,
- };
-
- slot->lock_fd = open(slot->lock_name, O_RDWR | O_CREAT,
+ slot->lock_fd = open(slot->lock_name, O_RDWR | O_CREAT | O_EXCL,
S_IRUSR | S_IWUSR);
if (slot->lock_fd == -1)
return errno;
- if (fcntl(slot->lock_fd, F_SETLK, &lock) < 0) {
- int saved_errno = errno;
- close(slot->lock_fd);
- slot->lock_fd = -1;
- return saved_errno;
- }
- if (ftruncate(slot->lock_fd, 0) < 0)
- return errno;
if (xwrite(slot->lock_fd, slot->key, slot->keylen + 1) < 0)
return errno;
return 0;
@@ -205,13 +164,6 @@ static int unlock_slot(struct cache_slot *slot, int replace_old_slot)
else
err = unlink(slot->lock_name);
- /* Restore stdout and close the temporary FD. */
- if (slot->stdout_fd >= 0) {
- dup2(slot->stdout_fd, STDOUT_FILENO);
- close(slot->stdout_fd);
- slot->stdout_fd = -1;
- }
-
if (err)
return errno;
@@ -223,9 +175,11 @@ static int unlock_slot(struct cache_slot *slot, int replace_old_slot)
*/
static int fill_slot(struct cache_slot *slot)
{
+ int tmp;
+
/* Preserve stdout */
- slot->stdout_fd = dup(STDOUT_FILENO);
- if (slot->stdout_fd == -1)
+ tmp = dup(STDOUT_FILENO);
+ if (tmp == -1)
return errno;
/* Redirect stdout to lockfile */
@@ -233,14 +187,14 @@ static int fill_slot(struct cache_slot *slot)
return errno;
/* Generate cache content */
- slot->fn();
+ slot->fn(slot->cbdata);
- /* Make sure any buffered data is flushed to the file */
- if (fflush(stdout))
+ /* Restore stdout */
+ if (dup2(tmp, STDOUT_FILENO) == -1)
return errno;
- /* update stat info */
- if (fstat(slot->lock_fd, &slot->cache_st))
+ /* Close the temporary filedescriptor */
+ if (close(tmp))
return errno;
return 0;
@@ -315,7 +269,7 @@ static int process_slot(struct cache_slot *slot)
/* If the cache slot does not exist (or its key doesn't match the
* current key), lets try to create a new cache slot for this
* request. If this fails (for whatever reason), lets just generate
- * the content without caching it and fool the caller to believe
+ * the content without caching it and fool the caller to belive
* everything worked out (but print a warning on stdout).
*/
@@ -323,7 +277,7 @@ static int process_slot(struct cache_slot *slot)
if ((err = lock_slot(slot)) != 0) {
cache_log("[cgit] Unable to lock slot %s: %s (%d)\n",
slot->lock_name, strerror(err), err);
- slot->fn();
+ slot->fn(slot->cbdata);
return 0;
}
@@ -332,7 +286,7 @@ static int process_slot(struct cache_slot *slot)
slot->lock_name, strerror(err), err);
unlock_slot(slot, 0);
close_lock(slot);
- slot->fn();
+ slot->fn(slot->cbdata);
return 0;
}
// We've got a valid cache slot in the lock file, which
@@ -356,7 +310,7 @@ static int process_slot(struct cache_slot *slot)
/* Print cached content to stdout, generate the content if necessary. */
int cache_process(int size, const char *path, const char *key, int ttl,
- cache_fill_fn fn)
+ cache_fill_fn fn, void *cbdata)
{
unsigned long hash;
int i;
@@ -366,15 +320,15 @@ int cache_process(int size, const char *path, const char *key, int ttl,
int result;
/* If the cache is disabled, just generate the content */
- if (size <= 0 || ttl == 0) {
- fn();
+ if (size <= 0) {
+ fn(cbdata);
return 0;
}
/* Verify input, calculate filenames */
if (!path) {
cache_log("[cgit] Cache path not specified, caching is disabled\n");
- fn();
+ fn(cbdata);
return 0;
}
if (!key)
@@ -389,8 +343,8 @@ int cache_process(int size, const char *path, const char *key, int ttl,
strbuf_addbuf(&lockname, &filename);
strbuf_addstr(&lockname, ".lock");
slot.fn = fn;
+ slot.cbdata = cbdata;
slot.ttl = ttl;
- slot.stdout_fd = -1;
slot.cache_name = filename.buf;
slot.lock_name = lockname.buf;
slot.key = key;
@@ -408,12 +362,12 @@ int cache_process(int size, const char *path, const char *key, int ttl,
static char *sprintftime(const char *format, time_t time)
{
static char buf[64];
- struct tm tm;
+ struct tm *tm;
if (!time)
return NULL;
- gmtime_r(&time, &tm);
- strftime(buf, sizeof(buf)-1, format, &tm);
+ tm = gmtime(&time);
+ strftime(buf, sizeof(buf)-1, format, tm);
return buf;
}
@@ -422,7 +376,7 @@ int cache_ls(const char *path)
DIR *dir;
struct dirent *ent;
int err = 0;
- struct cache_slot slot = { NULL };
+ struct cache_slot slot = { 0 };
struct strbuf fullname = STRBUF_INIT;
size_t prefixlen;