The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Как определить, что COM порт (/dev/tty) уже кем-то открыт?"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [ Отслеживать ]

"Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от marty37 email(ok) on 16-Апр-09, 19:51 
Здравствуете!

Можно ли как-то определить, что устройство /dev/tty кем-то открыто? Под виндой CreateFile возвращает ACCESS_DENIED, а под линуксом open открывает нормально, а хотелось бы поведения, аналогичного виндовому. Как это можно сделать?

Высказать мнение | Ответить | Правка | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от svn (??) on 17-Апр-09, 01:59 
> а под линуксом open открывает нормально, а хотелось бы
>поведения, аналогичного виндовому. Как это можно сделать?

Сломать линукс? ))
Блокировки в linux advisory. И это всем нравится.

Почитай http://tldp.org/HOWTO/Serial-HOWTO.html там всё написано.
программа использущая порт создаёт файл /var/lock/LCK..name где name - имя порта ttyS0 или что там у тебя. В файле PID твоей программы. Так все другие программы знают кто использует этот порт.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от marty37 email(ok) on 17-Апр-09, 17:31 
>Почитай http://tldp.org/HOWTO/Serial-HOWTO.html там всё написано.
>программа использущая порт создаёт файл /var/lock/LCK..name где name - имя порта ttyS0
>или что там у тебя. В файле PID твоей программы. Так
>все другие программы знают кто использует этот порт.

Не совсем понял, /var/lock/LCK..name - именно с двумя точками?
Нет ли какого-нибудь системного/библиотечного вызова, который атомарно проверяет наличие файла, если его нет, создает, а если есть, то считывает из него pid, проверяет, живой ли процесс с данным pid'ом, если не живой, то создает новый с pid'ом текущего процесса?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

7. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от svn (??) on 17-Апр-09, 20:35 
>Не совсем понял, /var/lock/LCK..name - именно с двумя точками?

Да. Ссылки не читаешь?

>Нет ли какого-нибудь системного/библиотечного вызова, который атомарно проверяет
>наличие файла, если его нет, создает

Смотри опции/флаги открытия файла.

>а если есть, то считывает из него pid, проверяет,
>живой ли процесс с данным pid'ом, если не живой, то создает
>новый с pid'ом текущего процесса?

Это уже сам. Но обычно программы блокировки за собой удаляют. А на случай аварийного выключения стартовые скрипты очищают /var/lock/

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

8. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от marty37 email(ok) on 17-Апр-09, 23:19 
>>Не совсем понял, /var/lock/LCK..name - именно с двумя точками?
>
>Да. Ссылки не читаешь?

Читал. Подумал, может там опечатка а вы просто скопировали, не обратив внимания ;)

>Это уже сам. Но обычно программы блокировки за собой удаляют. А на
>случай аварийного выключения стартовые скрипты очищают /var/lock/

Обычно да, длжны удалять. Но вдруг программа падает (но система не перезапускается), тогда лок файл останется. Надо проверять. А мои программы падают и будут падать на этапе разработки, так что надо это как-то продумать.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

9. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от vic (??) on 18-Апр-09, 01:11 
>[оверквотинг удален]
>Читал. Подумал, может там опечатка а вы просто скопировали, не обратив внимания
>;)
>
>>Это уже сам. Но обычно программы блокировки за собой удаляют. А на
>>случай аварийного выключения стартовые скрипты очищают /var/lock/
>
>Обычно да, длжны удалять. Но вдруг программа падает (но система не перезапускается),
>тогда лок файл останется. Надо проверять. А мои программы падают и
>будут падать на этапе разработки, так что надо это как-то продумать.
>

в lock файле обычно pid процесса, проверит наличие процесса не составляет труда, нет процесса - смело удаляем файл и создаем свой.


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от marty37 email(ok) on 17-Апр-09, 17:34 
И еще, насколько этот механизм блокировки поддерживается в разном софте? Следует ли кто-нибудь данным правилам?
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от svn (??) on 17-Апр-09, 20:27 
>И еще, насколько этот механизм блокировки поддерживается в разном софте? Следует ли
>кто-нибудь данным правилам?

Следуют.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

11. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от marty37 email(ok) on 20-Апр-09, 20:07 
Сделал как умные люди советовали, через блокировку в /var/lock.
Возник такой вопрос - лок файл создается с парвами --------- (т.е. ничего нельзя с ним делать). Голову сломал, не пойму, где косяк. Код такой:

