On Nov 16, 2015, at 2:56 PM, Eric Schlegel < email@hidden> wrote:
On Nov 16, 2015, at 4:46 AM, Bill Cheeseman < email@hidden> wrote: ....
In my free developer utility Event Taps Testbench < http://pfiddlesoft.com/eventtapstestbench>, I call the old PSN function to create an "empty" event tap, then I let the user set the parameter values in the application's GUI and click an Install button to configure and install it. It works perfectly. I convert the temporary Pid value of 0 to the equivalent PSN value using GetProcessForPid(), and the old PSN function returns a real CFMachPortRef.
So you call GetProcessForPID(0, &psn) and you get back noErr and a valid PSN? That surprises me. I’m not sure that’s really a supported configuration, but we’d have to ask some other Apple folks to be sure. Or maybe I’m misunderstanding what you’re actually doing. If you are passing 0 for the pid, why?
Event Taps Testbench allows you to configure and test event taps of any kind. I first create what I call an "empty" event tap with default settings and set up its run loop source, then I ask the user to provide real settings (active vs. passive, etc.) via my GUI and plug them into the event tap. I provide an initial Pid of 0 because the user hasn't yet selected the target application and I therefore don't have the real Pid. GetProcessForPID(pid, &psn) does provide a valid PSN for a Pid of 0, at least valid enough to let me set up the run loop source. (I vaguely recall that 0 is the Pid for root; I know it never represents a user application.) But the new Pid function does not work with a 0 Pid.
I suppose I should reverse my logic, getting the user's information first and then setting up a real event tap, bypassing this whole problem by eliminating the "empty" event tap step. I wrote this application long ago and no longer remember why I found it useful to create an "empty" event tap first. It worked, but since that approach now appears to have worked only by accident, I will alter my approach. In the new version of Event Taps Testbench that I am developing now, I call the new Pid function instead when running under El Capitan. It does not work. Either the Pid value of 0 or the two null parameters (which are not marked __nullable) result in a CFMachPortRef return value of 0. That in turn prevents me from creating the run loop source that I need in order to install the tap.
The implementation of the Pid function does not appear to support a pid value of 0. That’s probably the primary reason for your NULL return value.
The implementation also definitely returns NULL if you pass a NULL callback. So the callback parameter to the PSN function should not be marked __nullable (that’s a bug), and the lack of nullability on the callback parameter to the Pid function is correct.
I believe you're mistaken about the old PSN function's callback parameter. I pass null for callback and get a perfectly usable CFMachPortRef in the function result, which allows me to create the run loop source. So the __nullable annotation on the callback parameter in the PSN function appears to be correct, at least in terms of how the PSN function actually works. I can well imagine that the omission of the __nullable annotation on the callback parameter in the PID function is also correct, if your examination of the source indicates that null doesn't work there.
This raises the interesting philosophical question of whether _nullability annotations should be based on how a function actually works or how Apple wants it to be used. It also raises the question of whether "twin" functions like this should always work exactly alike except for the advertised difference.
Thanks for your comments. I'll work up a bug report.
|