libexplain  1.4.D001
libexplain/buffer/errno/accept.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - Explain errno values returned by libc functions
00003  * Copyright (C) 2008, 2009, 2011, 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/errno.h>
00020 
00021 #include <libexplain/buffer/eagain.h>
00022 #include <libexplain/buffer/ebadf.h>
00023 #include <libexplain/buffer/econnaborted.h>
00024 #include <libexplain/buffer/efault.h>
00025 #include <libexplain/buffer/ehostdown.h>
00026 #include <libexplain/buffer/ehostunreach.h>
00027 #include <libexplain/buffer/eintr.h>
00028 #include <libexplain/buffer/einval.h>
00029 #include <libexplain/buffer/emfile.h>
00030 #include <libexplain/buffer/enetdown.h>
00031 #include <libexplain/buffer/enetunreach.h>
00032 #include <libexplain/buffer/enfile.h>
00033 #include <libexplain/buffer/enobufs.h>
00034 #include <libexplain/buffer/enomem.h>
00035 #include <libexplain/buffer/enonet.h>
00036 #include <libexplain/buffer/enoprotoopt.h>
00037 #include <libexplain/buffer/enosr.h>
00038 #include <libexplain/buffer/enosys.h>
00039 #include <libexplain/buffer/enotsock.h>
00040 #include <libexplain/buffer/eperm.h>
00041 #include <libexplain/buffer/eproto.h>
00042 #include <libexplain/buffer/eprotonosupport.h>
00043 #include <libexplain/buffer/erestart.h>
00044 #include <libexplain/buffer/errno/accept.h>
00045 #include <libexplain/buffer/errno/generic.h>
00046 #include <libexplain/buffer/esocktnosupport.h>
00047 #include <libexplain/buffer/etimedout.h>
00048 #include <libexplain/buffer/fildes_to_pathname.h>
00049 #include <libexplain/buffer/gettext.h>
00050 #include <libexplain/buffer/pointer.h>
00051 #include <libexplain/buffer/socket_type.h>
00052 #include <libexplain/buffer/socklen.h>
00053 #include <libexplain/explanation.h>
00054 #include <libexplain/is_efault.h>
00055 
00056 
00057 static void
00058 explain_buffer_errno_accept_system_call(explain_string_buffer_t *sb,
00059     int errnum, int fildes, struct sockaddr *sock_addr,
00060     socklen_t *sock_addr_size)
00061 {
00062     (void)errnum;
00063     explain_string_buffer_printf(sb, "accept(fildes = %d", fildes);
00064     explain_buffer_fildes_to_pathname(sb, fildes);
00065     explain_string_buffer_puts(sb, ", sock_addr = ");
00066     explain_buffer_pointer(sb, sock_addr);
00067     explain_string_buffer_printf(sb, ", sock_addr_size = ");
00068     explain_buffer_socklen_star(sb, sock_addr_size);
00069     explain_string_buffer_putc(sb, ')');
00070 }
00071 
00072 
00073 static void
00074 explain_buffer_errno_accept_explanation(explain_string_buffer_t *sb,
00075     int errnum, int fildes, struct sockaddr *sock_addr,
00076     socklen_t *sock_addr_size)
00077 {
00078     /*
00079      * http://www.opengroup.org/onlinepubs/009695399/functions/accept.html
00080      */
00081     (void)sock_addr;
00082     switch (errnum)
00083     {
00084     case EAGAIN:
00085 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
00086     case EWOULDBLOCK:
00087 #endif
00088         explain_buffer_eagain_accept(sb);
00089         break;
00090 
00091     case EBADF:
00092         explain_buffer_ebadf(sb, fildes, "fildes");
00093         break;
00094 
00095     case ECONNABORTED:
00096         explain_buffer_econnaborted(sb);
00097         break;
00098 
00099     case EFAULT:
00100         if (explain_is_efault_pointer(sock_addr_size, sizeof(*sock_addr_size)))
00101             explain_buffer_efault(sb, "sock_addr_size");
00102         else
00103             explain_buffer_efault(sb, "sock_addr");
00104         break;
00105 
00106     case EHOSTDOWN:
00107         explain_buffer_ehostdown(sb);
00108         break;
00109 
00110     case EHOSTUNREACH:
00111         explain_buffer_ehostunreach(sb);
00112         break;
00113 
00114     case EINTR:
00115         explain_buffer_eintr(sb, "accept");
00116         break;
00117 
00118     case EINVAL:
00119         if
00120         (
00121             !explain_is_efault_pointer(sock_addr_size, sizeof(*sock_addr_size))
00122         &&
00123             *sock_addr_size <= 0
00124         )
00125         {
00126             explain_buffer_einval_too_small
00127             (
00128                 sb,
00129                 "sock_addr_size",
00130                 *sock_addr_size
00131             );
00132             break;
00133         }
00134         explain_buffer_einval_not_listening(sb);
00135         break;
00136 
00137     case EMFILE:
00138         explain_buffer_emfile(sb);
00139         break;
00140 
00141     case ENETDOWN:
00142         explain_buffer_enetdown(sb);
00143         break;
00144 
00145     case ENETUNREACH:
00146         explain_buffer_enetunreach(sb);
00147         break;
00148 
00149     case ENFILE:
00150         explain_buffer_enfile(sb);
00151         break;
00152 
00153     case ENOBUFS:
00154         explain_buffer_enobufs(sb);
00155         break;
00156 
00157     case ENOMEM:
00158         explain_buffer_enomem_kernel(sb);
00159         break;
00160 
00161 #ifdef ENONET
00162     case ENONET:
00163         explain_buffer_enonet(sb);
00164         break;
00165 #endif
00166 
00167     case ENOPROTOOPT:
00168         explain_buffer_enoprotoopt(sb, "fildes");
00169         break;
00170 
00171     case ENOTSOCK:
00172         explain_buffer_enotsock(sb, fildes, "fildes");
00173         break;
00174 
00175     case ENOSYS:
00176 #if defined(EOPNOTSUPP) && EOPNOTSUPP != ENOSYS
00177     case EOPNOTSUPP:
00178 #endif
00179         explain_buffer_enosys_socket(sb, "accept", fildes);
00180         break;
00181 
00182 #ifdef ENOSR
00183     case ENOSR:
00184         explain_buffer_enosr(sb);
00185         break;
00186 #endif
00187 
00188     case EPERM:
00189         explain_buffer_eperm_accept(sb);
00190         break;
00191 
00192 #ifdef EPROTO
00193     case EPROTO:
00194         explain_buffer_eproto_accept(sb, fildes);
00195         break;
00196 #endif
00197 
00198     case EPROTONOSUPPORT:
00199         explain_buffer_eprotonosupport(sb);
00200         break;
00201 
00202 #ifdef ERESTART
00203     case ERESTART:
00204         explain_buffer_erestart(sb, "accept");
00205         break;
00206 #endif
00207 
00208     case ESOCKTNOSUPPORT:
00209         explain_buffer_esocktnosupport(sb, "accept", fildes);
00210         break;
00211 
00212     case ETIMEDOUT:
00213         explain_buffer_etimedout(sb, "accept");
00214         break;
00215 
00216     default:
00217         explain_buffer_errno_generic(sb, errnum, "accept");
00218         break;
00219     }
00220 }
00221 
00222 
00223 void
00224 explain_buffer_errno_accept(explain_string_buffer_t *sb, int errnum,
00225     int fildes, struct sockaddr *sock_addr, socklen_t *sock_addr_size)
00226 {
00227     explain_explanation_t exp;
00228 
00229     explain_explanation_init(&exp, errnum);
00230     explain_buffer_errno_accept_system_call
00231     (
00232         &exp.system_call_sb,
00233         errnum,
00234         fildes,
00235         sock_addr,
00236         sock_addr_size
00237     );
00238     explain_buffer_errno_accept_explanation
00239     (
00240         &exp.explanation_sb,
00241         errnum,
00242         fildes,
00243         sock_addr,
00244         sock_addr_size
00245     );
00246     explain_explanation_assemble(&exp, sb);
00247 }
00248 
00249 
00250 /* vim: set ts=8 sw=4 et : */