bool tryMakeNewExclusiveLock( const char* lockFileName)
   {
    PID_T pid = getpid();
    char strPid[64];
    char strTick[64];
    sprintf(strPid, "%u", pid);
    sprintf(strTick, "%u", (unsigned)cliGetTickCount());

    char* uniqName = (char*)_alloca( strlen(lockFileName) + strlen(strPid) + strlen(strTick) + 16 );
    strcpy( uniqName, lockFileName );
    strcat( uniqName, "." );
    strcat( uniqName, strPid );
    strcat( uniqName, "." );
    strcat( uniqName, strTick );

    mode_t prevMask = umask(0777);
    //std::cout<<"prevMask: "<<prevMask<<"\n";
    //std::cout<<"newMask : "<<umask(0777)<<"\n";

    mode_t creatMode = S_IRWXU|S_IRWXG|S_IRWXO;
    int newLockFile = ::open( uniqName, O_CREAT|O_RDWR, creatMode );
    if (newLockFile==-1)
       {
        return false; // failed to lock
       }
    //std::cout<<"newLockFile: "<<newLockFile<<"\n";
    size_t bytesToWrite = strlen(strPid);
    if (::write(newLockFile, strPid, bytesToWrite )==-1)
       {
        //std::cout<<"Write error: "<<errno<<" "<<strerror(errno)<<"\n";
        //std::cout<<"newLockFile: "<<newLockFile<<"\n";
        ::close(newLockFile);
        ::unlink(uniqName);
        ::umask(prevMask);
        return false;
       }
    ::close(newLockFile);

    bool res = false;
    if (::link(uniqName, lockFileName)==-1)
       {
        struct stat s;
        ::stat(uniqName, &s);
        if (s.st_nlink>=2) res = true;      
       }
    else
       {
        res = true;
       }
    
    ::unlink(uniqName);
    ::umask(prevMask);
    return res;
   }

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

12. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от marty37 email(ok) on 20-Апр-09, 20:26 
Ой затупил, umaks же инвертируется перед объединением. Вопрос снят ;)
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

13. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от vic (??) on 21-Апр-09, 10:20 
Ужасы С++, да еще с ошибками :((
Читайте исходники опенпроектов, каждый день.
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

14. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от marty37 email(ok) on 21-Апр-09, 21:43 
>Ужасы С++, да еще с ошибками :((

В чем ужасы, и в чем ошибки, в двух словах, если не сложно?

>Читайте исходники опенпроектов, каждый день.

Пошел читать ;)
Вот где ужасы-то обычно гнездятся ;)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

15. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от vic (??) on 22-Апр-09, 03:35 
>>Ужасы С++, да еще с ошибками :((
>В чем ужасы, и в чем ошибки, в двух словах, если не сложно?

1. ужас в том что вроде как С++, а реально С кошмарный. Если уж С++, то и использовать для большей части действий средства C++ (стримы, строки, работа с файлами). Можно же реализовать большую часть кода (или весь) не опускаясь до работы с системными вызовами.
2. первые 10 строк (формирование названия файла) заменяются одним/двумя snprintf(), или std::string если уж С++.
3. вы используете не юниксовый способ названия переменных и функций, поэтому читать непривычно. Обратите свое внимание на code styles принятые в *nix, gnu.
4. ошибка при проверки write(), в проверке надо учитывать и положительный результат тоже:
    if (write(newLockFile, strPid, bytesToWrite) != bytesToWrite) {...}
write() может вернуть меньше чем заявленное len.
5. злоупотребление оператором ::
6. _alloca() - зло.
7. что за муть с линками?
8. и ваще название функции вводит в заблужение, какой такой Exclusive Lock)) нету его в линухе.
9. лучше open() либо с флагами O_CREAT|O_WRONLY|O_TRUNC, либо creat(). Вы же ни читаете в данном случае.
10. <- раз подумать прежде чем игнорить маску (тут это вообще не нужно). в данном куске кода при open failed маска у вас не восстанавливается.

ЗЫ лучше всего взять и посмотреть исходники программ в которых уже реализована нужная функция, благо их полно для изучения.


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

16. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от marty37 email(ok) on 22-Апр-09, 11:01 
Спасибо за коментарий. Кое в чем не согласен, пропробую оправдаться. Можете проигнорировать, если нет желания дискутировать ;)

>1. ужас в том что вроде как С++, а реально С кошмарный.
>Если уж С++, то и использовать для большей части действий средства
>C++ (стримы, строки, работа с файлами). Можно же реализовать большую часть
>кода (или весь) не опускаясь до работы с системными вызовами.

Потоки C++ тормоза, и я страюсь обходится без них. Системные вызовы не считаю злом.

>3. вы используете не юниксовый способ названия переменных и функций, поэтому читать
>непривычно. Обратите свое внимание на code styles принятые в *nix, gnu.

Я пишу под *nix и под Win32, coding style мой собственный, принятый в проекте.

>4. ошибка при проверки write(), в проверке надо учитывать и положительный результат
>тоже:

+

>5. злоупотребление оператором ::

+

>6. _alloca() - зло.

Наоборот, считаю его добром, которое быстро выделяет память и позволяет не заботиться о ее освобождении. Если есть ссылки на материалы, в которых аргументироно объясняется, что это зло, с интересом почитаю.

>7. что за муть с линками?

man 2 open говорит, что лучше делать так для лок файлов.

>8. и ваще название функции вводит в заблужение, какой такой Exclusive Lock))
>нету его в линухе.

