0

From an app written in C++, how can I tell that my launch daemon is currently running? And preferably how to get its PID?

For instance, if I run the following in the terminal:

launchctl list com.example.MyService                             

I get a JSON output, where it gives me the PID of the daemon process.

Having studied the source code for launchctl, I came up with the following:

const char *label = "com.example.MyService";

launch_data_t msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
launch_data_dict_insert(msg, launch_data_new_string(label), LAUNCH_KEY_GETJOB);

launch_data_t resp = launch_msg(msg);
launch_data_free(msg);

if(resp != NULL)
{
    launch_data_type_t tt = launch_data_get_type(resp);
    if(tt == LAUNCH_DATA_DICTIONARY)
    {
        launch_data_t pid_data =
            launch_data_dict_lookup(resp, LAUNCH_JOBKEY_PID);
        if (pid_data)
        {
           if (launch_data_get_type(pid_data) == LAUNCH_DATA_INTEGER)
           {
               pid_t pid = launch_data_get_integer(pid_data);

               //...
           }
        }
    }
    else if(tt == LAUNCH_DATA_ERRNO)
    {
        int nErr = launch_data_get_errno(resp);
        
        //ESRCH = 3 = No such process
    }

    launch_data_free(resp);
}
else
{
    //No such
}

But when I run the code above for my launch daemon "label", I get my launch_data_type_t returned as LAUNCH_DATA_ERRNO and launch_data_get_errno returns ESRCH (like I showed above.)

What am I doing wrong?

c00000fd
  • 20,994
  • 29
  • 177
  • 400
  • One simple way is to check if a special file exists. If not then run as usual, otherwise the program is already running. You can put the PID of the process in the file if you need it. – Some programmer dude Apr 01 '23 at 18:32
  • @Someprogrammerdude that's a general Linux approach, right? I'm curious, what do you do if the process crashes and such .pid file still remains? – c00000fd Apr 02 '23 at 09:05
  • It's a general **POSIX** approach. It has been done for longer than Linux existed. – Some programmer dude Apr 02 '23 at 09:26
  • And if the program crashes, you add an issue in your issue-tracking system and fix it. :) – Some programmer dude Apr 02 '23 at 09:26
  • @Someprogrammerdude what I meant is this. I'm assuming you'd do it as such: When the process starts, you create `/var/run/myapp.pid` file and before it exits, you `close` and `unlink` it, technically deleting it. Then to check if that process is running (from another process) you open that same file, and if it exists, this means that the first instance is running. Am I following you, so far? But what if the first process crashes and doesn't delete that file. What would happen then? The process that checks will read that file and assume that the process is running, when in reality it is not. – c00000fd Apr 02 '23 at 09:35
  • Basically yes that's what I mean. But if the program crashes and doesn't delete the file, it's a bug that needs to be fixed. I've have it happen for a *lot* or programs, some very big and prominent ones even, where I have to go in and remove the pid file manually. There are ways to work around the issue, but ultimately the proper fix is to actually fix the crash bug. If it happens once you delivered the program, then you need to have some way for customers to notify you about it, some kind of customer support. But there's no way to protect yourself 100% no matter the system used. – Some programmer dude Apr 02 '23 at 10:49
  • @Someprogrammerdude I disagree with your last statement. On Windows for instance, there are named kernel objects that are removed automatically when the last handle is closed. That way you don't need to delete anything if the app crashes, the named object will be closed, and thus removed by the kernel automatically. (Which I would use for this kinda application.) – c00000fd Apr 02 '23 at 11:06

0 Answers0