And syslog() shows up in the console app, always under any circumstances...
It's a bit weird, do you see? Anyhow, the situation which has not changed since I posted is that, if I had my druthers, I would like NSLog() to print to the console app. So the question now is:
Should I even dream of thinking that I can find the "problem" that prevents NSLog() from going to the console? Or should I just take the workable but annoying situation that has been discovered and call it a day?
You should start by taking the workable but annoying solution, i.e. "redirecting" stderr and/or stdout to your own file.
You could write to a file located in a directory where Console.app (look at its log list) normally looks for log files, and then you can open the log-file in Console.app and see it there. If you do this, make sure your redirection with freopen() opens the file for appending, so new output is added at the end.
One reason I suggested using fileno() was specifically so you can fstat() the resulting file descriptor. With the resulting stat structure you can find out what type the node is. For example, is it a file, a pipe, or a Unix domain socket? Who owns it? What are the permissions? And so on.
In short, you can show info similar to what 'ls -l' outputs.
The reason syslog() always shows up in the system log is the way that syslog is implemented. I'll warn you now: this explanation will pretty quickly go down the rabbit hole, or into a maze of twisty passages, depending on your choice of metaphor.
First, start by reading the man page for the syslog(3) C function.
https://developer.apple.com/library...n3/syslog.3.html#//apple_ref/doc/man/3/syslog
Notice that it mentions a "logger" and has See Also entries for a logger(1) command and a syslogd(8) daemon:
https://developer.apple.com/library...n1/logger.1.html#//apple_ref/doc/man/1/logger
https://developer.apple.com/library.../syslogd.8.html#//apple_ref/doc/man/8/syslogd
Also read the man page for the syslog(1) cmd:
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/syslog.1.html
The essential underlying fact here is that the system log is being written and maintained by a daemon (syslogd), which accepts input on Unix domain sockets, and formats received data for writing to a structured log.
The system log is not just a file.
After reading the above man pages, and then doing some exploring, I see there are multiple sockets in this dir:
/var/run/
The syslog UDP datagram socket's Unix domain path is noted in the syslogd man page, but there are others. One of them may be a Unix domain stream socket. You'd have to dig into it further, maybe by looking at the source for logger(1), or maybe by trying some experiments.
As to the reason why your privileged helper process loses its NSLog output stream, that's due to how a privileged process is started.
First, learn about how open file descriptors are inherited by a child process. Refer to 'man execve'.
Next, realize that when Xcode runs your program, it sets up the fd's so the output from your app is collected and processed for a window. Since that process runs without privilege escalation, it can use the normal route of fork() and execve(), and Xcode can control fd inheritance.
You can poke around in the process info of your main app and discover things like parent process id (getppid), process group id (getpgid), the controlling terminal (if any), and so on. The parent process id is likely Xcode at some point in the process ancestry, or a temporary process started by Xcode.
Unfortunately, this is not how a privileged process is started.
A privileged process must be started from a parent process that already has 'root' as its effective uid (euid) or real uid (ruid). You can read these for a process with geteuid() and getuid() (see their man pages). The actual process that starts the privileged helper has changed as the OS has evolved. I'm pretty sure it was the init process at one point, and then the login process. I've forgotten much of the details since the last time I looked at this, and that was when AEWP was the only way. The OS and APIs now are quite different.
The important thing here is that the privileged helper process is not a descendant of the process that requests the privileged execution. Instead, it goes through a privileged proxy, and that proxy is already running as root. Because the proxy doesn't inherit any fd's or streams from your main process, any connection between NSLog and syslog or an Xcode window is irrecoverably lost.
Inheritance of fd's only works for descendent processes, not ones started by a proxy. There are ways to pass fd's to processes, but it takes cooperation on the receiving end.
The net result of this is simple: if you want your privileged helper process to write to the system log using NSLog, you'll have to set that up yourself. To do that, however, you'll have to figure out what Unix domain socket to use, which itself is going to take some exploration.
The above is probably only about half the story, because I would fully expect more twisty little passages; this is Unix, and nothing is ever as simple as its visible API may suggest. In some ways this is intentional (separation of interface from implementation), and in some ways it's a result of the evolution of implementations.
This is why if you can get close to what you want using freopen(), that's almost certainly going to be a simpler approach. You might stumble on a simple way to write a stream to syslogd that proves me wrong, but I think that's more luck than anything else.
Personally, I'd do the simplest thing that came close to what I wanted. Then if you do happen to get lucky, you've still made a useful tool.