|
From: <jsa...@us...> - 2008-06-04 23:17:23
|
Revision: 1253
http://como.svn.sourceforge.net/como/?rev=1253&view=rev
Author: jsanjuas
Date: 2008-06-04 16:17:20 -0700 (Wed, 04 Jun 2008)
Log Message:
-----------
. storage is forked again instead of exec'ed
. merged libcomo within base (sepparation no longer necessary)
. changed msg()s in storage to debug()s
. storage-path config keyword now unnecessary
Modified Paths:
--------------
src/branches/2.0/CMakeLists.txt
src/branches/2.0/base/CMakeLists.txt
src/branches/2.0/base/config-lexic.l
src/branches/2.0/base/config-syntax.y
src/branches/2.0/base/config.c
src/branches/2.0/base/query-ondemand.c
src/branches/2.0/base/storage.c
src/branches/2.0/base/supervisor.c
src/branches/2.0/como.conf.cmake
src/branches/2.0/include/comopriv.h
src/branches/2.0/include/comotypes.h
Added Paths:
-----------
src/branches/2.0/base/alc.c
src/branches/2.0/base/array.c
src/branches/2.0/base/como.c
src/branches/2.0/base/eventloop.c
src/branches/2.0/base/hash.c
src/branches/2.0/base/ipc.c
src/branches/2.0/base/log.c
src/branches/2.0/base/mdl.c
src/branches/2.0/base/memory.c
src/branches/2.0/base/pool.c
src/branches/2.0/base/setproctitle.c
src/branches/2.0/base/shmem.c
src/branches/2.0/base/shobj.c
src/branches/2.0/base/socket.c
src/branches/2.0/base/storage-client.c
src/branches/2.0/base/util-io.c
Removed Paths:
-------------
src/branches/2.0/libcomo/
Modified: src/branches/2.0/CMakeLists.txt
===================================================================
--- src/branches/2.0/CMakeLists.txt 2008-06-04 21:37:13 UTC (rev 1252)
+++ src/branches/2.0/CMakeLists.txt 2008-06-04 23:17:20 UTC (rev 1253)
@@ -239,7 +239,6 @@
ADD_SUBDIRECTORY(sniffers)
ADD_SUBDIRECTORY(base)
ADD_SUBDIRECTORY(services)
-ADD_SUBDIRECTORY(libcomo)
ADD_SUBDIRECTORY(lib)
#ADD_SUBDIRECTORY(man)
Modified: src/branches/2.0/base/CMakeLists.txt
===================================================================
--- src/branches/2.0/base/CMakeLists.txt 2008-06-04 21:37:13 UTC (rev 1252)
+++ src/branches/2.0/base/CMakeLists.txt 2008-06-04 23:17:20 UTC (rev 1253)
@@ -7,26 +7,39 @@
INCLUDE_DIRECTORIES(${COMO_SOURCE_DIR}/loadshed)
ENDIF(ENABLE_LOADSHED)
-SET(STORAGE_SRCS
- storage.c
-)
-
SET(COMO_SRCS
+ alc.c
+ array.c
asn.c
capture.c
+ como.c
config.c
+ eventloop.c
export.c
+ hash.c
headerinfo.c
ieee80211frames.c
+ ipc.c
+ log.c
+ mdl.c
+ memory.c
metadesc.c
pktmeta.c
- query.c
+ pool.c
query-comms.c
query-ondemand.c
+ query.c
radio.c
services.c
+ setproctitle.c
+ shmem.c
+ shobj.c
sniffers.c
+ socket.c
+ storage-client.c
+ storage.c
supervisor.c
+ util-io.c
util-process.c
util-timers.c
${COMO_SOURCE_DIR}/lib/uhash.c
@@ -182,8 +195,6 @@
#
ADD_EXECUTABLE(como ${COMO_SRCS})
-ADD_EXECUTABLE(como-storage ${STORAGE_SRCS})
-
#
# Make sure modules can see como's symbols
#
@@ -218,11 +229,8 @@
TARGET_LINK_LIBRARIES(como m)
-TARGET_LINK_LIBRARIES(como comolib)
TARGET_LINK_LIBRARIES(como comomdl)
-TARGET_LINK_LIBRARIES(como-storage comolib)
-
IF(LINUX)
TARGET_LINK_LIBRARIES(como dl)
ENDIF(LINUX)
@@ -250,4 +258,4 @@
# Installation
#
INSTALL_TARGETS(${INST_BINDIR} como)
-INSTALL_TARGETS(${INST_BINDIR} como-storage)
+
Copied: src/branches/2.0/base/alc.c (from rev 1249, src/branches/2.0/libcomo/alc.c)
===================================================================
--- src/branches/2.0/base/alc.c (rev 0)
+++ src/branches/2.0/base/alc.c 2008-06-04 23:17:20 UTC (rev 1253)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2004-2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id:como.c 1032 2006-11-14 13:29:01Z m_canini $
+ */
+
+#include <string.h>
+
+#define LOG_DOMAIN "ALC"
+#include "como.h"
+
+char *
+alc_strdup(alc_t * alc, const char * s)
+{
+ char * o;
+
+ size_t l;
+ l = strlen(s);
+ o = alc_malloc(alc, l + 1);
+ strcpy(o, s);
+
+ return o;
+}
Copied: src/branches/2.0/base/array.c (from rev 1250, src/branches/2.0/libcomo/array.c)
===================================================================
--- src/branches/2.0/base/array.c (rev 0)
+++ src/branches/2.0/base/array.c 2008-06-04 23:17:20 UTC (rev 1253)
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/* Based on eglib's ptr array */
+/*
+ * Pointer Array
+ *
+ * Author:
+ * Aaron Bockover (abo...@no...)
+ *
+ * (C) 2006 Novell, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "como.h"
+#include "comopriv.h"
+
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+
+static void
+array_grow(array_t * array, int length)
+{
+ int off = array->data - array->base;
+ int new_length = array->len + length + (off / array->element_size);
+
+ if (new_length <= array->size) {
+ return;
+ }
+
+ array->size = 1;
+
+ while (array->size < new_length) {
+ array->size <<= 1;
+ }
+
+ array->size = MAX(array->size, 16);
+ array->base = safe_realloc(array->base, array->size * array->element_size);
+ array->data = array->base + off;
+}
+
+array_t *
+array_new(size_t element_size)
+{
+ return array_sized_new(element_size, 0);
+}
+
+array_t *
+array_sized_new(size_t element_size, int reserved_size)
+{
+ array_t *array = como_new0(array_t);
+
+ array->element_size = element_size;
+
+ if (reserved_size > 0) {
+ array_grow(array, reserved_size);
+ }
+
+ return (array_t *) array;
+}
+
+void **
+array_free(array_t * array, int free_seg)
+{
+ void **data = NULL;
+
+ if (array == NULL) {
+ return NULL;
+ }
+ if (free_seg) {
+ free(array->base);
+ } else {
+ if (array->data != array->base) {
+ memmove(array->base, array->data,
+ array->len * array->element_size);
+ }
+ data = array->base;
+ }
+
+ free(array);
+
+ return data;
+}
+
+void
+array_add(array_t * array, void *data)
+{
+ void *x;
+ array_grow(array, 1);
+ x = array->data + (array->len * array->element_size);
+ memcpy(x, data, array->element_size);
+ array->len++;
+}
+
+void
+array_sort(array_t * array, cmp_fn cmpFn)
+{
+ qsort(array->data, array->len, array->element_size, cmpFn);
+}
+
+void
+array_clear(array_t * array, int reserved_size, int zero_seg)
+{
+ if (zero_seg) {
+ memset(array->data, 0, array->len * array->element_size);
+ }
+
+ if (reserved_size > array->size) {
+ array_grow(array, reserved_size - array->size);
+ }
+ array->data = array->base;
+ array->len = 0;
+}
+
+void *
+array_shift_(array_t * array)
+{
+ void *x;
+ x = array->data;
+ array->data += array->element_size;
+ array->len--;
+ return x;
+}
+
+void
+array_remove(array_t *array, int position)
+{
+ void *src, *dst;
+ size_t len;
+
+ len = array->element_size * (array->len - position - 1);
+ dst = array->data + (position * array->element_size);
+ src = array->data + ((position + 1) * array->element_size);
+
+ memmove(dst, src, len);
+ array->len--;
+}
+
Copied: src/branches/2.0/base/como.c (from rev 1250, src/branches/2.0/libcomo/como.c)
===================================================================
--- src/branches/2.0/base/como.c (rev 0)
+++ src/branches/2.0/base/como.c 2008-06-04 23:17:20 UTC (rev 1253)
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2004-2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id:como.c 1032 2006-11-14 13:29:01Z m_canini $
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <string.h> /* strlen strcpy strncat memset */
+
+/* Required for symlink deletion */
+#include <errno.h>
+#include <signal.h> // signal...
+#include <unistd.h>
+
+#include "como.h"
+#include "comopriv.h"
+#include "storage.h" // mainloop
+#include "ipc.h" // ipc_listen()
+
+
+ipc_peer_full_t *COMO_SU;
+ipc_peer_full_t *COMO_CA;
+ipc_peer_full_t *COMO_EX;
+ipc_peer_full_t *COMO_ST;
+ipc_peer_full_t *COMO_QU;
+
+
+void
+como_init(const char * program, int argc, char ** argv)
+{
+ log_set_program(program);
+ if (!isatty(fileno(stderr))) {
+ log_set_use_color(FALSE);
+ }
+
+#if defined(linux) || defined(__APPLE__)
+ /* linux/Mac OS X does not support setproctitle. we have our own. */
+ setproctitle_init(argc, argv);
+#endif
+
+ COMO_SU = ipc_peer_new(COMO_SU_CLASS, "su", "SUPERVISOR");
+ COMO_CA = ipc_peer_new(COMO_CA_CLASS, "ca", "CAPTURE");
+ COMO_EX = ipc_peer_new(COMO_EX_CLASS, "ex", "EXPORT");
+ COMO_ST = ipc_peer_new(COMO_ST_CLASS, "st", "STORAGE");
+ COMO_QU = ipc_peer_new(COMO_QU_CLASS, "qu", "QUERY");
+}
+
+/**
+ * -- safe__malloc
+ *
+ * Not to be called directly, but through safe_malloc()
+ *
+ * simple wrapper to malloc that handles errors
+ * and returns only if the malloc call succeded. it
+ * forces a termination, otherwise.
+ *
+ */
+void *
+safe__malloc(size_t sz, const char * file, int line)
+{
+ void * v;
+
+ v = malloc(sz);
+ if (v == NULL) {
+ error("malloc failed: %u bytes (%s:%d): %s\n",
+ sz, file, line, strerror(errno));
+ }
+
+ return v;
+}
+
+
+/**
+ * -- safe__calloc
+ *
+ * Not to be called directly, but through safe_calloc()
+ *
+ * simple interface to calloc that handles errors
+ * and returns only if the calloc call succeded. it
+ * forces a termination, otherwise.
+ *
+ */
+void *
+safe__calloc(size_t n, size_t sz, const char * file, int line)
+{
+ void * v;
+
+ v = calloc(n, sz);
+ if (v == NULL) {
+ error("calloc failed: %u * %u bytes (%s:%d): %s\n",
+ n, sz, file, line, strerror(errno));
+ }
+
+ return v;
+}
+
+
+/**
+ * -- safe__realloc
+ *
+ * Not to be called directly, but through safe_realloc()
+ *
+ * simple interface to realloc that handles errors
+ * and returns only if the realloc call succeded. it
+ * forces a termination, otherwise.
+ *
+ */
+void *
+safe__realloc(void * ptr, size_t sz, const char * file, const int line)
+{
+ void * v;
+
+ v = realloc(ptr, sz);
+ if (v == NULL) {
+ error("realloc failed: %u bytes (%s:%d): %s\n",
+ sz, file, line, strerror(errno));
+ }
+
+ return v;
+}
+
+
+/**
+ * -- safe__strdup
+ *
+ * Not to be called directly, but through safe_strdup()
+ *
+ * simple interface to strdup() that handles errors
+ * and returns only if the call succeded. it
+ * forces a termination, otherwise.
+ *
+ */
+char *
+safe__strdup(const char * str, const char * file, const int line)
+{
+ char * v;
+
+ if (str == NULL)
+ return NULL;
+
+ v = strdup(str);
+ if (v == NULL) {
+ error("strdup failed (%s:%d): %s\n",
+ file, line, strerror(errno));
+ }
+
+ return v;
+}
+
+
+/*
+ * -- safe__freedup
+ *
+ * Not to be called directly, but through safe_freedup()
+ *
+ * Makes a malloc'ed copy of src into *dst,
+ * freeing the previous one if any
+ */
+char *
+safe__freedup(char **dst, char *src, const char * file, const int line)
+{
+ if (*dst)
+ free(*dst);
+ *dst = safe__strdup(src, file, line);
+ return *dst;
+}
+
+
+int
+safe__fileno(FILE *stream, const char *file, const int line)
+{
+ int i = fileno(stream);
+ if (i < 1)
+ error("fileno failed (%s:%d): %s\n",
+ file, line, strerror(errno));
+ if (fflush(stream) < 0) /* user will be using the fd, so first flush */
+ error("fileno failed (%s:%d) - can't flush stream: %s\n",
+ file, line, strerror(errno));
+ return i;
+}
+
+
+char *
+safe__asprintf(const char * file, const int line, char *fmt, ...)
+{
+ char *str;
+ va_list ap;
+ va_start(ap, fmt);
+ vasprintf(&str, fmt, ap);
+ if (str == NULL) {
+ error("vasprintf failed (%s:%d): %s\n",
+ file, line, strerror(errno));
+ }
+ va_end(ap);
+ return str;
+}
+
+char *
+como_basename(const char * path)
+{
+ return basename(path); /* GNU version of basename */
+}
+
+
+alc_t *
+como_alc()
+{
+ static alc_t alc = {
+ malloc: (alc_malloc_fn) safe__malloc,
+ calloc: (alc_calloc_fn) safe__calloc,
+ free: (alc_free_fn) free,
+ data: NULL
+ };
+
+ return &alc;
+}
+
Modified: src/branches/2.0/base/config-lexic.l
===================================================================
--- src/branches/2.0/base/config-lexic.l 2008-06-04 21:37:13 UTC (rev 1252)
+++ src/branches/2.0/base/config-lexic.l 2008-06-04 23:17:20 UTC (rev 1253)
@@ -100,7 +100,6 @@
db-path { dbg_return(TOK_DBPATH); }
librarydir { dbg_return(TOK_LIBDIR); }
-storage-path { dbg_return(TOK_STORAGEPATH); }
memsize { dbg_return(TOK_MEMSIZE); }
query-port { dbg_return(TOK_QUERY_PORT); }
Modified: src/branches/2.0/base/config-syntax.y
===================================================================
--- src/branches/2.0/base/config-syntax.y 2008-06-04 21:37:13 UTC (rev 1252)
+++ src/branches/2.0/base/config-syntax.y 2008-06-04 23:17:20 UTC (rev 1253)
@@ -93,7 +93,7 @@
%token TOK_TYPE TOK_COMMENT TOK_SNIFFER TOK_FILESIZE TOK_MODULE TOK_DESCRIPTION
%token TOK_SOURCE TOK_OUTPUT TOK_FILTER TOK_HASHSIZE TOK_STREAMSIZE TOK_ARGS
%token TOK_ONDEMAND TOK_END TOK_NEWLINE TOK_EQUALS TOK_COMMA
-%token TOK_STORAGEPATH TOK_ASNFILE TOK_SHEDMETHOD TOK_ALIAS TOK_VIRTUAL_NODE
+%token TOK_ASNFILE TOK_SHEDMETHOD TOK_ALIAS TOK_VIRTUAL_NODE
%token TOK_SOURCE_MODULE TOK_MINSRATE TOK_LEFTARROW
%token <string> TOK_STRING
%token <number> TOK_NUMBER
@@ -118,7 +118,6 @@
keyword: /* a global keyword */
TOK_DBPATH TOK_STRING { cfg->db_path = $2; }
| TOK_LIBDIR TOK_STRING { cfg->libdir = $2; }
- | TOK_STORAGEPATH TOK_STRING { cfg->storage_path = $2; }
| TOK_MEMSIZE TOK_NUMBER { set_memsize($2, cfg); }
| TOK_ASNFILE TOK_STRING { cfg->asn_file = $2; }
Modified: src/branches/2.0/base/config.c
===================================================================
--- src/branches/2.0/base/config.c 2008-06-04 21:37:13 UTC (rev 1252)
+++ src/branches/2.0/base/config.c 2008-06-04 23:17:20 UTC (rev 1253)
@@ -458,10 +458,6 @@
break;
}
- case 't': /* path to storage */
- cfg->storage_path = safe_strdup(optarg);
- break;
-
case '?': /* unknown */
error("unrecognized cmdline option (%s)\n\n" USAGE "\n",
argv[optind], argv[0]);
@@ -659,7 +655,6 @@
array_free(cfg->vnode_defs, 1);
free(cfg->como_executable_full_path); /* free strings */
- free(cfg->storage_path);
free(cfg->mono_path);
free(cfg->db_path);
free(cfg->libdir);
Copied: src/branches/2.0/base/eventloop.c (from rev 1252, src/branches/2.0/libcomo/eventloop.c)
===================================================================
--- src/branches/2.0/base/eventloop.c (rev 0)
+++ src/branches/2.0/base/eventloop.c 2008-06-04 23:17:20 UTC (rev 1253)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2004-2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id:eventloop.c 1010 2006-11-13 14:49:11Z m_canini $
+ *
+ */
+
+#include <string.h>
+#include <sys/select.h>
+#include <errno.h>
+
+#include "como.h"
+#include "comopriv.h"
+
+struct event_loop {
+ fd_set fds;
+ int max_fd;
+ struct timeval *timeoutptr;
+ struct timeval timeout;
+};
+
+
+event_loop_t *
+event_loop_new()
+{
+ event_loop_t *el = safe_malloc(sizeof(event_loop_t));
+
+ memset(el, 0, sizeof(event_loop_t));
+ FD_ZERO(&el->fds);
+
+ return el;
+}
+
+
+/*
+ * -- event_loop_add
+ *
+ * add a file descriptor to the interesting range;
+ * return max_fd value or -1 if failed.
+ */
+int
+event_loop_add(event_loop_t * el, int i)
+{
+ if (i < 0)
+ return -1;
+
+ FD_SET(i, &el->fds);
+ el->max_fd = (i >= el->max_fd) ? i + 1 : el->max_fd;
+
+ return el->max_fd;
+}
+
+
+/*
+ * -- event_loop_del
+ *
+ * delete a file descriptor to the interesting range;
+ * return max_fd value or -1 if failed.
+ */
+int
+event_loop_del(event_loop_t * el, int i)
+{
+ if (i < 0)
+ return -1;
+
+ FD_CLR(i, &el->fds);
+ if (i < el->max_fd - 1)
+ return el->max_fd;
+
+ /* we deleted the highest fd, so need to recompute the max */
+ for (i = el->max_fd - 1; i >= 0; i--)
+ if (FD_ISSET(i, &el->fds))
+ break;
+ el->max_fd = i + 1;
+
+ return el->max_fd;
+}
+
+
+
+void
+event_loop_set_timeout(event_loop_t * el, struct timeval * timeout)
+{
+ el->timeout = *timeout;
+ el->timeoutptr = &el->timeout;
+}
+
+
+int
+event_loop_select(event_loop_t * el, fd_set * ready, int * max_fd)
+{
+ int n;
+
+ *ready = el->fds;
+ n = select(el->max_fd, ready, NULL, NULL, el->timeoutptr);
+ if (n < 0 && errno != EINTR) {
+ error("Failed on select(): %s\n", strerror(errno));
+ }
+ el->timeoutptr = NULL;
+ *max_fd = el->max_fd;
+
+ return n;
+}
+
Copied: src/branches/2.0/base/hash.c (from rev 1250, src/branches/2.0/libcomo/hash.c)
===================================================================
--- src/branches/2.0/base/hash.c (rev 0)
+++ src/branches/2.0/base/hash.c 2008-06-04 23:17:20 UTC (rev 1253)
@@ -0,0 +1,1050 @@
+/*
+ * Copyright (c) 2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/*
+ * This file is derived from Tcl (http://tcl.sourceforge.net/)
+ * which holds the following copyright notice and license:
+ *
+ * This software is copyrighted by the Regents of the University of
+ * California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState
+ * Corporation and other parties. The following terms apply to all files
+ * associated with the software unless explicitly disclaimed in
+ * individual files.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+ * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+ * DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+ * IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+ * NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS.
+ *
+ * GOVERNMENT USE: If you are acquiring this software on behalf of the
+ * U.S. government, the Government shall have only "Restricted Rights"
+ * in the software and related documentation as defined in the Federal
+ * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
+ * are acquiring the software on behalf of the Department of Defense, the
+ * software shall be classified as "Commercial Computer Software" and the
+ * Government shall have only "Restricted Rights" as defined in Clause
+ * 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
+ * authors grant the U.S. Government and others acting in its behalf
+ * permission to use and distribute the software in accordance with the
+ * terms specified in this license.
+ */
+
+/* Portions are:
+ *
+ * Copyright (C) 2002 Red Hat, Inc.
+ * Copyright (c) 1991-1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ */
+
+#include <string.h>
+#include <assert.h>
+
+#include "como.h"
+#include "comopriv.h"
+
+/*
+ * When there are this many entries per bucket, on average, rebuild
+ * the hash table to make it larger.
+ */
+
+#define REBUILD_MULTIPLIER 3
+
+/*
+ * The following macro takes a preliminary integer hash value and
+ * produces an index into a hash tables bucket list. The idea is
+ * to make it so that preliminary values that are arbitrarily similar
+ * will end up in different buckets. The hash function was taken
+ * from a random-number generator.
+ */
+
+#define RANDOM_INDEX(tablePtr, i) \
+ (((((long) (i))*1103515245) >> (tablePtr)->downShift) & (tablePtr)->mask)
+
+/*
+ * Structure definition for an entry in a hash table. No-one outside
+ * Tcl should access any of these fields directly; use the macros
+ * defined below.
+ */
+
+typedef struct hash_entry_t {
+ struct hash_entry_t *nextPtr; /* Pointer to next entry in this
+ * hash bucket, or NULL for end of
+ * chain. */
+ hash_t *tablePtr; /* Pointer to table containing entry. */
+ unsigned int hash; /* Hash value. */
+ void *key; /* Key. */
+ void *value; /* Entry value. */
+} hash_entry_t;
+
+/*
+ * Structure definition for a hash table.
+ */
+
+#define SMALL_HASH_TABLE 4
+struct hash_t {
+ hash_entry_t **buckets; /* Pointer to bucket array. Each
+ * element points to first entry in
+ * bucket's hash chain, or NULL. */
+ hash_entry_t *staticBuckets[SMALL_HASH_TABLE];
+ /* Bucket array used for small tables
+ * (to avoid mallocs and frees). */
+ int numBuckets; /* Total number of buckets allocated
+ * at **bucketPtr. */
+ int numEntries; /* Total number of entries present
+ * in table. */
+ int rebuildSize; /* Enlarge table when numEntries gets
+ * to be this large. */
+ int downShift; /* Shift count used in hashing
+ * function. Designed to use high-
+ * order bits of randomized keys. */
+ int mask; /* Mask value used in hashing
+ * function. */
+ int keyType; /* Type of keys used in this table.
+ * It's either TCL_CUSTOM_KEYS,
+ * HASHKEYS_STRING, HASHKEYS_ULONG,
+ * or an integer giving the number of
+ * ints that is the size of the key.
+ */
+ hash_key_fn hashKeyFn;
+ compare_hash_keys_fn compareKeysFn;
+ destroy_notify_fn keyDestroyFn;
+ destroy_notify_fn valueDestroyFn;
+ alc_t *alc; /* Allocator of the hash table. */
+};
+
+/*
+ * Hash iterator
+ */
+typedef struct hash_real_iter_t {
+ hash_t *table; /* Pointer to table containing entry. */
+ hash_entry_t **bucket; /* Pointer to bucket that points to
+ * first entry in this entry's chain:
+ * used for deleting the entry.
+ */
+ hash_entry_t *entry; /* Current hash entry */
+ hash_entry_t *next_entry; /* Next entry to be iterated onto in current
+ * bucket
+ */
+ int next_bucket; /* index of next bucket */
+ int n_entries_on_init; /* used to detect table resize since
+ * initialization
+ */
+} hash_real_iter_t;
+
+/*
+ * Prototypes for the string hash key methods.
+ */
+
+static unsigned int string_hash(const void *keyPtr);
+
+/*
+ * Procedure prototypes for static procedures in this file:
+ */
+
+static void rebuild_table(hash_t * tablePtr);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * hash_new --
+ *
+ * Given storage for a hash table, set up the fields to prepare
+ * the hash table for use.
+ *
+ * Arguments:
+ * tablePtr - Pointer to table record, which is supplied by the caller.
+ * keyType - Type of keys to use in table: HASHKEYS_STRING,
+ * HASHKEYS_ULONG, or an integer >= 2.
+ * typePtr - Pointer to structure which defines the behaviour of this
+ * table.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * TablePtr is now ready to be passed to hash_lookup and
+ * hash_insert.
+ *
+ *----------------------------------------------------------------------
+ */
+
+hash_t *
+hash_new(alc_t * alc, int keyType, hash_key_fn hashKeyFn,
+ compare_hash_keys_fn compareKeysFn)
+{
+ return hash_new_full(alc, keyType, hashKeyFn, compareKeysFn, NULL, NULL);
+}
+
+hash_t *
+hash_new_full(alc_t * alc, int keyType, hash_key_fn hashKeyFn,
+ compare_hash_keys_fn compareKeysFn,
+ destroy_notify_fn keyDestroyFn, destroy_notify_fn valueDestroyFn)
+{
+ hash_t *tablePtr;
+
+ if (alc == NULL)
+ alc = como_alc();
+
+ tablePtr = alc_new0(alc, hash_t);
+
+#if (SMALL_HASH_TABLE != 4)
+#error "SMALL_HASH_TABLE must be 4!"
+#endif
+
+ tablePtr->buckets = tablePtr->staticBuckets;
+ tablePtr->staticBuckets[0] = tablePtr->staticBuckets[1] = 0;
+ tablePtr->staticBuckets[2] = tablePtr->staticBuckets[3] = 0;
+ tablePtr->numBuckets = SMALL_HASH_TABLE;
+ tablePtr->numEntries = 0;
+ tablePtr->rebuildSize = SMALL_HASH_TABLE * REBUILD_MULTIPLIER;
+ tablePtr->downShift = 28;
+ tablePtr->mask = 3;
+ tablePtr->keyType = keyType;
+ tablePtr->alc = alc;
+ tablePtr->hashKeyFn = hashKeyFn;
+ tablePtr->compareKeysFn = compareKeysFn;
+
+ if (keyType == HASHKEYS_STRING) {
+ if (hashKeyFn == NULL) {
+ tablePtr->hashKeyFn = string_hash;
+ }
+
+ if (compareKeysFn == NULL) {
+ tablePtr->compareKeysFn = (compare_hash_keys_fn) strcmp;
+ }
+ }
+
+ tablePtr->keyDestroyFn = keyDestroyFn;
+ tablePtr->valueDestroyFn = valueDestroyFn;
+
+ return tablePtr;
+}
+
+
+int
+hash_size(hash_t * tablePtr)
+{
+ return tablePtr->numEntries;
+}
+
+
+static hash_entry_t *
+hash_lookup_internal(hash_t * tablePtr, void *key)
+{
+ hash_entry_t *hPtr;
+ unsigned int hash;
+ int i;
+
+ if (tablePtr->hashKeyFn) {
+ hash = tablePtr->hashKeyFn(key);
+ i = hash & tablePtr->mask;
+ } else {
+ hash = (unsigned int) key;
+ i = RANDOM_INDEX(tablePtr, hash);
+ }
+
+ /*
+ * Search all of the entries in the appropriate bucket.
+ */
+ if (tablePtr->compareKeysFn) {
+ compare_hash_keys_fn compareKeysFn = tablePtr->compareKeysFn;
+ for (hPtr = tablePtr->buckets[i]; hPtr != NULL; hPtr = hPtr->nextPtr) {
+ if (hash != (unsigned int) hPtr->hash) {
+ continue;
+ }
+ if (compareKeysFn(key, hPtr->key) == 0) {
+ return hPtr;
+ }
+ }
+ } else {
+ for (hPtr = tablePtr->buckets[i]; hPtr != NULL; hPtr = hPtr->nextPtr) {
+ if (hash != (unsigned int) hPtr->hash) {
+ continue;
+ }
+ if (key == hPtr->key) {
+ return hPtr;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * hash_lookup_string --
+ *
+ * Given a hash table find the entry with a matching key.
+ *
+ * Arguments:
+ * tablePtr - Table in which to lookup entry.
+ * key - Key to use to find matching entry.
+ *
+ * Results:
+ * The return value is the value of the matching entry in the
+ * hash table, or NULL if there was no matching entry.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void *
+hash_lookup_string(hash_t * tablePtr, const char *key)
+{
+ hash_entry_t *hPtr;
+
+ assert(tablePtr->keyType == HASHKEYS_STRING);
+
+ hPtr = hash_lookup_internal(tablePtr, (void *) key);
+
+ return (hPtr) ? hPtr->value : NULL;
+}
+
+void *
+hash_lookup_ulong(hash_t * tablePtr, unsigned long key)
+{
+ hash_entry_t *hPtr;
+
+ assert(tablePtr->keyType == HASHKEYS_ULONG);
+
+ hPtr = hash_lookup_internal(tablePtr, (void *) key);
+
+ return (hPtr) ? hPtr->value : NULL;
+}
+
+void *
+hash_lookup(hash_t * tablePtr, void *key)
+{
+ hash_entry_t *hPtr;
+
+ assert(tablePtr->keyType == HASHKEYS_POINTER);
+
+ hPtr = hash_lookup_internal(tablePtr, key);
+
+ return (hPtr) ? hPtr->value : NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * hash_insert_internal --
+ *
+ * Given a hash table with string keys, and a string key, find
+ * the entry with a matching key. If there is no matching entry,
+ * then create a new entry that does match.
+ *
+ * Arguments:
+ * tablePtr - Table in which to lookup entry.
+ * key - Key to use to find or create matching entry.
+ * value - Value associated to Key.
+ *
+ * Results:
+ * If this is a newly-created entry, then the functions returns 1;
+ * otherwise returns 0.
+ *
+ * Side effects:
+ * A new entry may be added to the hash table.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+hash_insert_internal(hash_t * tablePtr, void *key, void *value)
+{
+ hash_entry_t *hPtr;
+ unsigned int hash;
+ int i;
+
+ if (tablePtr->hashKeyFn) {
+ hash = tablePtr->hashKeyFn(key);
+ i = hash & tablePtr->mask;
+ } else {
+ hash = (unsigned int) key;
+ i = RANDOM_INDEX(tablePtr, hash);
+ }
+
+ /*
+ * Search all of the entries in the appropriate bucket.
+ */
+
+ if (tablePtr->compareKeysFn) {
+ compare_hash_keys_fn compareKeysFn = tablePtr->compareKeysFn;
+ for (hPtr = tablePtr->buckets[i]; hPtr != NULL; hPtr = hPtr->nextPtr) {
+ if (hash != (unsigned int) hPtr->hash) {
+ continue;
+ }
+ if (compareKeysFn(key, hPtr->key) == 0) {
+ if (tablePtr->valueDestroyFn && value != hPtr->value)
+ tablePtr->valueDestroyFn(hPtr->value);
+
+ hPtr->value = value;
+ return 0;
+ }
+ }
+ } else {
+ for (hPtr = tablePtr->buckets[i]; hPtr != NULL; hPtr = hPtr->nextPtr) {
+ if (hash != (unsigned int) hPtr->hash) {
+ continue;
+ }
+ if (key == hPtr->key) {
+ if (tablePtr->valueDestroyFn && value != hPtr->value)
+ tablePtr->valueDestroyFn(hPtr->value);
+
+ hPtr->value = value;
+ return 0;
+ }
+ }
+ }
+
+ /*
+ * Entry not found. Add a new one to the bucket.
+ */
+ hPtr = alc_calloc(tablePtr->alc, 1, sizeof(hash_entry_t));
+ hPtr->key = key;
+ hPtr->value = value;
+ hPtr->tablePtr = tablePtr;
+ hPtr->hash = hash;
+ hPtr->nextPtr = tablePtr->buckets[i];
+ tablePtr->buckets[i] = hPtr;
+ tablePtr->numEntries++;
+
+ /*
+ * If the table has exceeded a decent size, rebuild it with many
+ * more buckets.
+ */
+
+ if (tablePtr->numEntries >= tablePtr->rebuildSize) {
+ rebuild_table(tablePtr);
+ }
+ return 1;
+}
+
+int
+hash_insert_string(hash_t * tablePtr, const char *key, void *value)
+{
+ assert(tablePtr->keyType == HASHKEYS_STRING);
+
+ return hash_insert_internal(tablePtr, (void *) key, value);
+}
+
+int
+hash_insert_ulong(hash_t * tablePtr, unsigned long key, void *value)
+{
+ assert(tablePtr->keyType == HASHKEYS_ULONG);
+
+ return hash_insert_internal(tablePtr, (void *) key, value);
+}
+
+int
+hash_insert(hash_t * tablePtr, void *key, void *value)
+{
+ assert(tablePtr->keyType == HASHKEYS_POINTER);
+
+ return hash_insert_internal(tablePtr, key, value);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * hash_remove --
+ *
+ * Remove a single entry from a hash table.
+ *
+ * Arguments:
+ * tablePtr - Table in which to remove entry.
+ * key - Key to use to find matching entry.
+ *
+ * Results:
+ * Returns 1 if the entry existed and was removed; otherwise 0.
+ *
+ * Side effects:
+ * The entry given by entryPtr is deleted from its table and
+ * should never again be used by the caller.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+hash_remove_entry_internal(hash_t * tablePtr, hash_entry_t ** bucketPtr,
+ hash_entry_t * entryPtr)
+{
+ if (*bucketPtr == entryPtr) {
+ *bucketPtr = entryPtr->nextPtr;
+ } else {
+ hash_entry_t *prevPtr;
+
+ for (prevPtr = *bucketPtr;; prevPtr = prevPtr->nextPtr) {
+ if (prevPtr == NULL) {
+ /* malformed bucket chain in hash_remove */
+ assert_not_reached();
+ }
+ if (prevPtr->nextPtr == entryPtr) {
+ prevPtr->nextPtr = entryPtr->nextPtr;
+ break;
+ }
+ }
+ }
+
+ tablePtr->numEntries--;
+
+ if (tablePtr->keyDestroyFn)
+ tablePtr->keyDestroyFn(entryPtr->key);
+ if (tablePtr->valueDestroyFn)
+ tablePtr->valueDestroyFn(entryPtr->value);
+
+ alc_free(tablePtr->alc, entryPtr);
+
+ return 1;
+}
+
+static int
+hash_remove_internal(hash_t * tablePtr, void *key)
+{
+ hash_entry_t *entryPtr;
+ hash_entry_t **bucketPtr;
+ int i;
+
+ entryPtr = hash_lookup_internal(tablePtr, key);
+ if (entryPtr == NULL)
+ return 0;
+
+ if (tablePtr->hashKeyFn) {
+ i = ((unsigned int) entryPtr->hash) & tablePtr->mask;
+ } else {
+ i = RANDOM_INDEX(tablePtr, entryPtr->hash);
+ }
+
+ bucketPtr = &(tablePtr->buckets[i]);
+
+ return hash_remove_entry_internal(tablePtr, bucketPtr, entryPtr);
+}
+
+int
+hash_remove_string(hash_t * tablePtr, const char *key)
+{
+ assert(tablePtr->keyType == HASHKEYS_STRING);
+
+ return hash_remove_internal(tablePtr, (void *) key);
+}
+
+int
+hash_remove_ulong(hash_t * tablePtr, unsigned long key)
+{
+ assert(tablePtr->keyType == HASHKEYS_ULONG);
+
+ return hash_remove_internal(tablePtr, (void *) key);
+}
+
+int
+hash_remove(hash_t * tablePtr, void *key)
+{
+ assert(tablePtr->keyType == HASHKEYS_POINTER);
+
+ return hash_remove_internal(tablePtr, key);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * hash_destroy --
+ *
+ * Free up everything associated with a hash table except for
+ * the record for the table itself.
+ *
+ * Arguments:
+ * tablePtr - Table to delete.
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The hash table is no longer useable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+hash_destroy(hash_t * tablePtr)
+{
+ hash_entry_t *hPtr, *nextPtr;
+ int i;
+
+ /*
+ * Free up all the entries in the table.
+ */
+ for (i = 0; i < tablePtr->numBuckets; i++) {
+ hPtr = tablePtr->buckets[i];
+ while (hPtr != NULL) {
+ nextPtr = hPtr->nextPtr;
+
+ if (tablePtr->keyDestroyFn)
+ tablePtr->keyDestroyFn(hPtr->key);
+ if (tablePtr->valueDestroyFn)
+ tablePtr->valueDestroyFn(hPtr->value);
+
+ alc_free(tablePtr->alc, hPtr);
+ hPtr = nextPtr;
+ }
+ }
+
+ /*
+ * Free up the bucket array, if it was dynamically allocated.
+ */
+ if (tablePtr->buckets != tablePtr->staticBuckets) {
+ alc_free(tablePtr->alc, tablePtr->buckets);
+ }
+
+ alc_free(tablePtr->alc, tablePtr);
+}
+
+/**
+ * Initializes a hash table iterator. To iterate over all entries in a
+ * hash table, use the following code (the printf assumes a hash
+ * from strings to strings obviously):
+ *
+ * @code
+ * hash_iter_t iter;
+ *
+ * hash_iter_init (table, &iter);
+ * while (hash_iter_next (&iter))
+ * {
+ * printf ("The first key is %s and value is %s\n",
+ * hash_iter_get_string_key (&iter),
+ * hash_iter_get_value (&iter));
+ * }
+ *
+ *
+ * @endcode
+ *
+ * The iterator is initialized pointing "one before" the first hash
+ * entry. The first call to hash_iter_next() moves it onto
+ * the first valid entry or returns 0 if the hash table is
+ * empty. Subsequent calls move to the next valid entry or return
+ * 0 if there are no more entries.
+ *
+ * Note that it is guaranteed to be safe to remove a hash entry during
+ * iteration, but it is not safe to add a hash entry.
+ *
+ * @param table the hash table to iterate over.
+ * @param iter the iterator to initialize.
+ */
+void
+hash_iter_init(hash_t * table, hash_iter_t * iter)
+{
+ hash_real_iter_t *real;
+
+ assert(sizeof(hash_iter_t) == sizeof(hash_real_iter_t));
+
+ real = (hash_real_iter_t *) iter;
+
+ real->table = table;
+ real->bucket = NULL;
+ real->entry = NULL;
+ real->next_entry = NULL;
+ real->next_bucket = 0;
+ real->n_entries_on_init = table->numEntries;
+}
+
+/**
+ * Move the hash iterator forward one step, to the next hash entry.
+ * The documentation for hash_iter_init() explains in more
+ * detail.
+ *
+ * @param iter the iterator to move forward.
+ * @returns 0 if there are no more entries to move to.
+ */
+int
+hash_iter_next(hash_iter_t * iter)
+{
+ hash_real_iter_t *real;
+
+ assert(sizeof(hash_iter_t) == sizeof(hash_real_iter_t));
+
+ real = (hash_real_iter_t *) iter;
+
+ /* if this assertion failed someone probably added hash entries
+ * during iteration, which is bad.
+ */
+ assert(real->n_entries_on_init >= real->table->numEntries);
+
+ /* Remember that real->entry may have been deleted */
+
+ while (real->next_entry == NULL) {
+ if (real->next_bucket >= real->table->numBuckets) {
+ /* invalidate iter and return false */
+ real->entry = NULL;
+ real->table = NULL;
+ real->bucket = NULL;
+ return 0;
+ }
+
+ real->bucket = &(real->table->buckets[real->next_bucket]);
+ real->next_entry = *(real->bucket);
+ real->next_bucket += 1;
+ }
+
+ assert(real->next_entry != NULL);
+ assert(real->bucket != NULL);
+
+ real->entry = real->next_entry;
+ real->next_entry = real->entry->nextPtr;
+
+ return 1;
+}
+
+/**
+ * Removes the current entry from the hash table.
+ * If a key_free_function or value_free_function
+ * was provided to hash_table_new(),
+ * frees the key and/or value for this entry.
+ *
+ * @param iter the hash table iterator.
+ */
+void
+hash_iter_remove_entry(hash_iter_t * iter)
+{
+ hash_real_iter_t *real;
+
+ real = (hash_real_iter_t *) iter;
+
+ assert(real->table != NULL);
+ assert(real->entry != NULL);
+ assert(real->bucket != NULL);
+
+ hash_remove_entry_internal(real->table, real->bucket, real->entry);
+
+ real->entry = NULL; /* make it crash if you try to use this entry */
+}
+
+/**
+ * Gets the value of the current entry.
+ *
+ * @param iter the hash table iterator.
+ */
+void *
+hash_iter_get_value(hash_iter_t * iter)
+{
+ hash_real_iter_t *real;
+
+ real = (hash_real_iter_t *) iter;
+
+ assert(real->table != NULL);
+ assert(real->entry != NULL);
+
+ return real->entry->value;
+}
+
+/**
+ * Sets the value of the current entry.
+ * If the hash table has a value_free_function
+ * it will be used to free the previous value.
+ * The hash table will own the passed-in value
+ * (it will not be copied).
+ *
+ * @param iter the hash table iterator.
+ * @param value the new value.
+ */
+void
+hash_iter_set_value(hash_iter_t * iter, void *value)
+{
+ hash_real_iter_t *real;
+
+ real = (hash_real_iter_t *) iter;
+
+ assert(real->table != NULL);
+ assert(real->entry != NULL);
+
+ if (real->table->valueDestroyFn && value != real->entry->value)
+ real->table->valueDestroyFn(real->entry->value);
+
+ real->entry->value = value;
+}
+
+/**
+ * Gets the key for the current entry.
+ * Only works for hash tables of type #HASHKEYS_POINTER.
+ *
+ * @param iter the hash table iterator.
+ */
+void *
+hash_iter_get_key(hash_iter_t * iter)
+{
+ hash_real_iter_t *real;
+
+ real = (hash_real_iter_t *) iter;
+
+ assert(real->table != NULL);
+ assert(real->entry != NULL);
+
+ return real->entry->key;
+}
+
+/**
+ * Gets the key for the current entry.
+ * Only works for hash tables of type #HASHKEYS_ULONG.
+ *
+ * @param iter the hash table iterator.
+ */
+unsigned long
+hash_iter_get_ulong_key(hash_iter_t * iter)
+{
+ hash_real_iter_t *real;
+
+ real = (hash_real_iter_t *) iter;
+
+ assert(real->table != NULL);
+ assert(real->entry != NULL);
+
+ return (unsigned long) real->entry->key;
+}
+
+/**
+ * Gets the key for the current entry.
+ * Only works for hash tables of type #HASHKEYS_STRING
+ * @param iter the hash table iterator.
+ */
+const char *
+hash_iter_get_string_key(hash_iter_t * iter)
+{
+ hash_real_iter_t *real;
+
+ real = (hash_real_iter_t *) iter;
+
+ assert(real->table != NULL);
+ assert(real->entry != NULL);
+
+ return real->entry->key;
+}
+
+#if 0
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_HashStats --
+ *
+ * Return statistics describing the layout of the hash table
+ * in its hash buckets.
+ *
+ * Results:
+ * The return value is a malloc-ed string containing information
+ * about tablePtr. It is the caller's responsibility to free
+ * this string.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_HashStats(tablePtr)
+hash_t *tablePtr; /* Table for which to produce stats. */
+{
+#define NUM_COUNTERS 10
+ int count[NUM_COUNTERS], overflow, i, j;
+ double average, tmp;
+ hash_entry_t *hPtr;
+ char *result, *p;
+
+ /*
+ * Compute a histogram of bucket usage.
+ */
+
+ for (i = 0; i < NUM_COUNTERS; i++) {
+ count[i] = 0;
+ }
+ overflow = 0;
+ average = 0.0;
+ for (i = 0; i < tablePtr->numBuckets; i++) {
+ j = 0;
+ for (hPtr = tablePtr->buckets[i]; hPtr != NULL; hPtr = hPtr->nextPtr) {
+ j++;
+ }
+ if (j < NUM_COUNTERS) {
+ count[j]++;
+ } else {
+ overflow++;
+ }
+ tmp = j;
+ average += (tmp + 1.0) * (tmp / tablePtr->numEntries) / 2.0;
+ }
+
+ /*
+ * Print out the histogram and a few other pieces of information.
+ */
+
+ result = (char *) ckalloc((unsigned) ((NUM_COUNTERS * 60) + 300));
+ sprintf(result, "%d entries in table, %d buckets\n",
+ tablePtr->numEntries, tablePtr->numBuckets);
+ p = result + strlen(result);
+ for (i = 0; i < NUM_COUNTERS; i++) {
+ sprintf(p, "number of buckets with %d entries: %d\n", i, count[i]);
+ p += strlen(p);
+ }
+ sprintf(p, "number of buckets with %d or more entries: %d\n",
+ NUM_COUNTERS, overflow);
+ p += strlen(p);
+ sprintf(p, "average search distance for entry: %.1f", average);
+ return result;
+}
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * string_alloc --
+ *
+ * Allocate space for a hash_entry_t containing the string key.
+ *
+ * Results:
+ * The return value is a pointer to the created entry.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static unsigned int
+string_hash(const void *str)
+{
+ const char *p = (const char *) str;
+ unsigned int h = *p;
+
+ if (h)
+ for (p += 1; *p != '\0'; p++)
+ h = (h << 5) - h + *p;
+
+ return h;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * rebuild_table --
+ *
+ * This procedure is invoked when the ratio of entries to hash
+ * buckets becomes too large. It creates a new table with a
+ * larger bucket array and moves all of the entries into the
+ * new table.
+ *
+ * Arguments:
+ * tablePtr - Table to enlarge.
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Memory gets reallocated and entries get re-hashed to new
+ * buckets.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+rebuild_table(hash_t * tablePtr)
+{
+ int oldSize, count, i;
+ hash_entry_t **oldBuckets;
+ hash_entry_t **oldChainPtr, **newChainPtr;
+ hash_entry_t *hPtr;
+ void *key;
+
+ oldSize = tablePtr->numBuckets;
+ oldBuckets = tablePtr->buckets;
+
+ /*
+ * Allocate and initialize the new bucket array, and set up
+ * hashing constants for new array size.
+ */
+
+ tablePtr->numBuckets *= 4;
+ tablePtr->buckets = alc_calloc(tablePtr->alc, tablePtr->numBuckets,
+ sizeof(hash_entry_t *));
+
+ for (count = tablePtr->numBuckets, newChainPtr = tablePtr->buckets;
+ count > 0; count--, newChainPtr++) {
+ *newChainPtr = NULL;
+ }
+ tablePtr->rebuildSize *= 4;
+ tablePtr->downShift -= 2;
+ tablePtr->mask = (tablePtr->mask << 2) + 3;
+
+ /*
+ * Rehash all of the existing entries into the new bucket array.
+ */
+
+ for (oldChainPtr = oldBuckets; oldSize > 0; oldSize--, oldChainPtr++) {
+ for (hPtr = *oldChainPtr; hPtr != NULL; hPtr = *oldChainPtr) {
+ *oldChainPtr = hPtr->nextPtr;
+
+ key = hPtr->key;
+
+ if (tablePtr->hashKeyFn) {
+ i = ((unsigned int) hPtr->hash) & tablePtr->mask;
+ } else {
+ i = RANDOM_INDEX(tablePtr, hPtr->hash);
+ }
+ hPtr->nextPtr = tablePtr->buckets[i];
+ tablePtr->buckets[i] = hPtr;
+ }
+ }
+
+ /*
+ * Free up the old bucket array, if it was dynamically allocated.
+ */
+
+ if (oldBuckets != tablePtr->staticBuckets) {
+ alc_free(tablePtr->alc, oldBuckets);
+ }
+}
Copied: src/branches/2.0/base/ipc.c (from rev 1250, src/branches/2.0/libcomo/ipc.c)
===================================================================
--- src/branches/2.0/base/ipc.c (rev 0)
+++ src/branches/2.0/base/ipc.c 2008-06-04 23:17:20 UTC (rev 1253)
@@ -0,0 +1,697 @@
+/*
+ * Copyright (c) 2005-2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id:ipc.c 1032 2006-11-14 13:29:01Z m_canini $
+ */
+
+/*
+ * Inter process communications.
+ *
+ * This set of functions enable communications between processes.
+ * Each process initializes the IPC engine using the ipc_register()
+ * call to register the s_handlers for all IPC messages of interest.
+ *
+ * Each message carries a type to identify the handler and an id
+ * to identify the senders. Several types have been defined.
+ * All communications are asynchronous.
+ *
+ * Several additional helper functions have been provided to allow
+ * processes to send/receive complex data structures.
+ *
+ * Exception handling is managed by the individual processes
+ * in the s_handlers.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdio.h>
+#include <string.h> /* strlen */
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include <sys/time.h> /* FD_SET */
+#include <sys/types.h>
+#include <sys/select.h>
+
+#define LOG_DOMAIN "IPC"
+
+#include "como.h"
+#include "comopriv.h"
+#include "ipc.h"
+
+#define IPC_CONNECT 0
+
+#include "ipc_peer_list.h"
+
+
+#define SIZEOF_IPC_PEER_CODE 4
+#define SIZEOF_IPC_PEER_NAME 12
+
+struct ipc_peer_full_t {
+ uint8_t class;
+ uint8_t parent_class;
+ uint16_t id;
+ char code[SIZEOF_IPC_PEER_CODE];
+ char name[SIZEOF_IPC_PEER_NAME];
+ char * at;
+ int fd;
+ int swap:1;
+ int connected:1;
+ int _res:6;
+ ipc_peer_list_entry_t next;
+};
+
+/*
+ * IPC messages exchanged between processes.
+ */
+typedef struct PACKED ipc_msg {
+ ipc_type type; /* message type */
+ ipc_peer_t sender; /* sender */
+ uint32_t len; /* payload length */
+ uint8_t data[0]; /* payload */
+} ipc_msg_t;
+
+
+typedef struct PACKED ipc_connect_msg {
+ char code[SIZEOF_IPC_PEER_CODE]; /* code of connecting peer */
+ char name[SIZEOF_IPC_PEER_NAME]; /* name of connecting peer */
+} ipc_connect_msg_t;
+
+
+static ipc_peer_full_t * s_me;
+static void * s_user_data;
+
+/*
+ * IPC peers.
+ * information about connected peers.
+ */
+
+static ipc_peer_list_t s_peers;
+
+/*
+ * IPC messages s_handlers.
+ * if NULL, the message is ignored.
+ */
+/* TODO: replace with hash table */
+static ipc_handler_fn s_handlers[65536] = {0};
+static ipc_on_connect_fn s_on_connect;
+
+ipc_peer_full_t *
+ipc_peer_new(uint8_t class, const char * code, const char * name)
+{
+ ipc_peer_full_t *p;
+ p = como_new0(ipc_peer_full_t);
+ p->class = class;
+ snprintf(p->code, SIZEOF_IPC_PEER_CODE, code);
+ snprintf(p->name, SIZEOF_IPC_PEER_NAME, name);
+ return p;
+}
+
+
+void
+ipc_peer_destroy(ipc_peer_full_t * p)
+{
+ if (p == NULL)
+ return;
+ free(p->at);
+ if (p->fd != -1) {
+ debug("ipc_peer_destroy -- closing fd %d\n", p->fd);
+ close(p->fd);
+ }
+ free(p);
+}
+
+
+ipc_peer_full_t *
+ipc_peer_at(const ipc_peer_full_t * p, const char * at)
+{
+ ipc_peer_full_t *p2;
+ p2 = como_new(ipc_peer_full_t);
+ *p2 = *p;
+ p2->fd = -1;
+ p2->at = safe_strdup(at);
+ p2->swap = 0;
+ memset(&p2->next, 0, sizeof(p2->next));
+ return p2;
+}
+
+
+/*
+ * -- ipc_peer_get_fd
+ *
+ * get the socket descriptor from a peer
+ *
+ */
+int
+ipc_peer_get_fd(const ipc_peer_t * p_)
+{
+ ipc_peer_full_t * p = (ipc_peer_full_t *) p_;
+
+ return p->fd;
+}
+
+
+const char *
+ipc_peer_get_name(const ipc_peer_t * p_)
+{
+ ipc_peer_full_t * p = (ipc_peer_full_t *) p_;
+
+ return p->name;
+}
+
+
+const char *
+ipc_peer_get_code(const ipc_peer_t * p_)
+{
+ ipc_peer_full_t * p = (ipc_peer_full_t *) p_;
+
+ return p->code;
+}
+
+
+ipc_peer_full_t *
+ipc_peer_child(const ipc_peer_full_t * kind, uint16_t id)
+{
+ ipc_peer_full_t *p;
+ p = como_new(ipc_peer_full_t);
+ *p = *kind;
+ p->parent_class = s_me->class;
+ p->id = id;
+ p->at = safe_strdup(s_me->at);
+ p->fd = -1;
+ memset(&p->next, 0, sizeof(p->next));
+ return p;
+}
+
+
+static char *
+ipc_peer_connection_point(const ipc_peer_full_t * p)
+{
+ char *cp;
+ assert(p->at != NULL);
+ if (p->at[0] == '/') {
+ if (p->parent_class == 0 && p->id != 0) {
+ asprintf(&cp, "%s/%s.sock", p->at, p->name);
+ } else {
+ asprintf(&cp, "%s/%s-%d.sock", p->at, p->name, p->id);
+ }
+ } else {
+ cp = strdup(p->at);
+ }
+ return cp;
+}
+
+static inline void
+swap_msg(ipc_msg_t * msg)
+{
+ msg->type = SWAP16(msg->type);
+ msg->sender.id = SWAP16(msg->sender.id);
+ msg->len = SWAP32(msg->len);
+}
+
+
+static inline ipc_peer_full_t *
+lookup_peer(int fd)
+{
+ ipc_peer_full_t *x;
+ ipc_peer_list_foreach(x, &s_peers) {
+ if (x->fd == fd)
+ return x;
+ }
+ return NULL;
+}
+
+
+static int
+ipc_create_socket(const ipc_peer_full_t * p, int is_server)
+{
+ int fd;
+ char *cp;
+
+ cp = ipc_peer_connection_point(p);
+
+ fd = create_socket(cp, is_server);
+
+ free(cp);
+ return fd;
+}
+
+
+static int
+ipc_destroy_socket(const ipc_peer_full_t * p)
+{
+ int r;
+ char *cp;
+
+ cp = ipc_peer_connection_point(p);
+ r = destroy_socket(cp);
+ free(cp);
+
+ return r;
+}
+
+
+void
+ipc_init(ipc_peer_full_t * me, ipc_on_connect_fn on_connect, void * user_data)
+{
+ memset(s_handlers, 0, sizeof(s_handlers));
+
+ s_me = me;
+ s_me->fd = -1;
+ s_on_connect = on_connect;
+ s_user_data = user_data;
+}
+
+/*
+ * -- ipc_listen
+ *
+ * create a socket, bind it to a unix socket whose
+ * name depends on the process. then, register a handler
+ * for ...
[truncated message content] |