POSIX API

Тема в разделе "WASM.HEAP", создана пользователем Nafanya, 10 сен 2011.

  1. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Добрый день. Не смог найти ответа на вопрос.

    В хедерах Линухи (например в unistd.h и в других) приводятся объявления POSIX API:
    ssize_t read(int fd, void *buf, size_t count);
    ssize_t write(int fd, const void *buf, size_t count);
    и т.д.

    POSIX API или System Interface, как я выяснил, это wrapper functions над системными вызовами ядра (syscalls).
    Вопрос - где искать реализацию (implementation) этих POSIX API? Я думаю в исходниках glibc, должна быть, но могу и ошибаться.

    Мне необходимо проследить путь от вызова API до сискола ядра, с целью сравнения двух схожих API. Наверное между этими точками выполняется море кода из обёрток:)
     
  2. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    glibc
     
  3. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Я в шоке... glibc, файл - sendto.c

    Код (Text):
    1. ssize_t
    2. __sendto (fd, buf, n, flags, addr, addr_len)
    3.      int fd;
    4.      __const __ptr_t buf;
    5.      size_t n;
    6.      int flags;
    7.      __CONST_SOCKADDR_ARG addr;
    8.      socklen_t addr_len;
    9. {
    10.   __set_errno (ENOSYS);
    11.   return -1;
    12. }
    Что за кодстайл? Венгерская нотация не соблюдается. Какие-то подчёркивания перед именами, непонятно с какого перепуга взявшиеся (__sendto). Код читать невозможно...

    Это разве определение функции? Почему типы аргументов не указываются перед переменными в круглых скобках?
    Почему разрабы glibc выбрали именно такой непонятный стиль и где документированы эти нюансы?
     
  4. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Это кроссплатформенная либа, компилируемая кучей компиляторов под различные целевые операционные и процессорные системы. Так что не пугайтесь ;)

    __sendto -- это скорее всего просто имя обёртки
     
  5. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Это из первых стандартов с++ вы что Страуструпа не читали?
     
  6. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
  7. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Оу, человек впервые добрался до кроссплатформенных стандартных хидеров.
    Конец немного предсказуем - http://lurkmore.ru/Shit_bricks
     
  8. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Nafanya
    Чего вы хотите от Си? Это кроссплатформенный ассемблер, хотите иного - юзайте типобезопасные языки, к примеру С++. Про венгерскую нотацию даже не заикайтесь - закопать не думая.
     
  9. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Booster

    Сейчас склонировал репозиторий glibc с git://sourceware.org/git/glibc.git на свою локальную тачку.
    Исходные тексты в репозитории те же самые, как и в архиве.
    Оказывается действительно разработчики развивают и поддерживают дерево в таком виде. Куча макросов и странности в именовании идентификаторов их не смущают.

    Продукт развивается, вот фото с системы контроля версий glibc:
    [​IMG]

    Видимо дело во мне, судя по фото - процесс разработки и фиксинга баг идёт непрерывно для glibc - значит другие программисты без затруднений читают такой кроссплатформенный код.
     
  10. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Ребята, может кто знает какие IDE применяют для навигации по огромным проектам (например - репозиторий glibc ~230 MB, Linux Kernel > полгига)?

    Студия уже не справляется, виснет, тормозит. Хотя по проекту с исходниками около 1,5 мегабайт навигация идёт очень шустро - моментальный переход от вызова функции к её определению.

    И ещё в огромных проектах - большая вложенность директорий с исходниками, а Студия видимо не поддерживает рекурсивный поиск headers и sources по вложенным каталогам при парсинге. Ищет только в путях прописанных в Include Directories и Sources Directories
     
  11. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    man ctags
    man cscope

    etags для emacs

    Билдовая система ядра может делать тэг-файлы, make help в помощь.
     
  12. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    7mm

    Спасибо, заюзал cscope.
    Если у вас есть исходники glibc, прошу взглянуть на следующий феномен.

    POSIX API sendto():
    sendto() -> __sendto -> __socket_send()
    Всё цепочка обрывается - ни cscope, ни grep, ни Студия не может найти определения wrapper-function: __socket_send(). Она только вызывается, но нет ни #define __socket_send ..., ни определения этой обёртки - какая-то функция-призрак.
     
  13. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    sendto.c - body of __sendto() wrapper function:

    Код (Text):
    1. ssize_t
    2. __sendto (int fd,
    3.       const void *buf,
    4.       size_t n,
    5.       int flags,
    6.       const struct sockaddr_un *addr,
    7.       socklen_t addr_len)
    8. {
    9.   addr_port_t aport;
    10.   error_t err;
    11.   size_t wrote;
    12.  
    13.   if (addr->sun_family == AF_LOCAL)
    14.     {
    15.       /* For the local domain, we must look up the name as a file and talk
    16.      to it with the ifsock protocol.  */
    17.       file_t file = __file_name_lookup (addr->sun_path, 0, 0);
    18.       if (file == MACH_PORT_NULL)
    19.     return -1;
    20.       err = __ifsock_getsockaddr (file, &aport);
    21.       __mach_port_deallocate (__mach_task_self (), file);
    22.       if (err == MIG_BAD_ID || err == EOPNOTSUPP)
    23.     /* The file did not grok the ifsock protocol.  */
    24.     err = ENOTSOCK;
    25.       if (err)
    26.     return __hurd_fail (err);
    27.     }
    28.   else
    29.     err = EIEIO;
    30.  
    31.   /* Get an address port for the desired destination address.  */
    32.   err = HURD_DPORT_USE (fd,
    33.             ({
    34.               if (err)
    35.                 err = __socket_create_address (port,
    36.                                addr->sun_family,
    37.                                (char *) addr,
    38.                                addr_len,
    39.                                &aport);
    40.               if (! err)
    41.                 {
    42.                   /* Send the data.  */
    43.                   err = __socket_send (port, aport,
    44.                            flags, buf, n,
    45.                            NULL,
    46.                            MACH_MSG_TYPE_COPY_SEND, 0,
    47.                            NULL, 0, &wrote);      //HERE WE CALL __socket_send FUNCTION!!!
    48.                   __mach_port_deallocate (__mach_task_self (),
    49.                               aport);
    50.                 }
    51.               err;
    52.             }));
    53.  
    54.   return err ? __hurd_sockfail (fd, flags, err) : wrote;
    55. }
    56.  
    57. weak_alias (__sendto, sendto)
    Где в glibc определение (тело) __socket_send функции? Поиск по всем файлам результата не дал. Вызывать функции без тела нельзя, а она вызывается. Как разрешить это противоречие?
     
  14. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    А вас не смущает, что вы смотрите в исходниках для HURD?...

    Код (Text):
    1. im@r00tbox:~/projects/glibc$ grep -r -n "__socket_send" ./*
    2. ./ChangeLog.4:1860:     * sysdeps/mach/hurd/send.c: Fix portsPoly arg to __socket_send.
    3. ./sysdeps/mach/hurd/sendmsg.c:144:                            err = __socket_send (port, aport,
    4. ./sysdeps/mach/hurd/sendto.c:71:                              err = __socket_send (port, aport,
    5. ./sysdeps/mach/hurd/send.c:36:  err = HURD_DPORT_USE (fd, __socket_send (port, MACH_PORT_NULL,
    Код (Text):
    1. im@r00tbox:~/projects/glibc$ grep -r -n "__socket_create_address" ./*
    2. ./sysdeps/mach/hurd/sendmsg.c:136:                          err = __socket_create_address (port,
    3. ./sysdeps/mach/hurd/sendto.c:63:                            err = __socket_create_address (port,
    4. ./sysdeps/mach/hurd/connect.c:61:                           err = __socket_create_address (port,
    5. ./sysdeps/mach/hurd/bind.c:109:                     err = __socket_create_address (port,
     
  15. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    7mm
    Можно поподробнее Вашу мысль?

    Вам удалось найти в glibc тела для следующих функций?
    1)__socket_send()
    2)__libc_sendto() - это псевдоним для __sendto()

    Мне нет.
     
  16. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    /socket/sendto.c - Тихий ужас.

    Код (Text):
    1. /* Send N bytes of BUF on socket FD to peer at address ADDR (which is
    2.    ADDR_LEN bytes long).  Returns the number sent, or -1 for errors.  */
    3. ssize_t
    4. __sendto (fd, buf, n, flags, addr, addr_len)
    5.      int fd;
    6.      __const __ptr_t buf;
    7.      size_t n;
    8.      int flags;
    9.      __CONST_SOCKADDR_ARG addr;
    10.      socklen_t addr_len;
    11. {
    12.   __set_errno (ENOSYS);
    13.   return -1;
    14. }
    15.  
    16. weak_alias (__sendto, sendto)
    Зачем это? Чтобы вместо отправки данных в сокет API sendto() сообщала об ошибке? Такой реализации я не ожидал...
     
  17. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    glibc/sysdeps/unix/sysv/linux/x86_64/send.c

    Код (Text):
    1. #include <errno.h>
    2. #include <sys/socket.h>
    3. #include <sysdep-cancel.h>
    4.  
    5. /* Send N bytes of BUF to socket FD.  Returns the number sent or -1.  */
    6. ssize_t
    7. __libc_send (int fd, const void *buf, size_t n, int flags)
    8. {
    9.   if (SINGLE_THREAD_P)
    10.     return INLINE_SYSCALL (sendto, 6, fd, buf, n, flags, NULL, (size_t) 0);
    11.  
    12.   int oldtype = LIBC_CANCEL_ASYNC ();
    13.  
    14.   ssize_t result = INLINE_SYSCALL (sendto, 6, fd, buf, n, flags, NULL,
    15.                                    (size_t) 0);
    16.  
    17.   LIBC_CANCEL_RESET (oldtype);
    18.  
    19.   return result;
    20. }
    21.  
    22. weak_alias (__libc_send, __send)
    23. libc_hidden_weak (__send)
    24. weak_alias (__send, send)
    __send weak alias для __libc_send

    * Вопрос в том, зачем вы смотрите в исходниках для HURD?
     
  18. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Это функция-заглушка, для того, чтобы если система не поддерживает операции с сокетами, то по запросу операции выдавалась бы ошибка. Смотрите weak_alias и __attribute__ weak для функций в gcc.
     
  19. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    7mm

    Так мне необходимо добраться до syscall'а ядра для API sendto() , а у ВАС:
    weak_alias (__libc_send, __send)
    libc_hidden_weak (__send)
    weak_alias (__send, send)

    Это API send(). Но всё равно спасибо.
     
  20. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    INLINE_SYSCALL -- вот он, системный вызов