X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Ffatal-signal.c;h=81805214383df9945a3f3f042c106d0d8c0a8f27;hb=45a7de56bbcb2adfabf2082b1133e768777d44d6;hp=ccb7fe4515922fbfa7ba22ad9cfaae8106febc4a;hpb=064af42167bf4fc9aaea2702d80ce08074b889c0;p=openvswitch diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c index ccb7fe45..81805214 100644 --- a/lib/fatal-signal.c +++ b/lib/fatal-signal.c @@ -1,17 +1,17 @@ /* * Copyright (c) 2008, 2009 Nicira Networks. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ #include #include "fatal-signal.h" @@ -23,8 +23,12 @@ #include #include #include +#include "shash.h" #include "util.h" +#define THIS_MODULE VLM_fatal_signal +#include "vlog.h" + /* Signals to catch. */ static const int fatal_signals[] = { SIGTERM, SIGINT, SIGHUP, SIGALRM }; @@ -56,7 +60,11 @@ static void call_hooks(int sig_nr); /* Registers 'hook' to be called when a process termination signal is raised. * If 'run_at_exit' is true, 'hook' is also called during normal process - * termination, e.g. when exit() is called or when main() returns. */ + * termination, e.g. when exit() is called or when main() returns. + * + * 'func' will be invoked from an asynchronous signal handler, so it must be + * written appropriately. For example, it must not call most C library + * functions, including malloc() or free(). */ void fatal_signal_add_hook(void (*func)(void *aux), void *aux, bool run_at_exit) { @@ -165,8 +173,7 @@ call_hooks(int sig_nr) } } -static char **files; -static size_t n_files, max_files; +static struct shash files = SHASH_INITIALIZER(&files); static void unlink_files(void *aux); static void do_unlink_files(void); @@ -183,10 +190,9 @@ fatal_signal_add_file_to_unlink(const char *file) } fatal_signal_block(); - if (n_files >= max_files) { - files = x2nrealloc(files, &max_files, sizeof *files); + if (!shash_find(&files, file)) { + shash_add(&files, file, NULL); } - files[n_files++] = xstrdup(file); fatal_signal_unblock(); } @@ -195,32 +201,50 @@ fatal_signal_add_file_to_unlink(const char *file) void fatal_signal_remove_file_to_unlink(const char *file) { - size_t i; + struct shash_node *node; fatal_signal_block(); - for (i = 0; i < n_files; i++) { - if (!strcmp(files[i], file)) { - free(files[i]); - files[i] = files[--n_files]; - break; - } + node = shash_find(&files, file); + if (node) { + shash_delete(&files, node); } fatal_signal_unblock(); } +/* Like fatal_signal_remove_file_to_unlink(), but also unlinks 'file'. + * Returns 0 if successful, otherwise a positive errno value. */ +int +fatal_signal_unlink_file_now(const char *file) +{ + int error = unlink(file) ? errno : 0; + if (error) { + VLOG_WARN("could not unlink \"%s\" (%s)", file, strerror(error)); + } + + fatal_signal_remove_file_to_unlink(file); + + return error; +} + static void unlink_files(void *aux UNUSED) { do_unlink_files(); } +/* This is a fatal_signal_add_hook() callback (via unlink_files()). It will be + * invoked from an asynchronous signal handler, so it cannot call most C + * library functions (unlink() is an explicit exception, see + * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html). + * That includes free(), so it doesn't try to free the 'files' data + * structure. */ static void do_unlink_files(void) { - size_t i; + struct shash_node *node; - for (i = 0; i < n_files; i++) { - unlink(files[i]); + SHASH_FOR_EACH (node, &files) { + unlink(node->name); } }