+

>9. лучше open() либо с флагами O_CREAT|O_WRONLY|O_TRUNC, либо creat(). Вы же ни
>читаете в данном случае.

+. Сначала собирался читать, потом передумал.

>10. <- раз подумать прежде чем игнорить маску (тут это вообще не
>нужно). в данном куске кода при open failed маска у вас
>не восстанавливается.

+. Спасибо, пропустил.
>
>ЗЫ лучше всего взять и посмотреть исходники программ в которых уже реализована
>нужная функция, благо их полно для изучения.

Я не большой знаток софта под *nix, на вскидку не могу ничего придумать, куда бы посмотреть.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

17. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от vic (??) on 22-Апр-09, 15:27 
>Потоки C++ тормоза, и я страюсь обходится без них. Системные вызовы не
>считаю злом.

в данной функции использование стримов для формирования названия файла и записи в него никак не влияют на скорость.
ну а для формирования имени файла snprintf(name, max_name_len, "%s.%d.%d.ded_moroz", ...);
с проверкой, читабельнее чем куча strcat().

>>6. _alloca() - зло.
>Наоборот, считаю его добром, которое быстро выделяет память и позволяет не заботиться
>о ее освобождении. Если есть ссылки на материалы, в которых аргументироно
>объясняется, что это зло, с интересом почитаю.

а c точки зрения внесение последующих изменений другим программистом - будет порождать различные ошибки в внесенном коде. Также возможна атака на стек (он не настолько резиновый), т.к. выделяемый размер зависит от strlen(lockFileName). Еще эта функция неидиоматичная, народ будет спотыкаться о нее при чтений кода + необходимость держать ее в голове до завершающей '}'. А так же не все умеют с ней правильно работать. Кстати, можно и char str[strlen(a)]; использовать, не так неожиданно будет. В общем тут минус как у goto, сам по себе оператор не плохой, а вот использование хромает, да и риски ошибок большие :)

http://blogs.sun.com/ambiguous/entry/a_safe_way_of_using - тут есть кое-что.
http://www.gnu.org/software/hello/manual/libc/Advantages-of-... - плюсы
http://www.gnu.org/software/hello/manual/libc/Disadvantages-... - минусы

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

>>7. что за муть с линками?
>man 2 open говорит, что лучше делать так для лок файлов.

это он про тот случай если O_EXCL не работает (NFS ниже какой-то версии) при межхостовых блокировках, у вас случай проще, com-порт локален и файл блокировки локален. Просто использовать O_EXCL.

>>9. лучше open() либо с флагами O_CREAT|O_WRONLY|O_TRUNC, либо creat(). Вы же ни
>>читаете в данном случае.
>+. Сначала собирался читать, потом передумал.

та я хотел чтобы пунктов было 10, вот и стал придираться :)

>Я не большой знаток софта под *nix, на вскидку не могу ничего
>придумать, куда бы посмотреть.

я тоже, но тот же minicom, или тот же ppp :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

18. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от marty37 email(ok) on 22-Апр-09, 15:58 
Еще раз спасибо за коментарии ;)

>не все умеют с ней правильно работать. Кстати, можно и char
>str[strlen(a)]; использовать, не так неожиданно будет.

Это фича C99, и MSVC не умеет работать с такими массивами, он не все фишки C99 поддерживает, не знаю, как GCC/

>http://blogs.sun.com/ambiguous/entry/a_safe_way_of_using - тут есть кое-что.
>http://www.gnu.org/software/hello/manual/libc/Advantages-of-... - плюсы
>http://www.gnu.org/software/hello/manual/libc/Disadvantages-... - минусы

Почитаем

>это он про тот случай если O_EXCL не работает (NFS ниже какой-то
>версии) при межхостовых блокировках, у вас случай проще, com-порт локален и
>файл блокировки локален. Просто использовать O_EXCL.

А я на всякий случай делал, мало-ли что еще в будущем понадобится ;)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

19. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от marty37 email(ok) on 22-Апр-09, 15:59 
>Это фича C99, и MSVC не умеет работать с такими массивами, он
>не все фишки C99 поддерживает, не знаю, как GCC/

Хотя я, конечно, тут затупил - этот участок полностью попадает пока под условную компиляцию только под *nux, и MSVC тут по идее не причем, но привычка-с ;)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от Аноним (??) on 17-Апр-09, 11:22 
lsof, fuser.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от marty37 email(ok) on 17-Апр-09, 17:32 
>lsof, fuser.

Интересно, спасибо, но сорцы не осилил. И переносимость не очень ясна.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

10. "Как определить, что COM порт (/dev/tty) уже кем-то открыт?"  
Сообщение от Аноним (??) on 18-Апр-09, 12:59 
man 2 stat, переносимость POSIX.
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру