Programmatically stop and start daemon - ios7

I want to stop my daemon from inside it. In other words daemon should stop and restart itself when a specific event occur. I am using following command it works fine in terminal but not inside daemon.
system("launchctl stop com.test.myDaemon");

Probably the simplest way of doing it.
In your daemon plist file add this
<key>KeepAlive</key>
<true/>
That way iOS will automatically restart your daemon when it quits for whatever reason (signal, exception, daemon itself).
When you need to restart your daemon simply call
exit(0);

creker's answer worked for me on a jailbroken iOS 7.0.4 phone. However, you should be able to make your launchctl work as well (yes, I tested this, too).
Here are some things you might want to check:
Are you doing something in your daemon's plist file that changes which user it runs as? If you are telling launchd to run your daemon as a non-root user, that might prevent your programmatic launchctl command from working.
Do you have an entry in your plist file for the OnDemand key? Normally, you shouldn't. I'm wondering if you do, and it's conflicting with the KeepAlive setting in creker's answer.
Are you sure that this command exactly (launchctl stop com.test.myDaemon) succeeds from the command line?
The reason I ask is that many people build their Launch Daemons based on a tutorial here. In general, it's a great tutorial. But, there is at least one mistake. In the sample daemon .plist file, the value here for Label:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.chrisalvares.DLocationDemon.plist</string>
is not correct. It shouldn't be com.chrisalvares.DLocationDemon.plist. It should just be com.chrisalvares.DLocationDemon. In many cases, it doesn't matter. But, if you are issuing launchctl stop commands, the name for Label must match what you pass to launchctl. If you repeated the mistake in the tutorial, then you either need to fix the plist file, or use this command:
system("launchctl stop com.test.myDaemon.plist");
    4. Finally, there might be an issue with calling exit(0). First, it's possible that if you run this enough times, and call exit(0) enough times, iOS might flag your process as a badly behaving process, and refuse to continue to restart it. I don't think these rules are documented anywhere, but there are other similar features in iOS that work this way. So, that might suggest using launchctl instead. The other thought I had is that, even though exit(0); worked once for me, it's possible that you should chose a different exit code (not 0). I know that with VoIP apps (which are similar to a daemon in some ways), iOS only restarts your app automatically if it exits with a non-zero exit code. So, you might try exit(1);.
Those are my best guesses.
References
https://developer.apple.com/library/mac/documentation/macosx/conceptual/bpsystemstartup/chapters/CreatingLaunchdJobs.html

Related

How to run a script from startup on Raspbian 10 (buster)?

