I am trying to install an event tap for my own process to intercept mouse events.
For this I found the function CGEventTapCreateForPSN which expects a process' serial number as its first parameter. How do I get the PSN of my own process? GetCurrentProcess is deprecated, GetProcessInformation has also been removed.
I know about CGEventTapCreate but from what I understand that installs a system-wide hook and that doesn't sound like a good idea or something I'd like to do. I also know about CGEventTapCreateForPid but I can't use that because I am also targeting older MacOSX versions that don't have that function and it also appears to be undocumented so who knows when it will go away.
FYI, I don't own the actual program, my code is only loaded into the process as a dynamic library so I cannot just modify the program's code or anything like that.
Related
I use gopacket in my program. on linux, it runs perfectly.
But on windows the whole program crashes if i did not install WinPcap before.
My plan was to check if WinPcap is installed, and if not to inform the user that he needs this to use 100% of all features.
But i dont come to this point. i cant use gopacket if WinPcap is not available. I mean... not a single line of code of it (=> crash)
Has anyone an idea how i can solve this? im do not need gopacket actually. My plan was, if it is installed, fine, super! If not, dont care... do other things.
But now i have 2 choices... remove gopacket totally or find a way to start my program without the need of wpcap.dll. at least to tell the user that he needs it.
Please help me :(
You're wrong in that you are «not [using] a single line of code of it»: it's not hard to see that
its Windows-specific code calls into winpcap.dll.
What is more fun, is that
its Unix-specific code calls into libpcap.so, and this means you have it working on your local system simply due to the fact you have libpcap package installed (or whatever it's named in your code).
All this means that currently your program is not really portable
anyway (I mean, in the sense you supposedly think it is portable).
You can run something like
$ ldd ./yourbinary
and see it printing a reference to libpcap.so of some version.
There are several ways to solve this.
The easiest is to just try shipping winpcap.dll with your binary. Windows by default looks for DLLs in the current directory of the application trying to load them. Since gopacket uses cgo, it means the winpcap.dll is attempted to be linked it at the application startup, so the application has no chance of changing its working directory before that library is attempted to be found and linked in.
A more complicated approach is to make (or obtain) a static version of the winpcap library (remember that DLL is a library, just a special form of it) and then jump around building gopacket so that it picks that static library.
Install Npcap in "Wpcap API compatibility mode".
Is it's possible to detect inside app from where it was run? From cmd/bash or from GUI? Assume that we are working in graphical mode, not in pure console.
Not really, but sort of. Short answer: better not to try, get the user to tell you via an argument, which you can pre-fill in a shortcut.
Long answer:
In both cases, the program is launched in a similar way: the shell application (whether cmd/bash or Windows explorer/whatever gui launcher linux has) call CreateProcess or ShellExecute on Windows or fork+exec on Linux and the way the user executed it gets lost.
However, the process does have a parent ID which might be useful.... but it isn't reliable either for a few reasons: telling if it is a gui or command line shell isn't easy (best you can do is look at the image name) and the parent might terminate as soon as you launch, so there'd be no parent! (Linux gui apps often fork themselves to detach from the terminal. Of course, if you do this you'd probably know, but if you use a library it might happen without you realizing it.)
Well, the fact that I'm going off on parenthetical asides after every sentence shows how unreliable and complicate that is. If you want to try though, looking at your parent process ID before doing any fork/detaching might be helpful.
BTW looking for a parent console isn't very helpful: a Windows GUI subsystem program won't attach to the parent console even if one exists and a Linux GUI program may attach to the controlling tty of the X window manager.
What I'd actually recommend though is passing an argument to your function to tell it how it got started. When you create the GUI shortcut, make it automatically pass the "started by gui" argument to you. Then you can check args for it and react accordingly.
It still isn't perfect, but it is fairly easy to implement and probably good enough - gui launchers would probably use a shortcut anyway and you can pass arguments through them, so the user doesn't need to know about how it is implemented.
Or you could install two programs, one which is convenient from the command line and one which is optimized for the gui environment.
But I think that's the best you can do.
I wish to know what tools my IDE runs and what command line arguments it uses.
Is there such tool that will provide such information?
I can make an app that will save all processes every second or even faster but I'm still not sure that it will hook everything. There must be some tool already that will do that work much better. Like hooking OS calls for WinExec or CreateProcess(Ex).
Sysinternals Process Monitor can log process events, among other things. It works by monitoring Native API calls, so it'll work regardless of which library function programs use.
I have a testing setup which runs an Application on OS X with a varying set of parameters, if/when the program crashes it's relaunched and continues from where it left off. However when the Application crashes OS X raises the “Application quit unexpectedly” dialog, I'd rather avoid this as it clutters the machine. Is there a way to inhibit this dialog from opening without modifying the source of the Application? If it's of any help in honing solutions the scripting setup is written in Python.
As an example, on Windows I handle the GPF dialog like this:
SEM_NOGPFAULTERRORBOX = 0x0002
ctypes.windll.kernel32.SetErrorMode(SEM_NOGPFAULTERRORBOX);
Ideally there'd be something similar I could use on OS X.
Thanks.
With the developer tools (Xcode, etc.) installed, you get a tool called CrashReporterPrefs. This is basically an interface to some plist file that sets globally how you want crashes handled. Probably not exactly what you're looking for, but if you control the deployment environment it might help.
There must be other options because Google products, like Sketchup, override the default handler and install their own crash reporter. My guess is that they register signal handlers for SIGBUS, SIGSEGV, etc. (see man 2 sigaction) and somehow mask the crash from MacOSX... but I'm speculating here.
I'll let others ask the question on why you can't fix the crash instead. :-)
My problem is not the best scenario for fork(). However, this is the best func I can get.
I am working on a Firefox plugin on Mac OSX. To make it robust, I need to create a new process to run my plugin. The problem is, when I forked a new process, much like this:
if (fork() == 0) exit(other_main());
However, since the state is not cleaned, I cannot properly initialized my new process (call NSApplicationLoad etc.). Any ideas? BTW, I certainly don't want create a new binary and exec it.
In general, you need to exec() after fork() on Mac OS X.
From the fork(2) man page:
There are limits to what you can do in the child process. To be totally safe you should restrict your-self to only executing async-signal safe operations until such time as one of the exec functions is called. All APIs, including global data symbols, in any framework or library should be assumed to be unsafe after a fork() unless explicitly documented to be safe or async-signal safe. If you need to use these frameworks in the child process, you must exec. In this situation it is reasonable to exec yourself.
TN2083 also comments on this subject:
Many Mac OS X frameworks do not work reliably if you call fork but do not call exec. The only exception is the System framework and, even there, the POSIX standard places severe constraints on what you can do between a fork and an exec.
IMPORTANT: In fact, in Mac OS X 10.5 and later, Core Foundation will detect this situation and print the warning message shown in Listing 13.
Listing 13: Core Foundation complaining about fork-without-exec
The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.
fork without exec is basically entirely unsafe on OSX. You will end up with stale mach ports for example.
I'm writing the FreeWRL plugin for Firefox (Linux at the moment, Mac & Windows soon).
http://freewrl.sourceforge.net/
It's based on fork+exec to launch FreeWRL and swallow its window into Firefox.
You'll have to use a pipe to correctly handle the possible failure of fork+exec or the failure of your child process :
How to handle execvp(...) errors after fork()?
Cheers,
C