lirc и O_NONBLOCK (Надо как-то разблокировать сокет, в нете полно информации, но не работ)

Модератор: Модераторы разделов

Ответить
spilver
Сообщения: 6
ОС: Archlinux

lirc и O_NONBLOCK

Сообщение spilver »

Всем привет. Столкнулся с такой проблемой.
Пытаюсь написать небольшое приложение для lirc.

Код: Выделить всё

#include <errno.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <lirc/lirc_client.h>

#include <fcntl.h>
#include <assert.h>

int sock, i=1;

void setSockNonblock(int sockfd)
{
    int arg = fcntl(sockfd, F_GETFL, NULL);
    arg |= O_NONBLOCK;
    fcntl(sockfd, F_SETFL, arg); // ---> Segfault Here
}


int main(int argc, char *argv[]) {

    struct lirc_config *config;
    char argf[]="irexec";
    char *progname=argf, *code, *c;
    int ret, flags;

    sock= lirc_init(argf,1);
    lirc_readconfig(NULL,&config,NULL);

    setSockNonblock(sock);

    while(lirc_nextcode(&code)==0) {
        ret=lirc_code2char(config,code,&c);
        if (c) printf("Execing command \"%s\" :: %d\n",c, i);
        else printf(":: %d\n", i);
        i++; // Только для визуального наблюдения, что цикл проходит и сокет разблокирован
    }

    lirc_freeconfig(config);
    lirc_deinit();
    return 0;
}


для того чтобы проверка lirc_code2char работала в цикле нужно разблокировать сокет, что я и сделал установив флаг O_NONBLOCK, но почему-то именно при установке этого флага программа сегфолтится...

Код: Выделить всё

./lirc
Ошибка сегментирования
./gdb lirc
(gdb) run
segfault
(gdb) backtrace
#0  0x00007ffff70ad7af in __rawmemchr_sse2 () from /lib/libc.so.6
#1  0x00007ffff7099170 in _IO_str_init_static_internal () from /lib/libc.so.6
#2  0x00007ffff7089580 in __isoc99_vsscanf () from /lib/libc.so.6
#3  0x00007ffff7089517 in __isoc99_sscanf () from /lib/libc.so.6
#4  0x00007ffff7bd718b in ?? () from /usr/lib/liblirc_client.so.0
#5  0x00007ffff7bd8e77 in lirc_code2char () from /usr/lib/liblirc_client.so.0
#6  0x0000000000400926 in main (argc=1, argv=0x7fffffffe668) at main.cc:35

и все, тупик, ничего по этой проблеме не нашел...
Все пишут что этого достаточно, отзывов я не нашел. У меня это почему-то не работает
Может быть кто-то сталкивался с подобным ? Как побороть эту беду ?

Заранее спасибо за помощь
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: lirc и O_NONBLOCK

Сообщение /dev/random »

spilver писал(а):
14.01.2012 03:06
... для того чтобы проверка lirc_code2char работала в цикле нужно разблокировать сокет, ...

Вы ошибаетесь. В такой программе, как вы привели, следует использовать как раз блокирующий сокет. Неблокирующий используется, если вы хотите делать что-то параллельно с ожиданием сигнала. Например, отрисовывать графический интерфейс.

Кстати, нет такого понятия, как "разблокировать сокет". Сокет не блокируеТСЯ, он блокируеТ прграмму на время ожидания. Или не блокирует, если он неблокирующий.

Upd: Рекомендую прочитать небольшое HOWTO на сайте lirc.
Спасибо сказали:
spilver
Сообщения: 6
ОС: Archlinux

Re: lirc и O_NONBLOCK

Сообщение spilver »

/dev/random писал(а):
14.01.2012 06:59
spilver писал(а):
14.01.2012 03:06
... для того чтобы проверка lirc_code2char работала в цикле нужно разблокировать сокет, ...

Вы ошибаетесь. В такой программе, как вы привели, следует использовать как раз блокирующий сокет. Неблокирующий используется, если вы хотите делать что-то параллельно с ожиданием сигнала. Например, отрисовывать графический интерфейс.

Кстати, нет такого понятия, как "разблокировать сокет". Сокет не блокируеТСЯ, он блокируеТ прграмму на время ожидания. Или не блокирует, если он неблокирующий.

Upd: Рекомендую прочитать небольшое HOWTO на сайте lirc.

Спасибо, уже читал несколько раз.
Именно для графического интерфейса я и пытался это сделать. Но т.к. листинг большой - оставил только основное.
Нужно чтобы программа GTK проверяла события lirc и сама одновременно обрабатывала свои события (мышку так и т.д.).
Но как только выполняется lirc_code2char выполнение останавливается, до появления события lirc, как будто какой-то scanf для lirc... и вот тут я пытаюсь отключить блокировку сокетом программы, чтобы цикл отрабатывал.
Может быть у вас есть какие-то идеи, как это реализовать ?
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: lirc и O_NONBLOCK

Сообщение /dev/random »

При использовании неблокирующих сокетов, если данных пока не поступило, функция lirc_nextcode() устанавливает code в NULL и возвращает управление. Вы пытаетесь использовать этот указатель без проверки, что и приводит к сегфолту.
Спасибо сказали:
spilver
Сообщения: 6
ОС: Archlinux

Re: lirc и O_NONBLOCK

Сообщение spilver »

/dev/random писал(а):
14.01.2012 12:29
При использовании неблокирующих сокетов, если данных пока не поступило, функция lirc_nextcode() устанавливает code в NULL и возвращает управление. Вы пытаетесь использовать этот указатель без проверки, что и приводит к сегфолту.


Сделал так:

Код: Выделить всё

while(lirc_nextcode(&code)==0) {
            if (code) ret=lirc_code2char(config,code,&c);
            if (c && code) printf("Execing command \"%s\" :: %d\n",c, i);
            else printf(":: %d\n", i);
            i++;
}

кажется что-то начинает получаться.
Спасибо, большое!
Спасибо сказали:
Ответить