I have designed a GUI that I want to run as soon as I turn on my Raspberry Pi. It is currently set up to automatically log in as user on startup, but if that makes the process more difficult I can change that. My Raspi runs on Raspbian 10 (buster), which has made things difficult since I can only find tutorials for Raspbian 8 or so.
I have tried modifying autostart folder, but it is not in the same location as it was in previous Raspbian versions and doesn't seem to be working the way it used to. Tutorials have said to create a .desktop file in /home/pi/.config/autostart but I don't have a .config folder, or at least it's hidden. For me, autostart is in /etc/xdg/autostart and when I try to create a new file here using nano in the terminal, I get the message [Directory '/etc/xdg/autostart' is not writable] and it doesn't save my file.
I have also tried calling my script in /etc/rc.local but it did nothing. Some have said it doesn't work for GUIs.
Here's what I type into terminal:
$ nano /etc/xdg/autostart/gui.desktop
and a new file pops up, but at the bottom I get the warning [Directory '/etc/xdg/autostart' is not writable]
How can I get my GUI script to run on startup with Raspbian 10 (buster)?
There are a number of issues here, first when you are looking at tutorials recognize that Linux distros are built in layers, for simplicity let's say your "layer stack" looks like this: kernel, systemd, x11, xdg, lxde. The kernel boots, then starts systemd, which then starts x11 (and a lot of other stuff), x11 starts xdg (and some other stuff, I think), lxde is started by either x11 or xdg I'm not sure which.
You want to add something to this process, you can do it at the kernel level (bad idea), at they systemd level (probably not right unless its a daemon), at the x11 level (still probably bad as you still don't have a user session yet), or at the xdg or lxde level.
xdg is probably the right place as it has all you need ( a gui, a user session) while being common (xdg will still work if you switch window managers, probably)
With that out of the way, why isn't your solution of modifying xdg working? It's because '/etc/xdg/autostart' is a system configuration directory. Any changes made to it will apply to all users. You may want this, but the system is trying to protect other users on your system and only allows root to make changes to everyone. If you want to do that use "sudo" (documented elsewhere on stack exchange and the internet). If you want to do it just for you use ~/.config/autostart, (https://wiki.archlinux.org/index.php/XDG_Autostart) you might need to create that directory with "mkdir ~/.config/" and then "emacs ~/.config/autostart"
Would it be better to have the python program run in a terminal window from startup? That way you would see what it is doing in case of errors.
If so, perhaps check this out https://stackoverflow.com/a/61730679/7575617
By the way, in the file manager, hit CTRL+H to toggle viewing hidden files and folders.

Why are environment variables always null to Gradle (only) when run from IntelliJ IDEA?

I wrote a task in gradle that grabs an environment variable.
task run(type:Exec) {
def SYS_ENV = System.getenv("SYSTEM_ENV")
// do something with SYS_ENV
}
If I run this task with ./gradlew :taskName it's all fine, but if I run the same task from IntelliJ IDEA, (with the button, or from the gradle panel) the env variable comes out as null.
I tried restarting IntelliJ, I also tried the Invalidate Caches/Restart option, but nothing changes.
Isn't IntelliJ IDEA supposed to run the Gradle script exactly like I run it form the command? What can I do to grab an env variable from Grade so that the script doesn't fail when run form IntelliJ?
EDIT: I did a bunch of trials, and I could make lanchctl setenv MY_PATH MY_VALUE work, but it's not permanent, and adding setenv MY_PATH MY_VALUE to /etc/lanchd.conf does not make it so.
A relatively old question, but the following worked for me on Yosemite (10.10) so answering here in case others have the issue.
Support for launchd.conf was removed in Yosemite. LaunchAgents can be used in OSX to start per-user processes. You can use these to re-run the launchctl step in your question effectively persisting the environment variable
Create a user Launch Agent to set your variables (edit the environment variables and run the following in a terminal window)
cat << EOF > ~/Library/LaunchAgents/user.environment.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>user.environment</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>-c</string>
<string>launchctl setenv MYPATH MY_VALUE</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
EOF
Restart your mac
Make sure you restart any open applications (e.g. IntelliJ). Just restarting didn't work for me, I needed to close and re-launch the apps.
References:
Setting environment variables via launchd.conf no longer works in OS X Yosemite/El Capitan/macOS Sierra?
https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html

Deleting plist file does not reset app on macOS 10.9+

While developing a Cocoa application on 10.9, I have noticed that if I go to ~/Library/Preferences and delete the plist file for my app (to reset it), on the next build-and-run, the app behaves as if the plist file had never been deleted at all.
It took me a long time to track down why this happens and I did not see a question/answer about it on SO, so I'm writing this question and answering it myself to help others.
On 10.9, the system is doing some more robust "caching" of preferences. After deleting the plist file, I fired up Activity Monitor and force-killed the "cfprefsd" process. Be careful: there are multiple processes with this name running and you only want to kill the one running under your own user; do not kill the one running as root.
Doing this seems to flush the preferences cache and on the next run of my app, I get a pristine start-from-scratch launch.
Edit: As reported below, using defaults delete [your bundle identifier] at the command line also appears to eliminate the caching issue. I've had mixed success with this.
I found out that killing the user process cfprefsd will reflush the cache, so your changes will be kept
killall -u $USER cfprefsd
In terminal:
defaults delete com.somecompany.someapp
BTW, I've just released a GUI app that may be more convenient than working with the defaults command:
http://www.tempel.org/PrefsEditor
It works practically the same as Xcode's plist editor, but affects the user's app preferences directly.
To delete all your prefs, you could open your prefs in my Prefs Editor, Select All, then delete them with the Backspace or Delete key, and they're instantly all gone.
However, for this particular task, using defaults delete might still be quicker, especially if you put the command into a text file ending in ".command", and make it executable (with chmod +x). Then you can double click it from the Finder to execute it.

iOS Processes Info (pid, uid, cpu, mem, ...)

I'm writing app like System Activity in Mac. I used modified darwin.h and darwin.c from this topic.
But it seems that it shows correct info only for certain fields (and some time ago it showed all correct info but only for current process - this app), for everything else it shows correct only pid, process name, group/owner. Everything else like cpu/mem/disk usage is nulled. I think it may be something with sandbox or security. Tried to move application to /Applications and setting root/wheel 755 but it's not work, still zeroed values.
Here's my output : click
Code changed in darwin.c : click, written after a lot of commented printf lines
Also there is a free apps approved in AppStore like SystemInfo (com.lymbilesoft.systeminfoliteforiphone) that shows detailed info about disk and processes, so how do it work? Tried nm-ing it's binary but did not find something useful.
Can someone please help me with it?
I'm not sure if this is the only problem, but it certainly is possible that your app needs to run as root for this to work correctly.
However, simply installing the app in /Applications, doing chown root.wheel, and chmod 755 will not cause it to run as root. It will still run as user mobile.
In order to get the app to run as root, see this answer
I've used this technique successfully, and if you have a jailbroken phone, you can navigate to /Applications/Cydia.app and see that this launch script is how Cydia does this, too.
I use ps aux from the Terminal/Command Line. That gives me all the stuff I need, regarding your concerns.

The application cannot be opened because its executable is missing

I have an application that I have been developing for some time now. Recently launching the application via a double click presents a dialog that says "You can't open the application RepoWatch because it may be damaged or incomplete."
Launching the application via open ./RepoWatch.app gives me "The application cannot be opened because its executable is missing."
I usually launch the application via ./RepoWatch.app/Contents/MacOS/RepoWatch simply out of habit (which DOES work), so I am unsure how long this has been happening, or what change happened immediately before hand. The most likely change is that I put cp Info.plist ./RepoWatch.app/Contents/ into my make file in order to version Info.plist without versioning everything in the .app bundle.
I have looked at Info.plist many times and cannot find anything wrong with it. The file opens up with Property List Editor without any errors. Saving from Property List Editor does not make the file "work" (if it is to blame in the first place).
The permissions as far as I can tell also look sane:
$ ls -l
./RepoWatch.app/Contents/Info.plist
-rw-rw-r--# 1 dgrace staff 789 Feb 1 23:20 ./RepoWatch.app/Contents/Info.plist
$ ls -l
/Applications/Adium.app/Contents/Info.plist
-rw-rw-r-- 1 dgrace staff 5750 Aug 21 15:41 /Applications/Adium.app/Contents/Info.plist
I am at a loss as to what to try next.
And here are the contents of Info.plist (Even though nothing has really changed in quite a while):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>RepoWatch</string>
<key>CFBundleIdentifier</key>
<string>com.doomstick.RepoWatch</string>
<key>CFBundleName</key>
<string>RepoWatch</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>LSMinimumSystemVersion</key>
<string>10.6</string>
<key>CFBundleVersion</key>
<string>Beta26</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>
Building on the answer that #smokris posted:
The problem seems to be with your app's registration in the Launch Services database. There is no need to rebuild the entire database. To force-update the entry for your app (specifically), use lsregister with the -f option:
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f MyApp.app
I was having the same problem you describe, and this worked for me. Thanks, #smokris!
Rebuilding the Launch Services database solves this problem for me.
Try executing the following command in Terminal:
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user
The problem is likely due to an invalid CFBundleExecutable property value in the Info.plist file you are copying into the application.
In Xcode projects the default value for this property is a special variable (placeholder) value (${EXECUTABLE_NAME}) that is expanded (replaced) when the build system builds the application. Are you sure you need to copy this file manually? Maybe you can add a script build phase that makes whatever changes you need after it has been expanded and copied into place by the normal build process.
While you are at it, you should check for other placeholder values in the file. It is likely that you will need to fill in CFBundleName (others may also be necessary, depending on your application type).
OK, some (more) shots in the dark.
The docs for LSMinimumSystemVersion say that the value is supposed to be a string with the form n.n.n. You might try adding a “.0” to the end of your value.
When you use ./RepoWatch.app/Contents/MacOS/RepoWatch to run it manually, are you using some sort of completion or filename generation, or are you typing it all in (especially the filename of the executable)?
Maybe the executable filename has some odd invisible/combining/look-alike character in it that does not match the value in Info.plist. Try ls -w /path/to/RepoWatch.app/Contents/MacOS/ | xxd to look at the bytes for anything non-ASCII.
Does plutil -lint /path/to/Info.plist give you an “OK”?
The # after the permissions in the ls -l output indicates some xattrs. These could be harmless, but have you looked at which ones are there with ls -l#?
If one of the xattrs looks suspect (or even if not) you could (cd /path/to/RepoWatch.app/Contents/ && mv Info.plist Info.plist.save && cat Info.plist.save > Info.plist) to get a copy without the xattrs and test with it.
If using the non-xattr'd file still causes problems, you might try systematically modifying and deleting keys (after making a backup copy, like the .save above) to see if you can cause a different error message that might help indicate the problem.
Project Menu > Set Active Executable