aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2004-10-18 23:14:51 +0000
committerKen Raeburn <raeburn@mit.edu>2004-10-18 23:14:51 +0000
commitfb8314743c17c15ebcfcebee3565069079a819fc (patch)
tree55f0b504462f595df9414882a9140036b361bbf2
parent32e9f9545401a17df3443a8e2969d6f84b29e74a (diff)
downloadkrb5-fb8314743c17c15ebcfcebee3565069079a819fc.zip
krb5-fb8314743c17c15ebcfcebee3565069079a819fc.tar.gz
krb5-fb8314743c17c15ebcfcebee3565069079a819fc.tar.bz2
Allow profile library caller to write the modified data to a different
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
-rw-r--r--src/util/profile/ChangeLog16
-rw-r--r--src/util/profile/prof_file.c80
-rw-r--r--src/util/profile/prof_init.c13
-rw-r--r--src/util/profile/prof_int.h4
-rw-r--r--src/util/profile/prof_test18
-rw-r--r--src/util/profile/profile.hin2
-rw-r--r--src/util/profile/profile.swg1
-rw-r--r--src/util/profile/profile_tcl.c26
8 files changed, 122 insertions, 28 deletions
diff --git a/src/util/profile/ChangeLog b/src/util/profile/ChangeLog
index 54533de..3ebbb45 100644
--- a/src/util/profile/ChangeLog
+++ b/src/util/profile/ChangeLog
@@ -1,3 +1,19 @@
+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
diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c
index d8386dc..55fd345 100644
--- a/src/util/profile/prof_file.c
+++ b/src/util/profile/prof_file.c
@@ -367,37 +367,26 @@ make_hard_link(const char *oldpath, const char *newpath)
#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;
@@ -416,17 +405,22 @@ errcode_t profile_flush_file_data(prf_data_t data)
}
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
@@ -434,24 +428,23 @@ errcode_t profile_flush_file_data(prf_data_t data)
#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)
@@ -459,6 +452,43 @@ errout:
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)
{
diff --git a/src/util/profile/prof_init.c b/src/util/profile/prof_init.c
index b65cf0d..6b04d61 100644
--- a/src/util/profile/prof_init.c
+++ b/src/util/profile/prof_init.c
@@ -132,6 +132,19 @@ profile_flush(profile_t profile)
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)
{
diff --git a/src/util/profile/prof_int.h b/src/util/profile/prof_int.h
index 32d71f2..60cadbd 100644
--- a/src/util/profile/prof_int.h
+++ b/src/util/profile/prof_int.h
@@ -189,6 +189,10 @@ errcode_t profile_update_file_data
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);
diff --git a/src/util/profile/prof_test1 b/src/util/profile/prof_test1
index 42a6021..d7d5fa8 100644
--- a/src/util/profile/prof_test1
+++ b/src/util/profile/prof_test1
@@ -35,10 +35,12 @@ proc test1 {} {
}
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:" }
diff --git a/src/util/profile/profile.hin b/src/util/profile/profile.hin
index e8515dd..d5a1b5e 100644
--- a/src/util/profile/profile.hin
+++ b/src/util/profile/profile.hin
@@ -47,6 +47,8 @@ long KRB5_CALLCONV profile_init_path
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);
diff --git a/src/util/profile/profile.swg b/src/util/profile/profile.swg
index 9607343..d6f16b7 100644
--- a/src/util/profile/profile.swg
+++ b/src/util/profile/profile.swg
@@ -151,6 +151,7 @@ typedef struct _profile_t *profile_t;
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! */
diff --git a/src/util/profile/profile_tcl.c b/src/util/profile/profile_tcl.c
index eb74f85..a4c3790 100644
--- a/src/util/profile/profile_tcl.c
+++ b/src/util/profile/profile_tcl.c
@@ -1327,6 +1327,31 @@ _wrap_profile_flush(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj
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 ;
@@ -1991,6 +2016,7 @@ static swig_command_info swig_commands[] = {
{ 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},