libexplain
1.4.D001
|
00001 /* 00002 * libexplain - Explain errno values returned by libc functions 00003 * Copyright (C) 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 your 00008 * option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful,but WITHOUT 00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 00013 * 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/sys/ioctl.h> 00020 #include <libexplain/ac/errno.h> 00021 #include <libexplain/ac/linux/hdreg.h> 00022 #include <libexplain/ac/linux/msdos_fs.h> /* for SECTOR_SIZE */ 00023 00024 #include <libexplain/buffer/char_data.h> 00025 #include <libexplain/buffer/dac.h> 00026 #include <libexplain/buffer/efault.h> 00027 #include <libexplain/buffer/is_the_null_pointer.h> 00028 #include <libexplain/capability.h> 00029 #include <libexplain/iocontrol/generic.h> 00030 #include <libexplain/iocontrol/hdio_drive_cmd.h> 00031 00032 #include <libexplain/buffer/int.h> 00033 00034 #ifdef HDIO_DRIVE_CMD 00035 00036 00037 static void 00038 print_data(const explain_iocontrol_t *p, explain_string_buffer_t *sb, 00039 int errnum, int fildes, int request, const void *data) 00040 { 00041 (void)p; 00042 (void)errnum; 00043 (void)fildes; 00044 (void)request; 00045 explain_buffer_char_data(sb, data, 4); 00046 } 00047 00048 00049 #define min(a, b) ((a) < (b) ? (a) : (b)) 00050 00051 00052 static void 00053 print_data_returned(const explain_iocontrol_t *p, explain_string_buffer_t *sb, 00054 int errnum, int fildes, int request, const void *data) 00055 { 00056 size_t len; 00057 const unsigned char *args; 00058 00059 (void)p; 00060 (void)errnum; 00061 (void)fildes; 00062 (void)request; 00063 args = data; 00064 /* 00065 * args[0] = status 00066 * args[1] = error 00067 * args[2] = sector count (output) 00068 * args[3] = sector count (input) 00069 */ 00070 len = 4 + SECTOR_SIZE * min(args[2], args[3]); 00071 explain_buffer_char_data(sb, data, len); 00072 } 00073 00074 00075 static void 00076 print_explanation(const explain_iocontrol_t *p, explain_string_buffer_t *sb, int 00077 errnum, int fildes, int request, const void *data) 00078 { 00079 switch (errnum) 00080 { 00081 case EACCES: 00082 /* you need both CAP_SYS_ADMIN and CAP_SYS_RAWIO */ 00083 if (!explain_capability_sys_admin()) 00084 { 00085 explain_buffer_dac_sys_admin(sb); 00086 break; 00087 } 00088 if (!explain_capability_sys_rawio()) 00089 { 00090 explain_buffer_dac_sys_rawio(sb); 00091 break; 00092 } 00093 goto generic; 00094 00095 case EFAULT: 00096 explain_buffer_efault(sb, "data"); 00097 break; 00098 00099 case EINVAL: 00100 if (!data) 00101 { 00102 explain_buffer_is_the_null_pointer(sb, "data"); 00103 break; 00104 } 00105 goto generic; 00106 00107 case ENOMEM: 00108 case EIO: 00109 goto generic; 00110 00111 default: 00112 generic: 00113 explain_iocontrol_generic_print_explanation 00114 ( 00115 p, 00116 sb, 00117 errnum, 00118 fildes, 00119 request, 00120 data 00121 ); 00122 break; 00123 } 00124 } 00125 00126 00127 /* 00128 * The data_size is tricky. On entry, it is always exactly 4. 00129 * The returned data, however, can be up to 4+255*SECTOR_SIZE. 00130 */ 00131 const explain_iocontrol_t explain_iocontrol_hdio_drive_cmd = 00132 { 00133 "HDIO_DRIVE_CMD", /* name */ 00134 HDIO_DRIVE_CMD, /* value */ 00135 0, /* disambiguate */ 00136 0, /* print_name */ 00137 print_data, 00138 print_explanation, 00139 print_data_returned, 00140 sizeof(unsigned char[4]), /* data_size */ 00141 "unsigned char[4]", /* data_type */ 00142 IOCONTROL_FLAG_SIZE_DOES_NOT_AGREE, /* flags */ 00143 __FILE__, 00144 __LINE__, 00145 }; 00146 00147 #else /* ndef HDIO_DRIVE_CMD */ 00148 00149 const explain_iocontrol_t explain_iocontrol_hdio_drive_cmd = 00150 { 00151 0, /* name */ 00152 0, /* value */ 00153 0, /* disambiguate */ 00154 0, /* print_name */ 00155 0, /* print_data */ 00156 0, /* print_explanation */ 00157 0, /* print_data_returned */ 00158 0, /* data_size */ 00159 0, /* data_type */ 00160 0, /* flags */ 00161 __FILE__, 00162 __LINE__, 00163 }; 00164 00165 #endif /* HDIO_DRIVE_CMD */ 00166 00167 00168 /* vim: set ts=8 sw=4 et : */