问题
I am able to set the RTS with ioctl in a small Terminal app, but not in my Mac plugin code, although both run the same code. In the plugin I can only "get" the serial ports flags/pins, but not "set" them. In the Terminal app I can both "get and "set" them. I get an errno of ENODEV. The error number is 19 and the message is "Operation not supported by device."
If this is a security issue (being in the context of a browser) is there a way to get permission to modify the flag with ioctl? I have a serial device attached to a usb port. Am using the FTDI vcp (virtual com port) driver. Everything smooth on the Windows side. Btw, I get the same result using both Safari and Firefox. Below is my code:
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;
}
=========
Update
If I refresh the browser page, forcing the code to be executed again, ioctl() returns 0, indicating success. Unfortunately, I need it to work the first time. Even if I write a loop and pause momentarily, using the usleep() method, and make subsequent tries, it fails. But then, when I refresh it succeeds. I've also duplicated the issue in a second, exclusively NPAPI project "BasicPlugin.xcodeproj", supplied by Mozilla. My first plugin project is a Firebreath project. They both fail at first, then succeed on page reload. I also have 2 separate Mac apps that work properly. One is SerialTools, and it uses the exact same method of setting the RTS on (and DTR off) as the my Terminal app and the plugins.
========
Update 2
I've been able to get code-level Apple support on this, so a solution may be coming. The engineer said it was "bizarre" that the code runs differently in a plugin than outside of one, and is speaking with Safari plugin engineers.
回答1:
You can make a AppleScript plugin, that will run automatically at particular times or during your login, or continuously in the background.
AppleScript can run terminal code. So you can easily have it automatically run the get/set code that you currently run in Terminal.
The code for the AppleScript plugin will be something like this ::
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
回答2:
The answer is that whenever TIOCMSET or TIOCMGET are used in a call to ioctl() the 3rd parameter must be an int. I was using a char. Duh. Can't believe I missed this. TIOCMSET and TIOCMGET are defined as follows:
#define TIOCMSET _IOW('t', 109, int) /* set all modem bits */
…
#define TIOCMGET _IOR('t', 106, int) /* get all modem bits */
and so it is not difficult to imagine that using a char as the type for my "flags" var might cause unpredictable behavior.
来源:https://stackoverflow.com/questions/14693724/how-can-i-set-the-rts-with-ioctl-in-a-mac-plugin