Задача под Линукс следующая: приложение-демон в момент запуска должно проверять наличие своей уже запущенной копии в памяти и выполнять действие в зависимости от результата (выдавать предупреждение и выгружаться, или передавать параметры работающей копии).
Для взаимодействия я выбрал сокеты типа AF_UNIX. Алгоритм следующий: в момент запуска программа выполняет следующий код:
addr.sa_family = AF_UNIX;
strcpy(addr.sa_data,"/tmp/a1");// Имя приемного сокета
unlink("/tmp/a1");// Удаляем, если есть связанный файл
s1 = socket(AF_UNIX, SOCK_DGRAM, 0);// создаем датаграмный сокет для приема ответа
bind(s1, &addr, sizeof(addr));.// привязываем к нему имя
addr.sa_family = AF_UNIX;
strcpy(addr.sa_data,"/tmp/a2");// имя отправляющего сокета
s2 = socket(AF_UNIX, SOCK_DGRAM, 0);// создаем сокет для отправки запроса
sendto(s2, &request, sizeof(request), 0, &addr, sizeof(addr));// напрявляем запрос уже возможно работающей копии программы
FD_ZERO(&rfds);
FD_SET(s1,&rfds);
tv.tv_sec = 2;tv.tv_usec = 0;// Подготавливаем структуры для функции select приемного сокета
retval = select(1, &rdfs, NULL, NULL, &tv);// ждем 2 секунды ответа на ранее отправленный запрос
if(retval)recvfrom(s1, &reply, sizeof(reply), 0, NULL, NULL);// Принимаем ответ, если он пришел
else ...
.................
получив положительный ответ, вызывает "exit" и завершается. Иначе, создает fork'ом новый процесс, содержащий функцию ответа и остается в памяти.
Функция ответа построена аналогично, только без использования select, блокируясь на recvfrom до получения запроса и сразу же выдает ответ через sendto. Запускается в новом процессе после отрицательного ответа вышеприведенного кода.
Все работает до получения ответа (select/recvfrom). Функция ответа получает запрос от вышеприведенного кода и отправляет ответ. В чем проблема, непонятно. Т.е. sendto отвечающей функции, ранее запущенной копии, выполняется, возвращает количество отправленных байт (их всего 8), но select из фрагмента выше вновь запущенной копии всегда завершается по таймауту (2 секунды) без указания на пришедшие данные. Может быть select вообще не работает с сокетами домена UNIX? И еще, выполнение close() сразу после sendto может уничтожить отправляемые данные, или они все-таки дойдут до адресата? (функция fflush на сокетах данного типа не поддерживается, вызывая segmentation fault).