- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, svn, 01:59 , 17-Апр-09 (1)
> а под линуксом open открывает нормально, а хотелось бы >поведения, аналогичного виндовому. Как это можно сделать? Сломать линукс? )) Блокировки в linux advisory. И это всем нравится. Почитай http://tldp.org/HOWTO/Serial-HOWTO.html там всё написано. программа использущая порт создаёт файл /var/lock/LCK..name где name - имя порта ttyS0 или что там у тебя. В файле PID твоей программы. Так все другие программы знают кто использует этот порт.
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, marty37, 17:31 , 17-Апр-09 (3)
>Почитай http://tldp.org/HOWTO/Serial-HOWTO.html там всё написано. >программа использущая порт создаёт файл /var/lock/LCK..name где name - имя порта ttyS0 >или что там у тебя. В файле PID твоей программы. Так >все другие программы знают кто использует этот порт. Не совсем понял, /var/lock/LCK..name - именно с двумя точками? Нет ли какого-нибудь системного/библиотечного вызова, который атомарно проверяет наличие файла, если его нет, создает, а если есть, то считывает из него pid, проверяет, живой ли процесс с данным pid'ом, если не живой, то создает новый с pid'ом текущего процесса?
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, svn, 20:35 , 17-Апр-09 (7)
>Не совсем понял, /var/lock/LCK..name - именно с двумя точками? Да. Ссылки не читаешь? >Нет ли какого-нибудь системного/библиотечного вызова, который атомарно проверяет >наличие файла, если его нет, создает Смотри опции/флаги открытия файла. >а если есть, то считывает из него pid, проверяет, >живой ли процесс с данным pid'ом, если не живой, то создает >новый с pid'ом текущего процесса? Это уже сам. Но обычно программы блокировки за собой удаляют. А на случай аварийного выключения стартовые скрипты очищают /var/lock/
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, marty37, 23:19 , 17-Апр-09 (8)
>>Не совсем понял, /var/lock/LCK..name - именно с двумя точками? > >Да. Ссылки не читаешь? Читал. Подумал, может там опечатка а вы просто скопировали, не обратив внимания ;) >Это уже сам. Но обычно программы блокировки за собой удаляют. А на >случай аварийного выключения стартовые скрипты очищают /var/lock/ Обычно да, длжны удалять. Но вдруг программа падает (но система не перезапускается), тогда лок файл останется. Надо проверять. А мои программы падают и будут падать на этапе разработки, так что надо это как-то продумать.
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, vic, 01:11 , 18-Апр-09 (9)
>[оверквотинг удален] >Читал. Подумал, может там опечатка а вы просто скопировали, не обратив внимания >;) > >>Это уже сам. Но обычно программы блокировки за собой удаляют. А на >>случай аварийного выключения стартовые скрипты очищают /var/lock/ > >Обычно да, длжны удалять. Но вдруг программа падает (но система не перезапускается), >тогда лок файл останется. Надо проверять. А мои программы падают и >будут падать на этапе разработки, так что надо это как-то продумать. >в lock файле обычно pid процесса, проверит наличие процесса не составляет труда, нет процесса - смело удаляем файл и создаем свой.
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, marty37, 17:34 , 17-Апр-09 (5)
И еще, насколько этот механизм блокировки поддерживается в разном софте? Следует ли кто-нибудь данным правилам?
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, marty37, 20:07 , 20-Апр-09 (11)
Сделал как умные люди советовали, через блокировку в /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; }
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, marty37, 20:26 , 20-Апр-09 (12)
Ой затупил, umaks же инвертируется перед объединением. Вопрос снят ;)
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, vic, 10:20 , 21-Апр-09 (13)
Ужасы С++, да еще с ошибками :(( Читайте исходники опенпроектов, каждый день.
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, marty37, 21:43 , 21-Апр-09 (14)
>Ужасы С++, да еще с ошибками :(( В чем ужасы, и в чем ошибки, в двух словах, если не сложно? >Читайте исходники опенпроектов, каждый день. Пошел читать ;) Вот где ужасы-то обычно гнездятся ;)
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, vic, 03:35 , 22-Апр-09 (15)
>>Ужасы С++, да еще с ошибками :(( >В чем ужасы, и в чем ошибки, в двух словах, если не сложно? 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 маска у вас не восстанавливается. ЗЫ лучше всего взять и посмотреть исходники программ в которых уже реализована нужная функция, благо их полно для изучения.
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, marty37, 11:01 , 22-Апр-09 (16)
Спасибо за коментарий. Кое в чем не согласен, пропробую оправдаться. Можете проигнорировать, если нет желания дискутировать ;)>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, на вскидку не могу ничего придумать, куда бы посмотреть.
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, vic, 15:27 , 22-Апр-09 (17)
>Потоки 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 :)
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, marty37, 15:58 , 22-Апр-09 (18)
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, marty37, 15:59 , 22-Апр-09 (19)
>Это фича C99, и MSVC не умеет работать с такими массивами, он >не все фишки C99 поддерживает, не знаю, как GCC/ Хотя я, конечно, тут затупил - этот участок полностью попадает пока под условную компиляцию только под *nux, и MSVC тут по идее не причем, но привычка-с ;)
- Как определить, что COM порт (/dev/tty) уже кем-то открыт?, Аноним, 11:22 , 17-Апр-09 (2)
|