libexplain  1.4.D001
libexplain/buffer/errno/getcwd.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - Explain errno values returned by libc functions
00003  * Copyright (C) 2008-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,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser 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/limits.h> /* for PATH_MAX on Solaris */
00020 #include <libexplain/ac/errno.h>
00021 #include <libexplain/ac/string.h>
00022 
00023 #include <libexplain/buffer/efault.h>
00024 #include <libexplain/buffer/enomem.h>
00025 #include <libexplain/buffer/errno/generic.h>
00026 #include <libexplain/buffer/errno/getcwd.h>
00027 #include <libexplain/buffer/get_current_directory.h>
00028 #include <libexplain/buffer/pointer.h>
00029 #include <libexplain/explanation.h>
00030 #include <libexplain/option.h>
00031 
00032 
00033 static void
00034 explain_buffer_errno_getcwd_system_call(explain_string_buffer_t *sb,
00035     int errnum, char *data, size_t data_size)
00036 {
00037     (void)errnum;
00038     explain_string_buffer_puts(sb, "getcwd(data = ");
00039     explain_buffer_pointer(sb, data);
00040     explain_string_buffer_printf(sb, ", data_size = %ld)", (long)data_size);
00041 }
00042 
00043 
00044 static void
00045 explain_buffer_errno_getcwd_explanation(explain_string_buffer_t *sb,
00046     int errnum, char *data, size_t data_size)
00047 {
00048     char            pathname[PATH_MAX * 2 + 1];
00049 
00050     /*
00051      * http://www.opengroup.org/onlinepubs/009695399/functions/getcwd.html
00052      */
00053     switch (errnum)
00054     {
00055     case EINVAL:
00056         explain_string_buffer_puts
00057         (
00058             sb,
00059             /* FIXME: i18n */
00060             "the data_size argument is zero and data is not the NULL pointer"
00061         );
00062         break;
00063 
00064     case ERANGE:
00065         explain_string_buffer_puts
00066         (
00067             sb,
00068             /* FIXME: i18n */
00069             "the data_size argument is less than the length of the "
00070             "working directory name, you need to allocate a bigger "
00071             "array and try again"
00072         );
00073         if (data && data_size && explain_option_dialect_specific())
00074         {
00075             explain_string_buffer_t nowhere;
00076 
00077             explain_string_buffer_init(&nowhere, 0, 0);
00078             if
00079             (
00080                 !explain_buffer_get_current_directory
00081                 (
00082                     &nowhere,
00083                     pathname,
00084                     sizeof(pathname)
00085                 )
00086             )
00087             {
00088                 explain_string_buffer_printf
00089                 (
00090                     sb,
00091                     " (%ld < %ld)",
00092                     (long)data_size,
00093                     (long)(strlen(pathname) + 1)
00094                 );
00095             }
00096         }
00097         break;
00098 
00099     case EACCES:
00100         if
00101         (
00102             !explain_buffer_get_current_directory
00103             (
00104                 sb,
00105                 pathname,
00106                 sizeof(pathname)
00107             )
00108         )
00109         {
00110             explain_string_buffer_puts
00111             (
00112                 sb,
00113                 /* FIXME: i18n */
00114                 "read or search permission was denied for a component "
00115                 "of the pathname"
00116             );
00117         }
00118         break;
00119 
00120     case ENOMEM:
00121         explain_buffer_enomem_user(sb, 0);
00122         break;
00123 
00124     case EFAULT:
00125         explain_buffer_efault(sb, "data");
00126         break;
00127 
00128     case ENOENT:
00129         if
00130         (
00131             !explain_buffer_get_current_directory
00132             (
00133                 sb,
00134                 pathname,
00135                 sizeof(pathname)
00136             )
00137         )
00138         {
00139             explain_string_buffer_puts
00140             (
00141                 sb,
00142                 /* FIXME: i18n */
00143                 "the current working directory has been unlinked"
00144             );
00145         }
00146         break;
00147 
00148     default:
00149         explain_buffer_errno_generic(sb, errnum, "getcwd");
00150         break;
00151     }
00152 }
00153 
00154 
00155 void
00156 explain_buffer_errno_getcwd(explain_string_buffer_t *sb, int errnum,
00157     char *data, size_t data_size)
00158 {
00159     explain_explanation_t exp;
00160 
00161     explain_explanation_init(&exp, errnum);
00162     explain_buffer_errno_getcwd_system_call
00163     (
00164         &exp.system_call_sb,
00165         errnum,
00166         data,
00167         data_size
00168     );
00169     explain_buffer_errno_getcwd_explanation
00170     (
00171         &exp.explanation_sb,
00172         errnum,
00173         data,
00174         data_size
00175     );
00176     explain_explanation_assemble(&exp, sb);
00177 }
00178 
00179 
00180 /* vim: set ts=8 sw=4 et : */