![]() |
|
Модераторы: xvr |
![]()
|
|
| DimonNew |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 15.5.2006 Репутация: нет Всего: нет |
Народ помогите пожалуйста разобраться в коде, искалл литературу ничего не нашел:
#include <errno.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <wchar.h> #include "libioP.h" static void perror_internal (FILE *fp, const char *s, int errnum) { char buf[1024]; const char *colon; const char *errstring; if (s == NULL || *s == '\0') s = colon = ""; else colon = ": "; errstring = __strerror_r (errnum, buf, sizeof buf); if (_IO_fwide (fp, 0) > 0) (void) __fwprintf (fp, L"%s%s%s\n", s, colon, errstring); else (void) fprintf (fp, "%s%s%s\n", s, colon, errstring); } void perror (const char *s) { int errnum = errno; FILE *fp; int fd = -1; if (__builtin_expect (_IO_fwide (stderr, 0) != 0, 1) || (fd = fileno (stderr)) == -1 || (fd = __dup (fd)) == -1 || (fp = fdopen (fd, "w+")) == NULL) { if (__builtin_expect (fd != -1, 0)) __close (fd); /* Use standard error as is. */ perror_internal (stderr, s, errnum); } else { perror_internal (fp, s, errnum); /* Close the stream. */ fclose (fp); } } libc_hidden_def (perror) Заранее благодарю за помощь. |
|||
|
||||
| GrayCardinal |
|
|||
|
Фигасе ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3039 Регистрация: 9.11.2003 Репутация: 8 Всего: 58 |
DimonNew,
Ничего интересного. Две очень извращенные финкции обработчика ошибок. вот эта фиговина perror_internal (FILE *fp, const char *s, int errnum) проверяет не равен ли дескрипотр потока stderr минус одному. Чела можно понять, C2H5OH он и в африке C2H5OH. Ну по ходу еще проверяется s на ноль и пустую длину это, возьмусь предположить шоб случайно не передали "неправильный" s. Вторая по ходу дела аналогичная только еще юзает __builtin_expect которые для i386 вообще не кодируются в код. Ну и по ходу дела пытается "dup'нуть" (клонировать) и открыть не существующий дискриптор "-1" на запись. Откуда у вас ЭТО ? |
|||
|
||||
| DimonNew |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 15.5.2006 Репутация: нет Всего: нет |
Меня интересует поподробнее это часть:
void perror (const char *s) { int errnum = errno; FILE *fp; int fd = -1; if (__builtin_expect (_IO_fwide (stderr, 0) != 0, 1) || (fd = fileno (stderr)) == -1 || (fd = __dup (fd)) == -1 || (fp = fdopen (fd, "w+")) == NULL) { if (__builtin_expect (fd != -1, 0)) __close (fd); /* Use standard error as is. */ perror_internal (stderr, s, errnum); } else { perror_internal (fp, s, errnum); /* Close the stream. */ fclose (fp); } } libc_hidden_def (perror) Студент я, которому нужна помощь профи это функция Perror точнее обработчик ошибок |
|||
|
||||
| GrayCardinal |
|
|||
|
Фигасе ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3039 Регистрация: 9.11.2003 Репутация: 8 Всего: 58 |
Только, пожалуйста, не говорите что из кода glibc, пожалейте мои нервы.
Добавлено @ 13:25 DimonNew, Ясно что не Вася Пупкин. Ок. Поподробнее. perror Получает строку-константу s. if (__builtin_expect (_IO_fwide (stderr, 0) != 0, 1) Понятия не имею что делает __IO_fwide. (это я-то !). Ну и проверяет что получилось на неравенство нулю. __builtin_expect и последний его аргумент (1) можно просто выбросить. Эт какая-то заморочка-оптимизилка, повторюсь для i386 вообще ничего не делает (скобки раскрываем просто и все). Далее (мама роди меня обратно): 1. (fd = fileno (stderr)) == -1 2. || (fd = __dup (fd)) == -1 3. || (fp = fdopen (fd, "w+")) == NULL) 1. fd присваивается номер дескриптора потока stderr и проверяется на -1 (!) 2. Эту fd пытаются клонировать 3. Из этого fd (дискриптор) пытаются сделать поток ввода - вывода (FILE *fp). Ну, на запись, "с добавлением". Вот. И если все нормально, закрывают этот самый fd. и делают. perror_internal (stderr, s, errnum); Если ошибка - perror_internal не делают. Я еще мог бы предположить что это писал трезвый программист если бы в perror_internal передавался _не_ stderr а _fp_. И все равно брЭд. Из контекста могу предположить что libc_hidden_def (perror) предназначена чтоб заменить perror стандартный своим. |
|||
|
||||
| GrayCardinal |
|
|||
|
Фигасе ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3039 Регистрация: 9.11.2003 Репутация: 8 Всего: 58 |
Извините - код брЭд поэтому и описание - тоже брЭд получилось.
Добавлено @ 13:34 Вам надо чтоб ЭТО работало ? |
|||
|
||||
| DimonNew |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 15.5.2006 Репутация: нет Всего: нет |
Спасибо большое
Тему можно прикрыть |
|||
|
||||
| GrayCardinal |
|
|||
|
Фигасе ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3039 Регистрация: 9.11.2003 Репутация: 8 Всего: 58 |
Млин, понял. Короче все те пункты - если все прошло нормально, вызывается
perror_internal со вновь созданным потоком (клон stderr). Прозевал там вторую perror_internal И все равно бред PS Я когда код вижу - сначала знаю бред это или нет, потому думаю как это может работать |
|||
|
||||
![]()
|
| Правила форума "С/С++: Программирование под Unix/Linux" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |