libexplain
1.4.D001
|
00001 /* 00002 * libexplain - Explain errno values returned by libc functions 00003 * Copyright (C) 2008-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 published by 00008 * the Free Software Foundation; either version 3 of the License, or (at 00009 * 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/errno.h> 00021 #include <libexplain/ac/fcntl.h> 00022 00023 #include <libexplain/buffer/ebadf.h> 00024 #include <libexplain/buffer/eintr.h> 00025 #include <libexplain/buffer/eio.h> 00026 #include <libexplain/buffer/errno/close.h> 00027 #include <libexplain/buffer/errno/generic.h> 00028 #include <libexplain/buffer/fildes_to_pathname.h> 00029 #include <libexplain/buffer/gettext.h> 00030 #include <libexplain/explanation.h> 00031 #include <libexplain/string_buffer.h> 00032 00033 00034 static void 00035 explain_buffer_errno_close_system_call(explain_string_buffer_t *sb, 00036 int errnum, int fildes) 00037 { 00038 (void)errnum; 00039 explain_string_buffer_printf(sb, "close(fildes = %d", fildes); 00040 explain_buffer_fildes_to_pathname(sb, fildes); 00041 explain_string_buffer_putc(sb, ')'); 00042 } 00043 00044 00045 void 00046 explain_buffer_errno_close_explanation(explain_string_buffer_t *sb, 00047 int errnum, const char *syscall_name, int fildes) 00048 { 00049 switch (errnum) 00050 { 00051 case EBADF: 00052 explain_buffer_ebadf(sb, fildes, "fildes"); 00053 break; 00054 00055 case EINTR: 00056 explain_buffer_eintr(sb, syscall_name); 00057 break; 00058 00059 case EIO: 00060 explain_buffer_eio_fildes(sb, fildes); 00061 break; 00062 00063 case EAGAIN: 00064 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN 00065 case EWOULDBLOCK: 00066 #endif 00067 explain_buffer_gettext 00068 ( 00069 sb, 00070 /* 00071 * xgettext: This error message is used when trying to close 00072 * a non-blocking file descriptor that is stillactive. 00073 */ 00074 i18n("the O_NONBLOCK flag was specified, and an operation " 00075 "has yet to complete") 00076 ); 00077 break; 00078 00079 default: 00080 explain_buffer_errno_generic(sb, errnum, syscall_name); 00081 break; 00082 } 00083 00084 /* 00085 * See of the file is still open, and tell the user if it is. 00086 */ 00087 if (fcntl(fildes, F_GETFL) >= 0) 00088 { 00089 explain_string_buffer_puts(sb->footnotes, "; "); 00090 explain_buffer_gettext 00091 ( 00092 sb->footnotes, 00093 /* 00094 * xgettext: This error message is used when a close(2) 00095 * system call fails and the file descriptor remains open. 00096 */ 00097 i18n("note that the file descriptor is still open") 00098 ); 00099 } 00100 } 00101 00102 00103 void 00104 explain_buffer_errno_close(explain_string_buffer_t *sb, int errnum, 00105 int fildes) 00106 { 00107 explain_explanation_t exp; 00108 00109 explain_explanation_init(&exp, errnum); 00110 explain_buffer_errno_close_system_call 00111 ( 00112 &exp.system_call_sb, 00113 errnum, 00114 fildes 00115 ); 00116 explain_buffer_errno_close_explanation 00117 ( 00118 &exp.explanation_sb, 00119 errnum, 00120 "close", 00121 fildes 00122 ); 00123 explain_explanation_assemble(&exp, sb); 00124 } 00125 00126 00127 /* vim: set ts=8 sw=4 et : */