-1

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.

NightFuryLxD
  • 847
  • 5
  • 15
  • What does this have to do with the Linux Kernel? MacOS is not Linux, and user applications don't run in the kernel. – Barmar Apr 10 '23 at 15:29
  • 1
    On MacOS, PID 1 is `launchd`, and all GUI processes are launched by this. – Barmar Apr 10 '23 at 15:32
  • @Barmar, I tagged linux because the question is about the linux OS call - getppid... and macOS is built on top of Linux. Apologies if it wasn't appropriate. – NightFuryLxD Apr 11 '23 at 06:19
  • It's not Linux-specific. It's in all flavors of Unix, and part of the POSIX standard. It's probably been around since the beginning of Unix, decades before Linux. – Barmar Apr 11 '23 at 15:14

1 Answers1

1

There is no valid process-tree in macOS world, unfortunately.

All unix stuff like getppid will return something valid only for the processes launched in a unix way, let's say running some console binaries from Terminal could show you behaviour you expect here.

GUI processes are launched on macOS in a complex way including 1+ IPC from the real source process who wants something to launch to the launchd.

Regarding your initial goal, I would say the most straightforward will be just to add some commandline argument or env variable into its launch plist, and check it then: if it is present - the app is launched as agent/daemon, if it is not - use GUI logic.

I've answered a question alike (a bit more complex) before here, if you want to read more on topic

Arthur Bulakaiev
  • 1,207
  • 8
  • 17
  • Thanks. I've also checked the parent PID of other GUI apps like Safari... and it was indeed 1 (will include more details in another answer). – NightFuryLxD Apr 11 '23 at 06:21