Задать вопрос
Ответы пользователя по тегу C
  • Как общаться с процессом в Linux?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Нужно написать программу, которая будет посылать в stdin программы данные и забирать из stdout.

    Что я делаю не так?


    Ты пользуешься не тем методом. pidfd_open делает совсем не то, что ты ожидаешь, см. раздел "Use cases for PID file descriptors" по приведённой ссылке.

    Взаимодействие с дочерним процессом через stdin/stdout обычно реализуется через пайп. Вот пример.

    Вот ещё пример который делает exec

    #include <unistd.h>
    
    int main()
    {
            int fd[2][2];
            pipe(fd[0]);
            pipe(fd[1]);
            pid_t pid_fork = fork();
            if (!pid_fork) {
                    // Дочерний процесс
                    close(fd[0][1]);
                    close(fd[1][0]);
                    dup2(fd[0][0], STDIN_FILENO);
                    dup2(fd[1][1], STDOUT_FILENO);
                    execl("/usr/bin/tr", "/usr/bin/tr", "l", "r", NULL);
            } else {
                    // Родительский процесс
                    close(fd[0][0]);
                    close(fd[1][1]);
                    char buf[1000];
                    ssize_t sz;
    
                    write(fd[0][1], "hello, world\n", sizeof("hello, world\n") - 1);
                    close(fd[0][1]);
                    sz = read(fd[1][0], buf, sizeof(buf));
                    if (sz > 0) {
                            write(STDOUT_FILENO, buf, sz);
                    }
            }
            return 0;
    }
    Ответ написан
    Комментировать
  • Почему после вызова Message Box, GetKeyState() не считывает состояние клавиши?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему … GetKeyState() не считывает состояние клавиши?

    Потому что чтобы GetKeyState работал, поток должен обрабатывать свою очередь сообщений (например, циклом, наподобие этого).
    Из man GetKeyState:
    The key status returned from this function changes as a thread reads key messages from its message queue. The status does not reflect the interrupt-level state associated with the hardware. Use the GetAsyncKeyState function to retrieve that information.
    Ответ написан
    Комментировать
  • Почему для драйвера мыши используется тот же порт, что и в драйвере клавиатуры?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Такие же порты используются при нахождении нажатой клавиши на клавиатуре, так как они могут быть и там и тут?

    Это называется мультиплексирование. В конце концов PS/2 -- довольно сложный интерфейс, работающий с командами, а не то чтобы клавиатура была напрямую подсоединена к одному из портов PC. См. https://wiki.osdev.org/Mouse_Input#Keyboard.2FAux_...
    Ответ написан
    Комментировать
  • Как исправить ошибку "Кадр не находится в модуле" при создании потока?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    "Кадр не находится в модуле". Подскажите с чем это может быть связано
    HANDLE h = CreateThread(
        NULL,
        0,
        factorial(gn),
        NULL,
        NULL,
        NULL
    );

    Третий параметр CreateThread -- указатель на функцию, которая будет запущена в создаваемом потоке. А у тебя записано скорее всего что-то другое. Если ты хотел запустить функцию factorial в потоке, она должна 1) иметь определённый прототип (вот такой), и 2) в функцию CreateThread надо передать её адрес, а не результат её вызова (например, так: CreateThread(NULL, 0, factorial, NULL, NULL, NULL)). 3) если ты сделаешь эти два изменения, тебе прийдётся также переделать передачу параметра в функцию factorial и получение результата её работы.
    Ответ написан
  • Как реализовать _open() для добавления своих потоков ввода-вывода?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почитать про libgloss, понять что надо самому разбирать пути переданные в параметре name и где-то хранить данные о том, что за файл и как был открыт. Понять, как именно ты хочешь "реализовать работу со своими устройствами" и… реализовать её.
    Ответ написан
  • Почему не работает inportb(0x60)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    во-первых компилятор даёт предупреждение, … , но ошибки не производит. Я спокойно линкую файл недо-драйвера с основным ядром, (конечный результат - .efi),

    Дело в том, что у EFI-приложений нет динамической линковки, а неопределённый символ после копирования из .so в .efi просто ссылается в никуда. Если вывести неопределённые символы для bootx64.so, то inportb будет среди них:
    objdump -t bootx64.so | grep UND
    0000000000000000         *UND*  0000000000000000 inportb


    В qemu результат вызова этой функции выглядит так:
    Trace 0: 0x7fb15d338e80 [0000000000000000/000000007e6e22de/0x40c2b0]
    ----------------                      
    IN: 
    0x7e6e2081:  bf 60 00 00 00           movl     $0x60, %edi
    0x7e6e2086:  b8 00 00 00 00           movl     $0, %eax
    0x7e6e208b:  e8 90 57 00 00           callq    0x7e6e7820
    
    Trace 0: 0x7fb15d3390c0 [0000000000000000/000000007e6e2081/0x40c2b0]
    ----------------                      
    IN: 
    0x7e6e7820:  af                       scasl    (%rdi), %eax
    0x7e6e7821:  af                       scasl    (%rdi), %eax
    0x7e6e7822:  af                       scasl    (%rdi), %eax
    0x7e6e7823:  af                       scasl    (%rdi), %eax
    0x7e6e7824:  af                       scasl    (%rdi), %eax
    0x7e6e7825:  af                       scasl    (%rdi), %eax
    0x7e6e7826:  af                       scasl    (%rdi), %eax
    0x7e6e7827:  af                       scasl    (%rdi), %eax
    0x7e6e7828:  af                       scasl    (%rdi), %eax
    0x7e6e7829:  af                       scasl    (%rdi), %eax
    0x7e6e782a:  af                       scasl    (%rdi), %eax
    0x7e6e782b:  af                       scasl    (%rdi), %eax
    …


    С другой стороны, если предоставить такую функцию:
    unsigned char
    inportb(unsigned short port)
    {
            unsigned char v;
            asm volatile ("in {%1|%b0}, {%b0|%1}\n" : "=a"(v) : "d"(port));
            return v;
    }

    то она прекрасно вызывается и возвращает значение.

    Можно добавить опцию -zdefs в команду линковки чтобы получать ошибку линковки при наличии ссылок на неопределённые символы.

    Чтобы посмотреть, какой именно код выполняется, я запускаю qemu с монитором в консоли (дополнительным ключом -monitor stdio). Я нажимаю ESC когда в QEMU запускается tianocore и выбираю Boot Manager -> EFI Internal Shell, а там пишу fs0:efi\boot\bootx64.efi, после этого в мониторной консоли включаю логгирование (командами logfile log, log in_asm,exec), после чего нажимаю enter в консоли EFI. После этого можно смотреть в файл log и искать в нём знакомые байты из objdump.
    Ответ написан
  • Как сортировать данные структуры по дате, если дата задаётся символьной строкой?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как сортировать данные структуры по дате, если дата задаётся символьной строкой?

    Строки вида yyyymmdd можно сортировать с помощью qsort сравнивая их функцией strcmp.
    Ответ написан
    Комментировать
  • Почему при работе с бинарными файлами .exe вызвал срабатывание точки останова СИ?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Первая функция работает, а при вызове второй функции - "срабатывание точки останова" при присвоении переменной fp указателя на поток - при вызове функции fopen(). Помогите разобраться с проблемой не понимаю, где ошибка.

    Вторая функция как-то очень сильно завязана на первую: arr она не инициализирует и считает, что там достаточно места для содержимого файла. Но это всё происходит после заявленной проблемы.
    В первой функции вызовы gets читают строчки неограниченной длины в какие-то поля твоей структуры. Определения структуры ты не привёл, но мой магический шар говорит, что gets вполне может вылезти за пределы полей в которые он читает и поломать кучу. Можно попробовать заменить gets(x) на fgets(x, sizeof(x), stdin).
    Ответ написан
  • Как программа получает ввод?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Здесь нет ни putchar(), ни scanf(), ни тому подобного.

    есть c = getchar().

    ОТКУДА программа получает ввод?

    из стандартного потока ввода, откуда getchar читает символы.
    Ответ написан
    Комментировать
  • Почему память в стеке для auto переменной не резервируется с помощью rsp?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    А почему память не резервируется с помощью rsp? А если произойдет прерывание? Или тут какая-то хитрость?


    Тут какая-то хитрость под названием red zone.
    Ответ написан
    Комментировать
  • Что больше? 1073741024 или 2147483648?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    на сегодня уже хватит программирования?

    на сегодня уже хватит программирования. Речь о размере объекта (в байтах), а каждый элемент массива int наверняка занимает хотя бы 4 байта.
    Ответ написан
    Комментировать
  • Откуда берется "OK" в виртуальном терминале?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    откуда взялся тот OK?

    пришёл от модема, в ответ на AT-команду.
    Ответ написан
  • Какой тип данных используется для чисел с фиксированной запятой на C?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Какой тип данных используется для чисел с фиксированной запятой на C?

    Нет такого стандартизированного типа данных.

    мне нужно провести вычисления с фиксированной запятой

    Логичнее всего использовать какой-нибудь целочисленный тип.
    Ответ написан
    2 комментария
  • Как прочитать из файла?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я уже просто испробовал много способов,но никак не дебажется.

    вот тебе цикл, который считает слова в файле fin, не расстраивайся:
    int z = 0;
    
    while (fscanf(fin, "%*s") == 0)
        ++z;
    Ответ написан
    Комментировать
  • Что не так с вложенным циклом?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    На выходе почему-то не выводятся все значения у, а только y=0

    У тебя там getchar() в коде стоит на каждой итерации по y. Ты на Enter-то нажимаешь?
    Ответ написан
    Комментировать
  • Вызов функции C в другом файле. Как реализовать?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Код выглядит нормально. Разбирайся с тем как выполняется сборка проекта. Похоже, что проект не линкуется с main.o
    Ответ написан
    Комментировать
  • Проблема с перестановками строк?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    array[pair[0]][1]=array[pair[1]][i];

    Ошибка здесь. Вместо первой 1 должна быть i.
    Ответ написан
  • Как реализовать на с или assembler асинхронную выборку из RAM?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как реализовать на с или assembler асинхронную выборку из RAM?

    Например так. Это часть реализации memcpy для MIPS. Этот код не выглядит асинхронным, но написан именно так (сначала групповая загрузка в разные регистры, потом изменение базового адреса загрузки, потом групповое сохранение, потом изменение базового адреса сохранения) с рассчётом на то, что процессор сможет, в том числе, перекрыть во времени операции загрузки, арифметики и сохранения данных.
    Ответ написан
    2 комментария
  • Include/header guards зачем?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Зачем нужны header guards если в заголовочных файлах мы пишем только объявление функции?

    Не всегда мы пишем только объявления. Иногда мы там пишем определения, например определяем структуры, или псевдонимы типов (typedef). Повторное определение таких вещей -- ошибка. Тут ты можешь сказать: "но я подключаю хедер в каждый исходник только один раз". Да, пока проект простой можно это отследить. Но когда одни хедеры начинают подключать другие хедеры это становится делать сложнее. header guards упрощают развитие проекта.
    Иногда между хедерами бывают циклические зависимости, header guards позволяют разорвать цикл.
    Ответ написан
    Комментировать