I have a macOS GUI app, which is also functionally capable of running as a background service i.e., Agent or a Daemon.
The main entry point is main.swift file, where I set some values and invoke some OS calls to understand if my app was launched a service (Agent or Daemon) or a GUI app.
// main.swift
import Foundation
// Set some variables
// Call an ObjC++ func which does the following:
// {
// if(getppid() == 1) {
// // Prepare app to function as a daemon/agent
// // Return to swift
// } else {
// // Prepare app to function as a GUI app
// // Return to swift
// }
// Back in swift layer, start initializing the NSApplication object and
// set the NSApplicationDelegate.
Lets not get into why I'm not using @main attribute, which removes this boilerplate code... Now, when I build this app using Xcode, launch it from the builds folder, I see that getppid() - the Linux OS call to know the parent process ID, returns 1, which means, app is a daemon or an agent (as all services are children of the init process, which has pid of 1).
I'm not creating any new threads nor invoking fork(), both of which can cause the main thread to be returned to OS... which leads to init process adopting the app.
Why does getppid() return 1 when app is launched by double clicking from Finder? Finder is the parent process in this case, right?
Update1:
As pointed out in Arthur's answer and Barmar's comment (in the question) - When I launch Safari and then checked its PPID using the 'top' command in terminal.
Output:
PID COMMAND %CPU TIME #TH #WQ #PORTS MEM PURG CMPRS PGRP PPID
5134 Safari 0.0 00:02.72 7 4 443 55M 9792K 0B 95134 1
94818 Xcode 0.0 00:17.81 10 3 569 469M 864K 0B 94818 1
As shown above, the PPID of Safari and Xcode is 1.