-1

My app is a Web Server. It runs on Windows as a service, on Linux as a daemon. The support for same is inside the app itself. e.g.

MyWebServer -s

Installs and runs it as a service on Windows

MyWebserver -d 

Runs it as a daemon on Linux (Though scripts can be used too)

On Mac OS X, all the posts point to

launchctl

which needs a plist xml file

I just want my users to type

sudo ./MyWebServer -s

And it should automatically install the MyWebServer instance as a "launchd" daemon set to start with the computer and run silently in the background.

I have seen some apps doing that without any plist xml file. How to add the support for same from within the app. My server is written in C/C++

Edit: I don't want to use fork method in OS X instead the recommended launchd daemon

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
adnan kamili
  • 8,967
  • 7
  • 65
  • 125
  • You are comparing apples with oranges. The equivalent of what you want to do on OSX under Linux would be to a) install an init script b) add this init script to the appropriate runlevels and c) call said init script which starts your server. So you should use an installer generator or write an appropriate Portfile (for MacPorts) or whatever brew uses as a control file for its installer routine. – Markus W Mahlberg May 01 '15 at 18:52
  • @MarkusWMahlberg I only provide server executable to my customers – adnan kamili May 01 '15 at 18:54
  • Aha. And how are they started automatically under Linux without an init script, which is what you want to do under OSX. – Markus W Mahlberg May 01 '15 at 18:55
  • 1
    @MarkusWMahlberg we can add daemon support from within by forking or simply using daemon() function. Starting automatically is a secondary question, first it should run as a daemon. I have seen apps doing it for mac, it should be possible – adnan kamili May 01 '15 at 18:57
  • 1
    What happens if you try to build the same fork and daemonizing code you use for Linux on OSX? – Chris Stratton May 01 '15 at 19:09
  • Which is not what you stated in your question. In OSX, you fork into background pretty much the same way as in Linux. But in order to have your daemon automatically start, you ***must*** communicate with launchd one way or the other. Except for using `@reboot` with cron, but that's a poor mans way (and comes with some implications) – Markus W Mahlberg May 01 '15 at 19:11
  • @MarkusWMahlberg daemon() function is deprecated in OS X and Apple recommends you to use launchd – adnan kamili May 01 '15 at 19:18
  • If you specifically do not want to use that, then include it in your question. But note that "deprecated" does not mean "does not work" and it is not the only way to accomplish similar functionality on a unix-style OS. – Chris Stratton May 01 '15 at 19:20
  • @ChrisStratton It's been a while, but wasn't there way using two forks? – Markus W Mahlberg May 01 '15 at 19:28
  • If your app is using high-level frameworks, you can't safely run it as a daemon. See my recent answer [here](https://stackoverflow.com/questions/29936961/drawbacks-of-building-a-background-only-cocoa-app-as-a-launch-daemon/29939696#29939696) for the reasons. In any case, if you want your app launched by launchd, you ***have to*** use a launchd .plist file installed in the right place with the right ownership and permissions. – Ken Thomases May 01 '15 at 21:30
  • @KenThomases It is written is C/C++ - code written on Linux compiles directly on Mac – adnan kamili May 02 '15 at 07:56
  • @adnankamili Yes `daemon` is deprecated but it also tells you what to use as a replacements: `posix_spawn` (not launchd). – scravy Jul 25 '18 at 09:27

3 Answers3

2

You can try to call launchctl and use its submit option that will let you submit a program without a configuration file. Read the man for more.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
  • I was able to do this with `launchctl submit -l -- /path/to/app`. I _think_ `AppLabel` is just for display purposes. – Eric Hu Apr 08 '20 at 01:38
1

If you want to have a process running as a deamon, just detach it from the terminal. Usual minimal way to do this is:

if (fork()!=0) {
  exit(0);
}
// do the job

This will create an orphan process which will be adopted by init.

If you want to provide boot time launching and launchd control, have a look at /Library/LaunchDaemons on OSX.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
  • This neither answers my question nor adds anything to may knowledge. I need a "launchd" daemon – adnan kamili May 01 '15 at 19:14
  • 1
    @adnankamili - blatantly untrue. Even in its original this answered the question **you actually asked** and clarified in comments - in particular it accomplishes the same thing as your Linux example. If it doesn't add to your knowlege, that is your fault for not asking a more precise question. – Chris Stratton May 01 '15 at 19:15
  • @ChrisStratton My question specifically mentions "launchd" daemon – adnan kamili May 01 '15 at 19:17
  • 1
    Your question shows a Linux example which uses no equivalent, and in comments you specifically invite "Starting automatically is a secondary question, first it should run as a daemon." Don't complain when you get exactly what you asked for. – Chris Stratton May 01 '15 at 19:18
  • @adnankamili You do not need a launchd daemon, you think you need one. For simply running as a daemon `fork` or `posix_spawn` get the job done. – scravy Jul 25 '18 at 09:29
0

You seem to be having a hard time understanding that running a start-up daemon in the background in OSX hidden from sight from the user should be as simple as creating a service with a line of text like in windows. This is just one of the reasons Windows is horrible for security and malware can just run around in it like it is an open pool of circus urine...

You saying that you coded it in C++ and complies on OSX doesn't mean anything about the legitimacy of getting your questionable Daemon on the launchd list.

You need to have your compiled program copied to the home folder. You then need to create a .plist file for it with all the correct details. Then copy over the .plist file to the /launchdaemons directory (which requires root access) You will then need root access again to register and change the ownership with chroot of the plist file in it's new location. Finally register it directly with launchd itself (requires root access)

If your Daemon is doing anything highly suspicious, loading/unloading kext modules or editing crucial files of that sorts, then it will be denied by SIP and you will either A) Goto Apple and get it certified or B) Manually disable SIP in recovery mode by hand