libexplain
1.4.D001
|
00001 /* 00002 * libexplain - Explain errno values returned by libc functions 00003 * Copyright (C) 2010-2013 Peter Miller 00004 * 00005 * This program is free software; you can redistribute it and/or modify it 00006 * under the terms of the GNU Lesser General Public License as published by 00007 * the Free Software Foundation; either version 3 of the License, or (at 00008 * your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, but 00011 * WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 00013 * General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 #include <libexplain/ac/errno.h> 00020 #include <libexplain/ac/limits.h> /* for PATH_MAX on Solaris */ 00021 #include <libexplain/ac/stdlib.h> 00022 #include <libexplain/ac/stdio.h> /* for TMP_MAX */ 00023 #include <libexplain/ac/string.h> 00024 #include <libexplain/ac/sys/param.h> /* for PATH_MAX everywhere else */ 00025 #include <libexplain/ac/sys/stat.h> 00026 00027 #include <libexplain/is_efault.h> 00028 #include <libexplain/mkdtemp.h> 00029 #include <libexplain/output.h> 00030 00031 00032 #ifndef HAVE_MKDTEMP 00033 00034 static char * 00035 mkdtemp(char *template) 00036 { 00037 char stash[PATH_MAX + 1]; 00038 size_t template_size; 00039 int n; 00040 int save_errno; 00041 00042 save_errno = errno; 00043 if (explain_is_efault_string(template)) 00044 { 00045 errno = EFAULT; 00046 return NULL; 00047 } 00048 template_size = strlen(template) + 1; 00049 if (template_size > sizeof(stash)) 00050 { 00051 errno = ENAMETOOLONG; 00052 return NULL; 00053 } 00054 memcpy(stash, template, template_size); 00055 for (n = 0; n < TMP_MAX; ++n) 00056 { 00057 if (!mkstemp(template)) 00058 return NULL; 00059 if (mkdir(template, 0700) >= 0) 00060 { 00061 errno = save_errno; 00062 return template; 00063 } 00064 if (errno != EEXIST) 00065 return NULL; 00066 memcpy(template, stash, template_size); 00067 } 00068 00069 /* 00070 * This is the defined error in the case where when we run out of 00071 * combinations to try. "Everything we tried already existed." 00072 */ 00073 errno = EEXIST; 00074 return NULL; 00075 } 00076 00077 #endif 00078 00079 char * 00080 explain_mkdtemp_on_error(char *pathname) 00081 { 00082 char *result; 00083 00084 result = mkdtemp(pathname); 00085 if (!result) 00086 { 00087 int hold_errno; 00088 00089 hold_errno = errno; 00090 explain_output_error("%s", explain_errno_mkdtemp(hold_errno, 00091 pathname)); 00092 errno = hold_errno; 00093 } 00094 return result; 00095 } 00096 00097 00098 /* vim: set ts=8 sw=4 et : */