libexplain
1.4.D001
|
00001 /* 00002 * libexplain - Explain errno values returned by libc functions 00003 * Copyright (C) 2009, 2010, 2013 Peter Miller 00004 * Written by Peter Miller <pmiller@opensource.org.au> 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU Lesser General Public License as 00008 * published by the Free Software Foundation; either version 3 of the 00009 * License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 #include <libexplain/ac/dlfcn.h> 00021 #include <libexplain/ac/stdio.h> 00022 #include <libexplain/ac/string.h> 00023 00024 #include <libexplain/string_to_thing.h> 00025 00026 00027 void * 00028 explain_parse_pointer_or_die(const char *text) 00029 { 00030 if (0 == strcasecmp(text, "null")) 00031 return NULL; 00032 if (0 == strcasecmp(text, "(null)")) 00033 return NULL; 00034 if (0 == strcasecmp(text, "nul")) 00035 return NULL; 00036 if (0 == strcasecmp(text, "nil")) 00037 return NULL; 00038 if (0 == strcasecmp(text, "(nil)")) 00039 return NULL; 00040 if (0 == strcmp(text, "stdin")) 00041 return stdin; 00042 if (0 == strcmp(text, "stdout")) 00043 return stdout; 00044 if (0 == strcmp(text, "stderr")) 00045 return stderr; 00046 00047 #ifdef HAVE_DLSYM 00048 if (text[0] == '&') 00049 { 00050 void *handle; 00051 00052 handle = dlopen(NULL, RTLD_NOW); 00053 if (handle) 00054 { 00055 void *p; 00056 00057 /* clear any previous error */ 00058 dlerror(); 00059 00060 p = dlsym(handle, text + 1); 00061 if (dlerror() == NULL) 00062 { 00063 dlclose(handle); 00064 return p; 00065 } 00066 dlclose(handle); 00067 } 00068 } 00069 #endif 00070 00071 /* 00072 * Pointers are strange beasts, and NULL pointers even stranger. The ANSI C 00073 * standard says that the NULL pointer need not be all-bits-zero, but that 00074 * a NULL pointer *constant* may be *written* as "0". This does _not_ mean 00075 * that an arithmetic value of all-bits-zero, when cast to (void *) will 00076 * actually have the same value as the NULL pointer. Hence the code below: 00077 * it uses an explicit constant NULL pointer. 00078 * 00079 * I have used such a machine, BTW, and I sincerely hope none of them are 00080 * still in use today. Zero was a valid code and data address (and actually 00081 * used!), so the operating system guaranteed that another page of memory 00082 * would never be mapped, and the NULL pointer, while written as 0, had a 00083 * value of the base address of that page of memory. 00084 */ 00085 if (0 == strcmp(text, "0")) 00086 return NULL; 00087 00088 #if SIZEOF_VOID_P > SIZEOF_LONG 00089 return (void *)explain_parse_longlong_or_die(text); 00090 #else 00091 return (void *)explain_parse_long_or_die(text); 00092 #endif 00093 } 00094 00095 00096 /* vim: set ts=8 sw=4 et : */