+2004-10-15 Ken Raeburn <raeburn@mit.edu>
+
+ * prof_file.c, prof_int.h, prof_set.c: Remove support for
+ non-SHARE_TREE_DATA case.
+ * prof_int.h (struct _prf_data_t): Change filespec to a trailing
+ char array. Add a length field for the filespec.
+ (profile_make_prf_data): Declare.
+ (profile_lock_global, profile_unlock_global): Prototypes need
+ argument lists.
+ * prof_file.c: Include stddef.h.
+ (scan_shared_trees_locked, scan_shared_trees_unlocked): New
+ functions.
+ (r_access, rw_access): Now take const_profile_filespec_t arg.
+ (profile_make_prf_data): New function.
+ (profile_open_file): Scan trees at beginning and end. Use
+ profile_make_prf_data to allocate and initialize storage.
+ (profile_dereference_data, profile_free_file_data): Scan trees.
+ (profile_ser_size, profile_ser_externalize): Filespec is never
+ null.
+ * prof_set.c (rw_setup): Use profile_make_prf_data to allocate
+ and initialize storage.
+
2004-10-13 Alexandra Ellwood <lxs@mit.edu>
* prof_file.c (profile_library_initializer,
#include <unistd.h>
#endif
#include <string.h>
+#include <stddef.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "k5-platform.h"
-#ifdef SHARE_TREE_DATA
struct global_shared_profile_data {
/* This is the head of the global list of shared trees */
prf_data_t trees;
0,
K5_MUTEX_PARTIAL_INITIALIZER
};
-#endif
MAKE_INIT_FUNCTION(profile_library_initializer);
MAKE_FINI_FUNCTION(profile_library_finalizer);
#if !USE_BUNDLE_ERROR_STRINGS
add_error_table(&et_prof_error_table);
#endif
-#ifdef SHARE_TREE_DATA
return k5_mutex_finish_init(&g_shared_trees_mutex);
-#else
- return 0;
-#endif
}
void profile_library_finalizer(void)
{
if (! INITIALIZER_RAN(profile_library_initializer) || PROGRAM_EXITING())
return;
-#ifdef SHARE_TREE_DATA
k5_mutex_destroy(&g_shared_trees_mutex);
-#endif
#if !USE_BUNDLE_ERROR_STRINGS
remove_error_table(&et_prof_error_table);
#endif
static void profile_free_file_data(prf_data_t);
-static int rw_access(profile_filespec_t filespec)
+static void scan_shared_trees_locked(void)
+{
+ prf_data_t d;
+ k5_mutex_assert_locked(&g_shared_trees_mutex);
+ for (d = g_shared_trees; d; d = d->next) {
+ assert(d->magic == PROF_MAGIC_FILE_DATA);
+ assert((d->flags & PROFILE_FILE_SHARED) != 0);
+ assert(d->filespec[0] != 0);
+ assert(d->fslen <= 1000); /* XXX */
+ assert(d->filespec[d->fslen] == 0);
+ assert(d->fslen = strlen(d->filespec));
+ }
+}
+
+static void scan_shared_trees_unlocked(void)
+{
+ int r;
+ r = k5_mutex_lock(&g_shared_trees_mutex);
+ assert (r == 0);
+ scan_shared_trees_locked();
+ k5_mutex_unlock(&g_shared_trees_mutex);
+}
+
+static int rw_access(const_profile_filespec_t filespec)
{
#ifdef HAVE_ACCESS
if (access(filespec, W_OK) == 0)
#endif
}
-#ifdef SHARE_TREE_DATA
-static int r_access(profile_filespec_t filespec)
+static int r_access(const_profile_filespec_t filespec)
{
#ifdef HAVE_ACCESS
if (access(filespec, R_OK) == 0)
return 0;
#endif
}
-#endif /* SHARE_TREE_DATA */
+
+prf_data_t
+profile_make_prf_data(const char *filename)
+{
+ prf_data_t d;
+ size_t len, flen, slen;
+ char *fcopy;
+
+ flen = strlen(filename);
+ slen = offsetof(struct _prf_data_t, filespec);
+ len = slen + flen + 1;
+ if (len < sizeof(struct _prf_data_t))
+ len = sizeof(struct _prf_data_t);
+ d = malloc(len);
+ if (d == NULL)
+ return NULL;
+ memset(d, 0, len);
+ fcopy = (char *) d + slen;
+ assert(fcopy == d->filespec);
+ strcpy(fcopy, filename);
+ d->refcount = 1;
+ d->comment = NULL;
+ d->magic = PROF_MAGIC_FILE_DATA;
+ d->root = NULL;
+ d->next = NULL;
+ d->fslen = flen;
+ return d;
+}
errcode_t profile_open_file(const_profile_filespec_t filespec,
prf_file_t *ret_prof)
if (retval)
return retval;
+ scan_shared_trees_unlocked();
+
prf = malloc(sizeof(struct _prf_file_t));
if (!prf)
return ENOMEM;
} else
memcpy(expanded_filename, filespec, len);
-#ifdef SHARE_TREE_DATA
retval = k5_mutex_lock(&g_shared_trees_mutex);
if (retval) {
free(expanded_filename);
free(prf);
+ scan_shared_trees_unlocked();
return retval;
}
+ scan_shared_trees_locked();
for (data = g_shared_trees; data; data = data->next) {
if (!strcmp(data->filespec, expanded_filename)
/* Check that current uid has read access. */
free(expanded_filename);
prf->data = data;
*ret_prof = prf;
+ scan_shared_trees_unlocked();
return retval;
}
(void) k5_mutex_unlock(&g_shared_trees_mutex);
- data = malloc(sizeof(struct _prf_data_t));
+ data = profile_make_prf_data(expanded_filename);
if (data == NULL) {
free(prf);
free(expanded_filename);
return ENOMEM;
}
- memset(data, 0, sizeof(*data));
+ free(expanded_filename);
prf->data = data;
-#else
- data = prf->data;
-#endif
-
- data->magic = PROF_MAGIC_FILE_DATA;
- data->refcount = 1;
- data->comment = 0;
- data->filespec = expanded_filename;
retval = k5_mutex_init(&data->lock);
if (retval) {
retval = profile_update_file(prf);
if (retval) {
-#ifndef SHARE_TREE_DATA
- k5_mutex_destroy(&data->lock);
-#endif
profile_close_file(prf);
return retval;
}
-#ifdef SHARE_TREE_DATA
retval = k5_mutex_lock(&g_shared_trees_mutex);
if (retval) {
profile_close_file(prf);
+ scan_shared_trees_unlocked();
return retval;
}
+ scan_shared_trees_locked();
data->flags |= PROFILE_FILE_SHARED;
data->next = g_shared_trees;
g_shared_trees = data;
+ scan_shared_trees_locked();
(void) k5_mutex_unlock(&g_shared_trees_mutex);
-#endif
*ret_prof = prf;
return 0;
void profile_dereference_data(prf_data_t data)
{
-#ifdef SHARE_TREE_DATA
int err;
+ scan_shared_trees_unlocked();
err = k5_mutex_lock(&g_shared_trees_mutex);
if (err)
return;
profile_dereference_data_locked(data);
(void) k5_mutex_unlock(&g_shared_trees_mutex);
-#else
- profile_free_file_data(data);
-#endif
+ scan_shared_trees_unlocked();
}
void profile_dereference_data_locked(prf_data_t data)
{
-#ifdef SHARE_TREE_DATA
data->refcount--;
if (data->refcount == 0)
profile_free_file_data(data);
-#else
- profile_free_file_data(data);
-#endif
}
int profile_lock_global()
/* Call with mutex locked! */
static void profile_free_file_data(prf_data_t data)
{
-#ifdef SHARE_TREE_DATA
+ scan_shared_trees_locked();
if (data->flags & PROFILE_FILE_SHARED) {
/* Remove from linked list. */
if (g_shared_trees == data)
}
}
}
-#endif
- if (data->filespec)
- free(data->filespec);
if (data->root)
profile_free_node(data->root);
if (data->comment)
free(data->comment);
data->magic = 0;
-#ifdef SHARE_TREE_DATA
free(data);
-#endif
+ scan_shared_trees_locked();
}
errcode_t profile_close_file(prf_file_t prf)
#define PROFILE_SUPPORTS_FOREIGN_NEWLINES
#endif
-/* N.B.: The locking code for the non-sharing case is not complete.
- Be sure to fix it if you turn off this flag. */
-#define SHARE_TREE_DATA
-
#include "k5-thread.h"
#include "com_err.h"
#include "profile.h"
prf_magic_t magic;
k5_mutex_t lock;
char *comment;
- profile_filespec_t filespec;
struct profile_node *root;
time_t timestamp; /* time tree was last updated from file */
int flags; /* r/w, dirty */
int upd_serial; /* incremented when data changes */
int refcount; /* prf_file_t references */
struct _prf_data_t *next;
+ /* Was: "profile_filespec_t filespec". Now: flexible char
+ array ... except, we need to work in C89, so an array
+ length must be specified. */
+ size_t fslen;
+ const char filespec[sizeof("/etc/krb5.conf")];
};
typedef struct _prf_data_t *prf_data_t;
+prf_data_t profile_make_prf_data(const char *);
struct _prf_file_t {
prf_magic_t magic;
-#ifdef SHARE_TREE_DATA
struct _prf_data_t *data;
-#else
- struct _prf_data_t data[1];
-#endif
struct _prf_file_t *next;
};
void profile_dereference_data (prf_data_t);
void profile_dereference_data_locked (prf_data_t);
-int profile_lock_global();
-int profile_unlock_global();
+int profile_lock_global (void);
+int profile_unlock_global (void);
/* prof_init.c -- included from profile.h */
errcode_t profile_ser_size
return 0;
}
-#ifdef SHARE_TREE_DATA
if ((file->data->flags & PROFILE_FILE_SHARED) != 0) {
prf_data_t new_data;
- new_data = malloc(sizeof(struct _prf_data_t));
+ new_data = profile_make_prf_data(file->data->filespec);
if (new_data == NULL) {
retval = ENOMEM;
} else {
- *new_data = *file->data;
- /* We can blow away the information because update
- will be called further down */
- new_data->comment = NULL;
- new_data->root = NULL;
- new_data->flags &= ~PROFILE_FILE_SHARED;
- new_data->timestamp = 0;
- /* copy the file spec */
- new_data->filespec = malloc(strlen(file->data->filespec) + 1);
- if (new_data->filespec == NULL) {
- retval = ENOMEM;
- } else {
- strcpy (new_data->filespec, file->data->filespec);
+ retval = k5_mutex_init(&new_data->lock);
+ if (retval == 0) {
+ new_data->root = NULL;
+ new_data->flags = file->data->flags & ~PROFILE_FILE_SHARED;
+ new_data->timestamp = 0;
+ new_data->upd_serial = file->data->upd_serial;
}
}
profile_dereference_data_locked(file->data);
file->data = new_data;
}
-#endif /* SHARE_TREE_DATA */
profile_unlock_global();
retval = profile_update_file(file);