Няшная / Говнокод #26828 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+  N T M a p M e m o r y                                                      %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Mmap() emulates the Unix method of the same name.
%
%  The format of the NTMapMemory method is:
%
%    MagickPrivate void *NTMapMemory(char *address,size_t length,int protection,
%      int access,int file,MagickOffsetType offset)
%
*/
MagickPrivate void *NTMapMemory(char *address,size_t length,int protection,
  int flags,int file,MagickOffsetType offset)
{
  DWORD
    access_mode,
    high_length,
    high_offset,
    low_length,
    low_offset,
    protection_mode;

  HANDLE
    file_handle,
    map_handle;

  void
    *map;

  (void) address;
  access_mode=0;
  file_handle=INVALID_HANDLE_VALUE;
  low_length=(DWORD) (length & 0xFFFFFFFFUL);
  high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL);
  map_handle=INVALID_HANDLE_VALUE;
  map=(void *) NULL;
  low_offset=(DWORD) (offset & 0xFFFFFFFFUL);
  high_offset=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL);
  protection_mode=0;
  if (protection & PROT_WRITE)
    {
      access_mode=FILE_MAP_WRITE;
      if (!(flags & MAP_PRIVATE))
        protection_mode=PAGE_READWRITE;
      else
        {
          access_mode=FILE_MAP_COPY;
          protection_mode=PAGE_WRITECOPY;
        }
    }
  else
    if (protection & PROT_READ)
      {
        access_mode=FILE_MAP_READ;
        protection_mode=PAGE_READONLY;
      }
  if ((file == -1) && (flags & MAP_ANONYMOUS))
    file_handle=INVALID_HANDLE_VALUE;
  else
    file_handle=(HANDLE) _get_osfhandle(file);
  map_handle=CreateFileMapping(file_handle,0,protection_mode,high_length,
    low_length,0);
  if (map_handle)
    {
      map=(void *) MapViewOfFile(map_handle,access_mode,high_offset,low_offset,
        length);
      CloseHandle(map_handle);
    }
  if (map == (void *) NULL)
    return((void *) ((char *) MAP_FAILED));
  return((void *) ((char *) map));
}

Мумуляция «mmap» в «Винде». Это даже работает, если пофиксить две строчки (кто угадает, какие именно, тому ничего).

Отсюда:
https://github.com/ImageMagick/ImageMagick/blob/master/MagickCore/nt-base.c

Запостил: Myxa Myxa, (Updated )

