file than was originally read.
* prof_file.c (write_data_to_file): New function, split out from
profile_flush_file_data. Add argument can_create indicating whether the old
file should already exist or not.
(profile_flush_file_data): Call it.
(profile_flush_file_data_to_file): New function.
* prof_int.h (profile_flush_file_data_to_file): Declare it.
(profile_flush_file_to_file): New macro.
* prof_init.c (profile_flush_to_file): New function.
* profile.hin (profile_flush_to_file): Declare.
* profile.swg (profile_flush_to_file): Declare.
* profile_tcl.c: Regenerated.
* prof_test1: Use profile_flush_to_file instead of profile_flush, and reload
from the new filename.
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16825
dc483132-0cff-0310-8789-
dd5450dbe970
+2004-10-18 Ken Raeburn <raeburn@mit.edu>
+
+ * prof_file.c (write_data_to_file): New function, split out from
+ profile_flush_file_data. Add argument can_create indicating
+ whether the old file should already exist or not.
+ (profile_flush_file_data): Call it.
+ (profile_flush_file_data_to_file): New function.
+ * prof_int.h (profile_flush_file_data_to_file): Declare it.
+ (profile_flush_file_to_file): New macro.
+ * prof_init.c (profile_flush_to_file): New function.
+ * profile.hin (profile_flush_to_file): Declare.
+ * profile.swg (profile_flush_to_file): Declare.
+ * profile_tcl.c: Regenerated.
+ * prof_test1: Use profile_flush_to_file instead of profile_flush,
+ and reload from the new filename.
+
2004-10-15 Ken Raeburn <raeburn@mit.edu>
* prof_file.c, prof_int.h, prof_set.c: Remove support for
#endif
}
-errcode_t profile_flush_file_data(prf_data_t data)
+static errcode_t write_data_to_file(prf_data_t data, const char *outfile,
+ int can_create)
{
FILE *f;
profile_filespec_t new_file;
profile_filespec_t old_file;
errcode_t retval = 0;
- if (!data || data->magic != PROF_MAGIC_FILE_DATA)
- return PROF_MAGIC_FILE_DATA;
-
- retval = k5_mutex_lock(&data->lock);
- if (retval)
- return retval;
-
- if ((data->flags & PROFILE_FILE_DIRTY) == 0) {
- k5_mutex_unlock(&data->lock);
- return 0;
- }
-
retval = ENOMEM;
new_file = old_file = 0;
- new_file = malloc(strlen(data->filespec) + 5);
+ new_file = malloc(strlen(outfile) + 5);
if (!new_file)
goto errout;
- old_file = malloc(strlen(data->filespec) + 5);
+ old_file = malloc(strlen(outfile) + 5);
if (!old_file)
goto errout;
- sprintf(new_file, "%s.$$$", data->filespec);
- sprintf(old_file, "%s.bak", data->filespec);
+ sprintf(new_file, "%s.$$$", outfile);
+ sprintf(old_file, "%s.bak", outfile);
errno = 0;
}
unlink(old_file);
- if (make_hard_link(data->filespec, old_file) == 0) {
+ if (make_hard_link(outfile, old_file) == 0) {
/* Okay, got the hard link. Yay. Now we've got our
backup version, so just put the new version in
place. */
- if (rename(new_file, data->filespec)) {
+ if (rename(new_file, outfile)) {
/* Weird, the rename didn't work. But the old version
should still be in place, so no special cleanup is
needed. */
retval = errno;
goto errout;
}
+ } else if (errno == ENOENT && can_create) {
+ if (rename(new_file, outfile)) {
+ retval = errno;
+ goto errout;
+ }
} else {
/* Couldn't make the hard link, so there's going to be a
small window where data->filespec does not refer to
#ifndef _WIN32
sync();
#endif
- if (rename(data->filespec, old_file)) {
+ if (rename(outfile, old_file)) {
retval = errno;
goto errout;
}
- if (rename(new_file, data->filespec)) {
+ if (rename(new_file, outfile)) {
retval = errno;
- rename(old_file, data->filespec); /* back out... */
+ rename(old_file, outfile); /* back out... */
goto errout;
}
}
data->flags = 0;
- if (rw_access(data->filespec))
+ if (rw_access(outfile))
data->flags |= PROFILE_FILE_RW;
retval = 0;
-
+
errout:
- k5_mutex_unlock(&data->lock);
if (new_file)
free(new_file);
if (old_file)
return retval;
}
+errcode_t profile_flush_file_data(prf_data_t data)
+{
+ errcode_t retval = 0;
+
+ if (!data || data->magic != PROF_MAGIC_FILE_DATA)
+ return PROF_MAGIC_FILE_DATA;
+
+ retval = k5_mutex_lock(&data->lock);
+ if (retval)
+ return retval;
+
+ if ((data->flags & PROFILE_FILE_DIRTY) == 0) {
+ k5_mutex_unlock(&data->lock);
+ return 0;
+ }
+
+ retval = write_data_to_file(data, data->filespec, 0);
+ k5_mutex_unlock(&data->lock);
+ return retval;
+}
+
+errcode_t profile_flush_file_data_to_file(prf_data_t data, const char *outfile)
+{
+ errcode_t retval = 0;
+
+ if (!data || data->magic != PROF_MAGIC_FILE_DATA)
+ return PROF_MAGIC_FILE_DATA;
+
+ retval = k5_mutex_lock(&data->lock);
+ if (retval)
+ return retval;
+ retval = write_data_to_file(data, outfile, 1);
+ k5_mutex_unlock(&data->lock);
+ return retval;
+}
+
+
void profile_dereference_data(prf_data_t data)
{
return 0;
}
+errcode_t KRB5_CALLCONV
+profile_flush_to_file(profile_t profile, const_profile_filespec_t outfile)
+{
+ if (!profile || profile->magic != PROF_MAGIC_PROFILE)
+ return PROF_MAGIC_PROFILE;
+
+ if (profile->first_file)
+ return profile_flush_file_to_file(profile->first_file,
+ outfile);
+
+ return 0;
+}
+
void KRB5_CALLCONV
profile_abandon(profile_t profile)
{
errcode_t profile_flush_file_data
(prf_data_t data);
+#define profile_flush_file_to_file(P,F) (((P) && (P)->magic == PROF_MAGIC_FILE) ? profile_flush_file_data_to_file((P)->data, (F)) : PROF_MAGIC_FILE)
+errcode_t profile_flush_file_data_to_file
+ (prf_data_t data, const char *outfile);
+
void profile_free_file
(prf_file_t profile);
}
if $verbose { puts "" }
#profile_iterator_free $iter
- profile_flush $p
+ catch {file delete $wd/test3.ini}
+ profile_flush_to_file $p $wd/test3.ini
+ profile_release $p
- if $verbose { puts "Reloading profile" }
- set p [profile_init_path $wd/test2.ini]
+ if $verbose { puts "Reloading new profile" }
+ set p [profile_init_path $wd/test3.ini]
set iter [profile_iterator_create $p $sect 0]
set done 0
if $verbose { puts "Iterating again:" }
long KRB5_CALLCONV profile_flush
(profile_t profile);
+long KRB5_CALLCONV profile_flush_to_file
+ (profile_t profile, const_profile_filespec_t outfile);
void KRB5_CALLCONV profile_abandon
(profile_t profile);
errcode_t profile_init_path(const char *path = NULL, profile_t *OUTPUT);
errcode_t profile_init(const char **nullterm = NULL, profile_t *OUTPUT);
errcode_t profile_flush(profile_t);
+errcode_t profile_flush_to_file(profile_t, const char *path);
/* Nota bene: There is nothing at all in this code to prevent a script
from accessing a profile object after calling one of these routines
to destroy it! */
}
+static int
+_wrap_profile_flush_to_file(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
+ profile_t arg1 = (profile_t) 0 ;
+ char *arg2 ;
+ errcode_t result;
+
+ if (SWIG_GetArgs(interp, objc, objv,"os:profile_flush_to_file profile_t path ",0,&arg2) == TCL_ERROR) SWIG_fail;
+ if ((SWIG_ConvertPtr(objv[1], (void **) &arg1, SWIGTYPE_profile_t,SWIG_POINTER_EXCEPTION | 0) != TCL_OK)) SWIG_fail;
+ result = (errcode_t)profile_flush_to_file(arg1,(char const *)arg2);
+
+ {
+ /* out errcode_t result */
+ if (result) {
+ /* There could be a memory leak here in the SWIG-Tcl layer,
+ I'm not sure. Not going to worry about it though. */
+ Tcl_SetResult(interp, error_message(result), TCL_STATIC);
+ SWIG_fail;
+ }
+ }
+ return TCL_OK;
+ fail:
+ return TCL_ERROR;
+}
+
+
static int
_wrap_profile_abandon(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
profile_t arg1 = (profile_t) 0 ;
{ SWIG_prefix "profile_init_path", (swig_wrapper_func) _wrap_profile_init_path, NULL},
{ SWIG_prefix "profile_init", (swig_wrapper_func) _wrap_profile_init, NULL},
{ SWIG_prefix "profile_flush", (swig_wrapper_func) _wrap_profile_flush, NULL},
+ { SWIG_prefix "profile_flush_to_file", (swig_wrapper_func) _wrap_profile_flush_to_file, NULL},
{ SWIG_prefix "profile_abandon", (swig_wrapper_func) _wrap_profile_abandon, NULL},
{ SWIG_prefix "profile_release", (swig_wrapper_func) _wrap_profile_release, NULL},
{ SWIG_prefix "profile_get_values", (swig_wrapper_func) _wrap_profile_get_values, NULL},