Index: modules/dav/fs/repos.c =================================================================== --- modules/dav/fs/repos.c (revision 414468) +++ modules/dav/fs/repos.c (working copy) @@ -181,6 +181,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 @@ -839,6 +840,7 @@ dav_stream *ds = apr_pcalloc(p, sizeof(*ds)); apr_int32_t flags; apr_status_t rv; + char* fpath; switch (mode) { default: @@ -855,7 +857,17 @@ 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; + } + 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."); @@ -869,6 +881,8 @@ static dav_error * dav_fs_close_stream(dav_stream *stream, int commit) { + apr_status_t rv; + apr_file_close(stream->f); if (!commit) { @@ -880,7 +894,16 @@ "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."); + } + } + return NULL; }