Я могу установить RTS с помощью ioctl в небольшом приложении Terminal, но не в коде моего плагина Mac, хотя оба запускают один и тот же код. В плагине я могу только «получить» флаги / пины последовательных портов, но не «установить» их. В приложении «Терминал» я могу как «получить», так и «установить» их. Я получаю сообщение об ошибке ENODEV. Номер ошибки — 19, а сообщение «Операция не поддерживается устройством».
Если это проблема безопасности (в контексте браузера), есть ли способ получить разрешение на изменение флага с помощью ioctl? У меня есть последовательное устройство, подключенное к USB-порту. Я использую драйвер FTDI vcp (виртуальный com-порт). Все гладко на стороне Windows. Кстати, я получаю одинаковый результат, используя Safari и Firefox. Ниже мой код:
int disableRTS ()
{
char fd, ret, flags;
// open device
if ((fd = open("/dev/cu.mydevice", O_RDWR | O_NDELAY)) < 0)
{
fprintf(stderr, "failed to open device");
return -1;
}
// Get the current state of the bits
ioctl(fd, TIOCMGET, &flags);
fprintf(stderr, "Flags are %x.\n", flags);
flags &= ~TIOCM_RTS; // Disable the RTS bit
ret = ioctl(fd, TIOCMSET, &flags);
if (ret == -1)
fprintf(stderr, "TIOCMSET failed\n");
else
fprintf(stderr, "TIOCMSET succeeded. flags: %x.\n", flags);
return 0;
}
=========
Если я обновляю страницу браузера, заставляя код выполняться снова, ioctl () возвращает 0, что указывает на успех. К сожалению, мне нужно, чтобы он работал с первого раза. Даже если я напишу цикл и на мгновение сделаю паузу, используя метод usleep (), и предприму последующие попытки, это не удастся. Но потом, когда я обновляюсь, это удается. Я также продублировал эту проблему во втором, исключительно NPAPI-проекте «BasicPlugin.xcodeproj», поставляемом Mozilla. Мой первый проект плагина — это проект Firebreath. Они оба терпят неудачу сначала, затем преуспевают при перезагрузке страницы. У меня также есть 2 отдельных приложения Mac, которые работают должным образом. Одним из них является SerialTools, и он использует тот же метод установки RTS (и DTR выключен), что и приложение my Terminal и плагины.
========
Мне удалось получить поддержку Apple на уровне кода, поэтому решение может приходить Инженер сказал, что это «странно», что код работает в плагине иначе, чем вне его, и говорит с инженерами плагина Safari.
Вы можете создать плагин AppleScript, который будет запускаться автоматически в определенное время, во время входа в систему или постоянно в фоновом режиме.
AppleScript может запускать код терминала. Таким образом, вы можете легко запустить код get / set, который вы в данный момент запускаете в Терминале.
Код для плагина AppleScript будет примерно таким:
tell application "Finder"display dialog explanation buttons {"GET", "SET"} default button "GET"if result = {button returned:"GET"} then
tell application "Terminal"set status to (do shell script "terminal code for getting the RTS here")
end tell
else if result = {button returned:"SET"} then
tell application "Terminal"set status to (do shell script "terminal code for setting the RTS here")
end tell
end if
end tell
Ответ заключается в том, что всякий раз, когда TIOCMSET или TIOCMGET используются в вызове ioctl (), 3-й параметр должен быть int. Я использовал чар. Duh. Не могу поверить, что я пропустил это. TIOCMSET и TIOCMGET определяются следующим образом:
#define TIOCMSET _IOW('t', 109, int) /* set all modem bits */
…
#define TIOCMGET _IOR('t', 106, int) /* get all modem bits */
и поэтому нетрудно представить, что использование char в качестве типа для моих «флагов» var может привести к непредсказуемому поведению.