Atomically create files when using DAV to stop files being deleted on error
From: https://issues.apache.org/bugzilla/show_bug.cgi?id=39815 Bump PKGREVISION. OK tron@
This commit is contained in:
parent
b0abda62fe
commit
d62c833ad9
4 changed files with 163 additions and 2 deletions
|
@ -1,6 +1,8 @@
|
|||
# $NetBSD: Makefile,v 1.68 2011/08/31 12:52:45 tron Exp $
|
||||
# $NetBSD: Makefile,v 1.69 2011/09/12 17:18:46 sborrill Exp $
|
||||
|
||||
DISTNAME= httpd-2.2.20
|
||||
PKGREVISION= 1
|
||||
|
||||
PKGNAME= ${DISTNAME:S/httpd/apache/}
|
||||
CATEGORIES= www
|
||||
MASTER_SITES= ${MASTER_SITE_APACHE:=httpd/} \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
$NetBSD: distinfo,v 1.40 2011/08/31 12:52:45 tron Exp $
|
||||
$NetBSD: distinfo,v 1.41 2011/09/12 17:18:46 sborrill Exp $
|
||||
|
||||
SHA1 (httpd-2.2.20.tar.bz2) = c8f00a505af6ed3f89f45b640217c388f5cd32b0
|
||||
RMD160 (httpd-2.2.20.tar.bz2) = 299d1a8a9f3a6eb925d63ce96fa8ea4a06ec1f17
|
||||
|
@ -14,3 +14,5 @@ SHA1 (patch-ai) = 4ebc3bd580a298973928eb6d13d2ce745eac0312
|
|||
SHA1 (patch-al) = 56b9f5c2f6fd01fe5067f9210e328cbf674c68f1
|
||||
SHA1 (patch-am) = ab4a2f7e5a1a3064e908b61157e7fd349c0b0c08
|
||||
SHA1 (patch-aw) = ca53d67beeb2c2c4d9adb04d3d79e24a8c427fd4
|
||||
SHA1 (patch-lock.c) = 770ca03f1cb4421879bd5baa5a7c30cc91acb6e1
|
||||
SHA1 (patch-repos.c) = 0e0361b91d4b0fe6c7c55a12fdfd2e6aacc710e1
|
||||
|
|
58
www/apache22/patches/patch-lock.c
Normal file
58
www/apache22/patches/patch-lock.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
$NetBSD: patch-lock.c,v 1.1 2011/09/12 17:18:46 sborrill Exp $
|
||||
|
||||
Atomically create files when using DAV to stop files being deleted on error
|
||||
|
||||
From:
|
||||
https://issues.apache.org/bugzilla/show_bug.cgi?id=39815
|
||||
|
||||
--- modules/dav/fs/lock.c.orig 2007-11-29 21:21:10.000000000 +0100
|
||||
+++ modules/dav/fs/lock.c 2009-07-10 13:42:43.000000000 +0200
|
||||
@@ -398,46 +398,48 @@
|
||||
** to look up lock information for this file.
|
||||
**
|
||||
** (inode/dev not supported or file is lock-null):
|
||||
** apr_datum_t->dvalue = full path
|
||||
**
|
||||
** (inode/dev supported and file exists ):
|
||||
** apr_datum_t->dvalue = inode, dev
|
||||
*/
|
||||
static apr_datum_t dav_fs_build_key(apr_pool_t *p,
|
||||
const dav_resource *resource)
|
||||
{
|
||||
const char *file = dav_fs_pathname(resource);
|
||||
+#if 0
|
||||
apr_datum_t key;
|
||||
apr_finfo_t finfo;
|
||||
apr_status_t rv;
|
||||
|
||||
/* ### use lstat() ?? */
|
||||
/*
|
||||
* XXX: What for platforms with no IDENT (dev/inode)?
|
||||
*/
|
||||
rv = apr_stat(&finfo, file, APR_FINFO_IDENT, p);
|
||||
if ((rv == APR_SUCCESS || rv == APR_INCOMPLETE)
|
||||
&& ((finfo.valid & APR_FINFO_IDENT) == APR_FINFO_IDENT))
|
||||
{
|
||||
/* ### can we use a buffer for this? */
|
||||
key.dsize = 1 + sizeof(finfo.inode) + sizeof(finfo.device);
|
||||
key.dptr = apr_palloc(p, key.dsize);
|
||||
*key.dptr = DAV_TYPE_INODE;
|
||||
memcpy(key.dptr + 1, &finfo.inode, sizeof(finfo.inode));
|
||||
memcpy(key.dptr + 1 + sizeof(finfo.inode), &finfo.device,
|
||||
sizeof(finfo.device));
|
||||
|
||||
return key;
|
||||
}
|
||||
+#endif
|
||||
|
||||
return dav_fs_build_fname_key(p, file);
|
||||
}
|
||||
|
||||
/*
|
||||
** dav_fs_lock_expired: return 1 (true) if the given timeout is in the past
|
||||
** or present (the lock has expired), or 0 (false) if in the future
|
||||
** (the lock has not yet expired).
|
||||
*/
|
||||
static int dav_fs_lock_expired(time_t expires)
|
||||
{
|
||||
return expires != DAV_TIMEOUT_INFINITE && time(NULL) >= expires;
|
99
www/apache22/patches/patch-repos.c
Normal file
99
www/apache22/patches/patch-repos.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
$NetBSD: patch-repos.c,v 1.1 2011/09/12 17:18:46 sborrill Exp $
|
||||
|
||||
Atomically create files when using DAV to stop files being deleted on error
|
||||
|
||||
From:
|
||||
https://issues.apache.org/bugzilla/show_bug.cgi?id=39815
|
||||
|
||||
--- modules/dav/fs/repos.c.orig 2008-08-16 00:12:47.000000000 +0200
|
||||
+++ modules/dav/fs/repos.c 2009-07-10 19:01:24.000000000 +0200
|
||||
@@ -191,6 +191,7 @@
|
||||
apr_pool_t *p;
|
||||
apr_file_t *f;
|
||||
const char *pathname; /* we may need to remove it at close time */
|
||||
+ const char *temppath;
|
||||
};
|
||||
|
||||
/* returns an appropriate HTTP status code given an APR status code for a
|
||||
@@ -841,6 +842,14 @@
|
||||
&& ctx2->pathname[len1] == '/');
|
||||
}
|
||||
|
||||
+static apr_status_t tmpfile_cleanup(void *data) {
|
||||
+ dav_stream *ds = data;
|
||||
+ if (ds->temppath) {
|
||||
+ apr_file_remove(ds->temppath, ds->p);
|
||||
+ }
|
||||
+ return APR_SUCCESS;
|
||||
+}
|
||||
+
|
||||
static dav_error * dav_fs_open_stream(const dav_resource *resource,
|
||||
dav_stream_mode mode,
|
||||
dav_stream **stream)
|
||||
@@ -849,6 +858,7 @@
|
||||
dav_stream *ds = apr_pcalloc(p, sizeof(*ds));
|
||||
apr_int32_t flags;
|
||||
apr_status_t rv;
|
||||
+ char* fpath;
|
||||
|
||||
switch (mode) {
|
||||
default:
|
||||
@@ -865,7 +875,18 @@
|
||||
|
||||
ds->p = p;
|
||||
ds->pathname = resource->info->pathname;
|
||||
- rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p);
|
||||
+ ds->temppath = NULL;
|
||||
+
|
||||
+ if (mode == DAV_MODE_WRITE_TRUNC) {
|
||||
+ fpath = apr_pstrcat(p, ds->pathname, ".tmp.XXXXXX", NULL);
|
||||
+ rv = apr_file_mktemp(&ds->f, fpath, flags, ds->p);
|
||||
+ ds->temppath = fpath;
|
||||
+ apr_pool_cleanup_register(p, ds, tmpfile_cleanup, apr_pool_cleanup_null);
|
||||
+ }
|
||||
+ else {
|
||||
+ rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p);
|
||||
+ }
|
||||
+
|
||||
if (rv != APR_SUCCESS) {
|
||||
return dav_new_error(p, MAP_IO2HTTP(rv), 0,
|
||||
"An error occurred while opening a resource.");
|
||||
@@ -879,16 +900,32 @@
|
||||
|
||||
static dav_error * dav_fs_close_stream(dav_stream *stream, int commit)
|
||||
{
|
||||
+ apr_status_t rv;
|
||||
+
|
||||
apr_file_close(stream->f);
|
||||
|
||||
if (!commit) {
|
||||
- if (apr_file_remove(stream->pathname, stream->p) != APR_SUCCESS) {
|
||||
- /* ### use a better description? */
|
||||
- return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,
|
||||
- "There was a problem removing (rolling "
|
||||
- "back) the resource "
|
||||
- "when it was being closed.");
|
||||
+ if (stream->temppath) {
|
||||
+ apr_pool_cleanup_run(stream->p, stream, tmpfile_cleanup);
|
||||
+ }
|
||||
+ else {
|
||||
+ if (apr_file_remove(stream->pathname, stream->p) != APR_SUCCESS) {
|
||||
+ /* ### use a better description? */
|
||||
+ return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,
|
||||
+ "There was a problem removing (rolling "
|
||||
+ "back) the resource "
|
||||
+ "when it was being closed.");
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ else if (stream->temppath) {
|
||||
+ rv = apr_file_rename(stream->temppath, stream->pathname, stream->p);
|
||||
+ if (rv) {
|
||||
+ return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, rv,
|
||||
+ "There was a problem writing the file "
|
||||
+ "atomically after writes.");
|
||||
}
|
||||
+ apr_pool_cleanup_kill(stream->p, stream, tmpfile_cleanup);
|
||||
}
|
||||
|
||||
return NULL;
|
Loading…
Reference in a new issue