Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Народ SOS срочно, Код программы. 
:(
    Опции темы
DimonNew
Дата 15.5.2006, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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)


Заранее благодарю за помощь. 
PM MAIL   Вверх
GrayCardinal
Дата 15.5.2006, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Фигасе
****


Профиль
Группа: Завсегдатай
Сообщений: 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" на запись. 

Откуда у вас ЭТО ? 


--------------------
PM MAIL WWW   Вверх
DimonNew
Дата 15.5.2006, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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)


Студент я, которому нужна помощь профи smile
это функция Perror точнее обработчик ошибок 
PM MAIL   Вверх
GrayCardinal
Дата 15.5.2006, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Фигасе
****


Профиль
Группа: Завсегдатай
Сообщений: 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 стандартный своим.
 


--------------------
PM MAIL WWW   Вверх
GrayCardinal
Дата 15.5.2006, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Фигасе
****


Профиль
Группа: Завсегдатай
Сообщений: 3039
Регистрация: 9.11.2003

Репутация: 8
Всего: 58



Извините - код брЭд поэтому и описание - тоже брЭд получилось. smile

Добавлено @ 13:34 
Вам надо чтоб ЭТО работало ? smile 


--------------------
PM MAIL WWW   Вверх
DimonNew
Дата 15.5.2006, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 15.5.2006

Репутация: нет
Всего: нет



Спасибо большое 
Тему можно прикрыть  
PM MAIL   Вверх
GrayCardinal
Дата 15.5.2006, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Фигасе
****


Профиль
Группа: Завсегдатай
Сообщений: 3039
Регистрация: 9.11.2003

Репутация: 8
Всего: 58



Млин, понял. Короче все те пункты - если все прошло нормально, вызывается 
perror_internal со вновь созданным потоком (клон stderr).
Прозевал там вторую perror_internal smile
И все равно бред smile

PS
Я когда код вижу - сначала знаю бред это или нет, потому думаю как это может работать smile 


--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0446 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.