Комментарии (29) RSS

  • SEO-пост.

    Метки: #виндовоз, #ленсук, #мумуляция, #целыйпитух.
    Ответить
  • Что мне не нравится: злоупотребление типом int и прочими типами неопределённого размера. На некоторых компиляторах можно поймать какой багор.

    Код (offset >> 32) на 32-битном x86 может выполниться вообще без сдвига (посчитается как просто offset), если offset случайно окажется 32-битным, поэтому безопаснее писать так:
    (uint64_t) offset >> 32
    Я всё-таки надеюсь на то, что MagickOffsetType шире 32 бит в любом компиляторе (мне лень искать его определение).

    И ещё у них забавный гольф: (void *) ((char *) map). Зачем такие многократные приведения указателей?
    Ответить
    • Винда ж, откуда там "некоторые конпеляторы". Все под мс по конвеншону подстраиваются.
      Ответить
    • > low_length=(DWORD) (length & 0xFFFFFFFFUL);
      > high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL);

      Я с определённых пор возненавидел эти байтоёбские сдвиги, маски.
      union и bit fields должны сделать код ГОРАЗДО читабельнее.
      Насчёт Ub и прочих багров не уверен. Но можно вместо union скастить в struct.
      Ответить
        • И в новых стандартах?

          Пиздец. Почему они их не починят?

          >implementarion defined. Нахуй и впизду.
          Ну для MS-онли-компилера может и сойдёт.
          Ответить
          • А как их починишь? Это ж придётся все конпеляторы к одному представлению привести. У кого не такой implementation defined был - тот соснул вместе со всей кодовой базой.
            Ответить
            • > Это ж придётся все конпеляторы к одному представлению привести.
              Да.
              Ну в стандарт записать как надо ложить.
              И пусть ебутся чтобы соотвествовать.
              Ответить
              • Монетку что ли подбросить? Или кто больше заплатит?
                Ответить
  • Поздно, чтобы вчитываться.

    Но в Луниксе mmap используется не только для файлов, но и как Царская альтернатива mallocу.

    Тут к сожалению не реализован сей нюанс. Какой-то VirtualAlloc.
    Ответить
    • Реализован. Анонимный маппинг же через инвалид хендл в строке 66.
      Ответить
        • С этого кайфанул:
          #define SERVER_START_REQ(type) \
              do { \
                  struct __server_request_info __req; \
                  struct type##_request * const req = &__req.u.req.type##_request; \
                  const struct type##_reply * const reply = &__req.u.reply.type##_reply; \
                  memset( &__req.u.req, 0, sizeof(__req.u.req) ); \
                  __req.u.req.request_header.req = REQ_##type; \
                  __req.data_count = 0; \
                  (void)reply; \
                  do
          
          #define SERVER_END_REQ \
                  while(0); \
              } while(0)

          Использование
          SIZE_T ret = 0;
                  SERVER_START_REQ( get_mapping_committed_range )
                  {
                      req->base   = wine_server_client_ptr( view->base );
                      req->offset = start << page_shift;
                      if (!wine_server_call( req ))
                      {
                          ret = reply->size;
                          if (reply->committed)
                          {
                              *vprot |= VPROT_COMMITTED;
                              set_page_vprot_bits( base, ret, VPROT_COMMITTED, 0 );
                          }
                      }
                  }
                  SERVER_END_REQ;
                  return ret;

          Какая фабрика )))
          Ответить
  • Начнём с того, что они пиздоглазые мудилы в «MapViewOfFile» смещение — вовсе не произвольное число:
    That is, the offset must be a multiple of the allocation granularity.

    Пользователи этого кода рискуют поиметь здоровенные багры. Сам когда-то на это налетал.
    Ответить
    • А в mmap разве произвольное?

      А, понял, в ммап 4к. А в винде 64к.
      Ответить
      • > А в mmap разве произвольное?
        А, не знал. Ну тогда багры будут с allocation granularity, ага.
        Ответить
        • Да никто не передает туда адрес...

          Кроме ебучего mingw, которое иногда падает на форке из-за того что адрес занят.
          Ответить
          • Ага, после установки некоторых пакетов приходится выполнять rebase, чтобы «mingw» снова мог форкать.

            Точнее, не в «mingw», а в «MSYS» (позиксовый слой для «mingw») и в «Cygwin».
            Ответить
            • >после установки некоторых пакетов приходится выполнять rebase, чтобы «mingw» снова мог форкать
              Ой, помню этот багор.

              И даже не после установки. А во время работы. Собираешь что-то мейком: хуяк система залипла.

              Я ещё тогда на 32-битной системе был, это ОЧЕНЬ сильно раздражало. Т.к. виртуальной памяти было не так много.
              Ответить
            • А, туплю. Ну кстати смещение в mmap тоже выровнено должно быть.
              Ответить
            • То есть если всегда мапить файлы с нулевого смещения, то дефект реализации не заметишь?
              Ответить
              • Подтверждаю.
                Впрочем, я сейчас в эту портянку вчитываться не хочу, мне ещё спать идти, желательно без кошмаров про превращение в итератор DWORD64. Так что там могут и другие багры быть.
                Ответить
                • Затем заставляют представить DWORD64. Неподготовленный человек боится представить DWORD64 так как некоторые участки подсознания не могут совместить DWORD и 64. Этот страх подпитывает страх суицида и разрушение чёткости логики.

                  Говорят, что для того, чтобы это прекратилось необходимо использовать DWORDLONG.
                  Ответить
      • For mmap(), offset must be a multiple of the underlying huge page size.  The system automatically aligns length to be a multiple of the underlying huge page size.
        
        offset must be a multiple of the page size as returned by sysconf(_SC_PAGE_SIZE).
        
         For mmap(), offset must be a multiple of the underlying huge page size.  
        The system automatically aligns length to be a multiple of the underlying huge page size.
        
        Library/kernel differences
               This  page  describes the interface provided by the glibc mmap() wrapper function.  Originally, this function invoked a system call of the same name.  Since kernel 2.4, that
               system call has been superseded by mmap2(2), and nowadays the glibc mmap() wrapper function invokes mmap2(2) with a suitably adjusted value for offset.
        Ответить
      • >А, понял, в ммап 4к
        Вот хуй.
        Если там huge pages, то может быть и 2Mb и 4Mb (емнип на армах).
        Ответить
  • > ((void *) ((char *) map))

    А зачем?
    Ответить

Добавить комментарий для 3.14159265 Отменить ответ

Из-за тебя ушел bormand, guest!

    А не использовать ли нам bbcode?


    8