Commit f6347471 authored by Dag Erling Smørgrav's avatar Dag Erling Smørgrav

Untested & undocumented login code. I don't have time to continue working

on it right now, but I want it in the tree so phk doesn't start duplicating
my effort.

git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@41 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 5a0e422d
# $Id$
include_HEADERS = varnishapi.h
include_HEADERS = \
varnish/assert.h \
varnishapi.h
/*
* $Id$
*/
#ifndef VARNISH_ASSERT_H_INCLUDED
#define VARNISH_ASSERT_H_INCLUDED
#ifdef NDEBUG
#define V_ASSERT(test) \
do { /* nothing */ } while (0)
#else
#define V_ASSERT(test) \
do { \
if (!(test)) \
vdb_panic("assertion failed in %s line %d: %s", \
#test, __FILE__, __LINE__); \
} while (0)
#endif
#endif
......@@ -5,6 +5,23 @@
#ifndef VARNISHAPI_H_INCLUDED
#define VARNISHAPI_H_INCLUDED
/* ... */
#define V_DEAD __attribute__ ((noreturn))
/* varnish_debug.c */
void vdb_panic(const char *, ...) V_DEAD;
/* varnish_log.c */
typedef struct vlo_buffer vlo_buffer_t;
vlo_buffer_t *vlo_open(const char *, size_t, int);
ssize_t vlo_write(vlo_buffer_t *, const void *, size_t);
vlo_buffer_t *vlo_attach(const char *);
ssize_t vlo_read(vlo_buffer_t *, const void *, size_t);
#if 0
uuid_t vlo_get_uuid(vlo_buffer_t *);
#endif
int vlo_close(vlo_buffer_t *);
/* varnish_util.c */
int vut_open_lock(const char *, int, int, int);
#endif
......@@ -4,4 +4,7 @@ INCLUDES = -I$(top_srcdir)/include
lib_LTLIBRARIES = libvarnishapi.la
libvarnishapi_la_SOURCES =
libvarnishapi_la_SOURCES = \
varnish_debug.c \
varnish_log.c \
varnish_util.c
/*
* $Id$
*/
#include "config.h"
#include <sys/types.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <varnishapi.h>
void
varnish_panic(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, fmt, ap);
va_end(ap);
signal(SIGABRT, SIG_DFL);
raise(SIGABRT);
}
/*
* $Id$
*/
#include "config.h"
#include <sys/file.h>
#include <sys/mman.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <varnish/assert.h>
#include <varnishapi.h>
#define VLO_MAGIC 0x564c4f00
typedef struct vlo_control vlo_control_t;
/* should this be part of the exported API? */
struct vlo_control {
uint32_t magic;
#if 0
uuid_t uuid;
#endif
uint32_t size;
uint32_t head;
uint32_t tail;
};
struct vlo_buffer {
int mode;
int cfd;
vlo_control_t *ctl;
int bfd;
unsigned char *buf;
uint32_t rpos;
};
/*
* Open a log file for writing; create it if necessary. If the control
* file already exists, try to preserve its state, in case someone is
* already listening.
*/
vlo_buffer_t *
vlo_open(const char *name, size_t size, int perm)
{
char ctlname[PATH_MAX];
vlo_buffer_t *vb;
int page_size;
int i, serr;
page_size = getpagesize();
V_ASSERT(size > 0);
V_ASSERT(size % page_size == 0);
if (snprintf(ctlname, sizeof ctlname, "%s.ctl", name) >= sizeof ctlname) {
errno = ENAMETOOLONG;
return (NULL);
}
if ((vb = malloc(sizeof *vb)) == NULL)
goto out;
vb->mode = O_RDWR;
vb->cfd = -1;
vb->ctl = NULL;
vb->bfd = -1;
vb->buf = NULL;
vb->rpos = 0;
/* open, lock and mmap the control file */
if ((vb->cfd = vut_open_lock(ctlname, O_RDWR|O_CREAT,
LOCK_EX|LOCK_NB, perm)) == -1 ||
ftruncate(vb->cfd, page_size) == -1 ||
(vb->ctl = mmap(NULL, page_size, PROT_READ|PROT_WRITE,
MAP_SHARED, vb->cfd, 0)) == NULL ||
mlock(vb->ctl, page_size) == -1)
goto out;
/* open, lock and mmap the buffer file */
if ((vb->bfd = open(name, O_RDWR|O_CREAT, perm)) == -1 ||
flock(vb->bfd, LOCK_EX) == -1 ||
ftruncate(vb->bfd, size) == -1 ||
(vb->buf = mmap(NULL, size, PROT_READ|PROT_WRITE,
MAP_SHARED, vb->bfd, 0)) == NULL ||
mlock(vb->ctl, size) == -1)
goto out;
/* initialize control structures */
if (vb->ctl->magic != VLO_MAGIC ||
vb->ctl->size != size ||
vb->ctl->head >= size ||
vb->ctl->tail >= size) {
vb->ctl->magic = VLO_MAGIC;
#if 0
vb->ctl->uuid = /* XXX */;
#endif
vb->ctl->size = size;
vb->ctl->head = size - page_size; /* early wraparound */
vb->ctl->tail = vb->ctl->head;
vb->rpos = vb->ctl->tail;
}
/* pre-fault buffer */
for (i = 0; i < size; i += page_size)
vb->buf[i] = '\0';
return (vb);
out:
serr = errno;
if (vb != NULL) {
if (vb->buf != NULL) {
munlock(vb->buf, size);
munmap(vb->buf, size);
}
if (vb->bfd != -1)
close(vb->bfd);
if (vb->ctl != NULL) {
munlock(vb->ctl, page_size);
munmap(vb->ctl, page_size);
}
if (vb->cfd != -1)
close(vb->cfd);
free(vb);
}
errno = serr;
return (NULL);
}
/*
* Write to a log file.
*/
ssize_t
vlo_write(vlo_buffer_t *vb, const void *data, size_t len)
{
ssize_t result;
size_t copylen;
V_ASSERT(vb != NULL);
V_ASSERT(vb->mode == O_WRONLY || vb->mode == O_RDWR);
V_ASSERT(vb->cfd != -1 && vb->ctl != NULL);
V_ASSERT(vb->bfd != -1 && vb->buf != NULL);
V_ASSERT(vb->ctl->magic == VLO_MAGIC);
for (result = 0; len > 0; len -= copylen, result += copylen) {
if (vb->ctl->head + len > vb->ctl->size)
copylen = vb->ctl->size - vb->ctl->head;
else
copylen = len;
if (vb->ctl->tail > vb->ctl->head &&
vb->ctl->tail <= vb->ctl->head + copylen)
vb->ctl->tail =
(vb->ctl->head + copylen + 1) % vb->ctl->size;
memcpy(vb->buf + vb->ctl->head, data, copylen);
vb->ctl->head = (vb->ctl->head + copylen) % vb->ctl->size;
}
return (result);
}
/*
* Attach to an existing log buffer.
*/
vlo_buffer_t *
vlo_attach(const char *name)
{
char ctlname[PATH_MAX];
vlo_buffer_t *vb;
int page_size;
int serr;
page_size = getpagesize();
if (snprintf(ctlname, sizeof ctlname, "%s.ctl", name) >= sizeof ctlname) {
errno = ENAMETOOLONG;
return (NULL);
}
if ((vb = malloc(sizeof *vb)) == NULL)
goto out;
vb->mode = O_RDONLY;
vb->cfd = -1;
vb->ctl = NULL;
vb->bfd = -1;
vb->buf = NULL;
vb->rpos = 0;
/* open, lock and mmap the control file */
if ((vb->cfd = open(ctlname, O_RDONLY)) == -1 ||
(vb->ctl = mmap(NULL, page_size, PROT_READ,
MAP_SHARED, vb->cfd, 0)) == NULL ||
mlock(vb->ctl, page_size) == -1)
goto out;
/* verify control structure */
if (vb->ctl->magic != VLO_MAGIC ||
!(vb->ctl->size > 0 && (vb->ctl->size % page_size) == 0)) {
errno = EINVAL; /* XXX document */
goto out;
}
/* open, lock and mmap the buffer file */
if ((vb->bfd = open(name, O_RDONLY)) == -1 ||
(vb->buf = mmap(NULL, vb->ctl->size, PROT_READ,
MAP_SHARED, vb->bfd, 0)) == NULL ||
mlock(vb->ctl, vb->ctl->size) == -1)
goto out;
vb->rpos = vb->ctl->tail;
return (vb);
out:
serr = errno;
if (vb != NULL) {
if (vb->buf != NULL) {
munlock(vb->buf, vb->ctl->size);
munmap(vb->buf, vb->ctl->size);
}
if (vb->bfd != -1)
close(vb->bfd);
if (vb->ctl != NULL) {
munlock(vb->ctl, page_size);
munmap(vb->ctl, page_size);
}
if (vb->cfd != -1)
close(vb->cfd);
free(vb);
}
errno = serr;
return (NULL);
}
/*
* Read from a log file.
*/
ssize_t
vlo_read(vlo_buffer_t *vb, const void *data, size_t len)
{
V_ASSERT(vb != NULL);
V_ASSERT(vb->mode == O_RDONLY || vb->mode == O_RDWR);
V_ASSERT(vb->cfd != -1 && vb->ctl != NULL);
V_ASSERT(vb->bfd != -1 && vb->buf != NULL);
V_ASSERT(vb->ctl->magic == VLO_MAGIC);
/* not implemented */
return (-1);
}
#if 0
/*
* Return the UUID of the process writing to the log file.
*/
uuid_t
vlo_get_uuid(vlo_buffer *vb)
{
V_ASSERT(vb != NULL);
V_ASSERT(vb->cfd != -1 && vb->ctl != NULL);
V_ASSERT(vb->bfd != -1 && vb->buf != NULL);
V_ASSERT(vb->ctl->magic == VLO_MAGIC);
return (vb->ctl->uuid);
}
#endif
/*
* Close a log file.
*/
int
vlo_close(vlo_buffer_t *vb)
{
int page_size;
page_size = getpagesize();
V_ASSERT(vb != NULL);
V_ASSERT(vb->cfd != -1 && vb->ctl != NULL);
V_ASSERT(vb->bfd != -1 && vb->buf != NULL);
V_ASSERT(vb->ctl->magic == VLO_MAGIC);
munlock(vb->buf, vb->ctl->size);
munmap(vb->buf, vb->ctl->size);
close(vb->bfd);
munlock(vb->ctl, page_size);
munmap(vb->ctl, page_size);
close(vb->cfd);
free(vb);
return (0);
}
/*
* $Id$
*/
#include "config.h"
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <varnishapi.h>
/**
* Open and lock a file.
*/
int
vut_open_lock(const char *name, int mode, int lockop, int perm)
{
struct stat sb, fsb;
int fd, serr;
for (;;) {
if ((fd = open(name, mode, perm)) == -1)
/* not much we can do about that */
return (-1);
while (flock(fd, lockop) == -1) {
if (errno != EINTR) {
serr = errno;
close(fd);
errno = serr;
return (-1);
}
}
if (stat(name, &sb) == -1) {
serr = errno;
close(fd);
errno = serr;
if (errno == ENOENT && (mode & O_CREAT))
/* file was deleted from under our nose */
continue;
return (-1);
}
if (fstat(fd, &fsb) == -1) {
/* serious voodoo is going on*/
serr = errno;
close(fd);
errno = serr;
return (-1);
}
if (sb.st_dev == fsb.st_dev && sb.st_ino == fsb.st_ino)
/* we have the correct file */
return (fd);
close(fd);
}
/* not reached */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment