libexplain
1.4.D001
|
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 : */