libexplain  1.4.D001
libexplain/buffer/errno/ioctl.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/ctype.h>
00020 #include <libexplain/ac/string.h>
00021 
00022 #include <libexplain/buffer/errno/ioctl.h>
00023 #include <libexplain/buffer/fildes_to_pathname.h>
00024 #include <libexplain/iocontrol.h>
00025 #include <libexplain/explanation.h>
00026 
00027 
00028 static int
00029 last_char(const char *s)
00030 {
00031     if (!s || !*s)
00032         return 0;
00033     while (s[1])
00034         ++s;
00035     return (unsigned char)*s;
00036 }
00037 
00038 
00039 static void
00040 system_call(const explain_iocontrol_t *p, explain_string_buffer_t *sb,
00041     int errnum, int fildes, int request, const void *data)
00042 {
00043     (void)errnum;
00044     explain_string_buffer_printf(sb, "ioctl(fildes = %d", fildes);
00045     explain_buffer_fildes_to_pathname(sb, fildes);
00046     explain_string_buffer_puts(sb, ", request = ");
00047     explain_iocontrol_print_name(p, sb, errnum, fildes, request, data);
00048     explain_string_buffer_puts(sb, ", ");
00049     if (data && p->data_type)
00050     {
00051         const char      *s;
00052         const char      *a;
00053 
00054         s = p->data_type;
00055         a = strchr(s, '[');
00056         if (a)
00057         {
00058             const char      *e;
00059 
00060             e = a;
00061             while (e > s && isspace((unsigned char)e[-1]))
00062                 --e;
00063             explain_string_buffer_write(sb, s, e - s);
00064             if (isalpha((unsigned char)e[-1]))
00065                 explain_string_buffer_putc(sb, ' ');
00066             explain_string_buffer_puts(sb, "data");
00067             explain_string_buffer_puts(sb, a);
00068         }
00069         else
00070         {
00071             explain_string_buffer_puts(sb, p->data_type);
00072             if (isalpha(last_char(p->data_type)))
00073                 explain_string_buffer_putc(sb, ' ');
00074             explain_string_buffer_puts(sb, "data");
00075         }
00076     }
00077     else
00078         explain_string_buffer_puts(sb, "data");
00079     explain_string_buffer_puts(sb, " = ");
00080     explain_iocontrol_print_data(p, sb, errnum, fildes, request, data);
00081     explain_string_buffer_putc(sb, ')');
00082 }
00083 
00084 
00085 void
00086 explain_buffer_errno_ioctl(explain_string_buffer_t *sb, int errnum,
00087     int fildes, int request, void *data)
00088 {
00089     const explain_iocontrol_t *p;
00090     explain_explanation_t exp;
00091 
00092     explain_explanation_init(&exp, errnum);
00093     p = explain_iocontrol_find_by_number(fildes, request, data);
00094     system_call(p, &exp.system_call_sb, errnum, fildes, request, data);
00095     explain_iocontrol_print_explanation
00096     (
00097         p,
00098         &exp.explanation_sb,
00099         errnum,
00100         fildes,
00101         request,
00102         data
00103     );
00104     explain_explanation_assemble(&exp, sb);
00105 }
00106 
00107 /* vim: set ts=8 sw=4 et : */