Observe a Process of Unknown PID (no UI) - objective-c

I've found this question, but even when is close to what I need, is useless
Basically, I have an app that needs to do something when another process (of known name) is launched and/or terminated, but i don't have the PID, so i can't set a kqueue to look for it.
I could do a while for "ps aux | grep processtolook | grep -v grep" command, but that's my last resort.
Any ideas?

Look at this answer: Determine Process Info Programmatically in Darwin/OSX. The libproc.h header file has proc_listpids which will get you all the pids. You can then get the pid information in a loop and using proc_pidinfo and check the name. Looking at the top source as suggested there might also be worthwhile. (The current verson is here http://www.opensource.apple.com/source/top/top-67/.)
Unfortunately, this is an undocumented interface and subject to change at any time. Also, it isn't the quickest thing, since you have to loop over all the processes in the system. In general, this isn't a great way to do this.
A better way might be to write a new processtolook that simply invoked the old one which you can move or rename. It could then notify you of the process start and stop. Is that a possibility?

If the target process/program name which you want the PID is "processtolook" then you can use pidof command to get the PID of that running program.
pidof processtolook
have a look at the pidof manual. This is a part of sysvinit-tools package.
EDIT1:
Have a look at this code i found: http://programming-in-linux.blogspot.com/2008/03/get-process-id-by-name-in-c.html
This might help you get you the outline.

On BSD you can use kvm_openfiles and kvm_getprocs to implement what you want. I don't know if it's available on OSX. If you have a pgrep program, look how it's implemented (src/bin/pkill.c).

Related

How to check if another instance of the app/binary is already running

I'm writing a command line application in Mac using Objective-c
At the start of the application, i want to check if another instance of the same application is already running. If it is, then i should be either wait for it to finish or exit the current instance or quit the other instance etc.
Is there any way of doing this?
The standard Unix solution for this is to create a "run file". When you start up, you try to create that file and write your pid to it if it doesn't exist; if it does exist, read the pid out of it, and if there's a running program with that pid and your process name, wait/exit/whatever.
The question is, where do you put that file, and what do you call it?
Well, first, you have to decide what exactly "already running" means. Obviously not "anywhere in the world", but it could be anything from "anywhere on the current machine" to "in the current desktop session". (For example, if User A starts your program, pauses it, then User B comes along and takes over the computer via Fast User Switching, should she be able to run the program, or not?)
For pretty much any reasonable answer to that question, there's an obvious pathname pattern. For example, on a Mac, /tmp is shared system-wide, while $TMPDIR is specific to a given session, so, e.g., /tmp/${ARGV[0]}.pid is a good way to say "only one copy on the machine, period", while ${TMPDIR}/${ARGV[0]}.pid is a good way to say "only one copy per session".
Simple but common way to do this is to check the process list for the name of your executable.
ps - A | grep <your executable name>
Thank you #abarnert.
This is how I have presently implemented. At the start of the main(), I would check if a file named .lock exists in the binary's own directory (I am considering moving it to /tmp). If it is, application exits.
If not, it would create the file.
At the end of the application, the .lock file is removed
I haven't yet written the pid to that file, but I will when exiting the previous instance is required (as of yet I don't need it, but may in the future).
I think PID can be retrieved using
int myPID=[[NSProcessInfo processInfo] processIdentifier];
The program will be invoked by a custom scheduler which is running as a root daemon. So it would be run as root.
Seeing the answers, I would assume that there is no direct method of solving the problem.

How to prioritize a particular process on start up?

In Linux, I want a process to be assigned with higher priority than usual. I.e. when a process starts I want it's priority to be set to higher value. I want this to be done implicitly, i.e when the process starts (eg.:on a double click).
For this will I have to change the kernel code (sched.c)?
And are there any tools or packages using which I can see how exactly a process starts and how the priorities are assigned?
Would ptrace ( http://linux.die.net/man/2/ptrace) and strace ( http://linux.die.net/man/1/strace) help me with this?
Assuming you don't want to hack the actual application itself you can always create a custom desktop file which wraps the command with "nice" which will modify the niceness (priority) of the command you'll run.
For example, create a ~/.local/share/applications/myfastapp.desktop which looks like:
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Exec=nice -n -20 /usr/bin/myapp
Name=My App (niced)
Comment=Custom definition for myapp
Have the process call the set_priority() system call in main() to lower it's nice level and raise it's priority. See the man page for details: http://linux.die.net/man/2/setpriority
You can also mark the process as a real time process using sched_setscheduler() but that is a little bit more involved and probably an overkill for what you seek.
You 100% don't need to change the kernel for this :-)

Monitor hung instances of a powershell script

I´m writing a Powershell script to do a bunch of things and when finished it will be run as a scheduled task. For that reason I want to be able to check whether an older instance is still alive when I start running the script and kill the older one if it exists.
I was thinking I would use something like this:
$process = Get_Process | $name
$process.kill
But how to get the $name variable in a simple way?
Does anyone have a better suggestion?
Best regards,
Gísli
You can do this in windows scheduled task configuration. The settings depends on the OS you are using though.
EDIT: that is you can configure the task to be killed after a certain period of time (i.e. when your next one starts).
Why do you need to get the name? Get-Process returns high fidelity Process objects and you can operate on it directly.
To get a process of a particular name use $n = Get-Process notepad, say, and then do $n.kill() to kill it. If you do need to check the name again, do $n.Name. To see what properties and methods you can use, try $n | get-member
And make sure you read the manual: http://technet.microsoft.com/en-us/library/dd347630.aspx

Kill process after launching with AuthorizationExecuteWithPrivileges

If I launched a shell script using AuthorizationExecuteWithPrivileges what would be the easiest way to kill the script and any other processes that it spawned.
Thanks
It's running as root, so you can't kill it from a regular-user process. You're going to have to ask it nicely to exit on its own.
Apple has sample code that uses stdout to pass the PID back to the caller.
Use the communications pipe that AuthorizationExecuteWithPrivileges() returns by reference in its last argument, FILE **communicationPipe, to send a message to the child process that asks it to take itself and its descendants out. It can then kill itself and all its descendants using kill(0, SIGINT), or, if more drastic measures are required, SIGKILL.
The message you use can be as simple as closing the file while the child waits for the file to close; at that point, it knows you're done talking to it and it's time to take itself out.
There are some caveats about the descendants that will actually receive this message, for which see the kill(2) manpage. The caveats mostly won't matter so long as the process you started via AEWP hasn't dropped privileges, though one implicit issue is that this approach won't work if any child processes have put themselves in a new process group.

Force a Samba process to close a file

Is there a way to force a Samba process to close a given file without killing it?
Samba opens a process for each client connection, and sometimes I see it holds open files far longer than needed. Usually i just kill the process, and the (windows) client will reopen it the next time it access the share; but sometimes it's actively reading other file for a long time, and i'd like to just 'kill' one file, and not the whole connection.
edit: I've tried the 'net rpc file close ', but doesn't seem to work. Anybody knows why?
edit: this is the best mention i've found of something similar. It seems to be a problem on the win32 client, something that microsoft servers have a workaround for; but Samba doesn't. I wish the net rpc file close <fileid> command worked, I'll keep trying to find out why. I'm accepting LuckyLindy's answer, even if it didn't solve the problem, because it's the only useful procedure in this case.
This happens all the time on our systems, particularly when connecting to Samba from a Win98 machine. We follow these steps to solve it (which are probably similar to yours):
See which computer is using the file (i.e. lsof|grep -i <file_name>)
Try to open that file from the offending computer, or see if a process is hiding in task manager that we can close
If no luck, have the user exit any important network programs
Kill the user's Samba process from linux (i.e. kill -9 <pid>)
I wish there was a better way!
I am creating a new answer, since my first answer really just contained more questions, and really was not a whole lot of help.
After doing a bit of searching, I have not been able to find any current open bugs for the latest version of Samba, please check out the Samba Bug Report website, and create a new bug. This is the simplest way to get someone to suggest ideas as to how to possibly fix it, and have developers look at the issue. LuckyLindy left a comment in my previous answer saying that this is the way it has been for 5 years now, well the project is Open Source the best way to fix something that is wrong by reporting it, and or providing patches.
I have also found one mailing list entry: Samba Open files, they suggest adding posix locking=no to the configuration file, as long as you don't also have the files handed out over NFS not locking the file should be okay, that is if the file is being held is locked.
If you wanted too, you could write a program that uses ptrace and attaches to the program, and it goes through and unlocks and closes all the files. However, be aware that this might possibly leave Samba in an unknown state, which can be more dangerous.
The work around that I have already mentioned is to periodically restart samba as a work around. I know it is not a solution but it might work temporarily.
This is probably answered here: How to close a file descriptor from another process in unix systems
At a guess, 'net rpc file close' probably doesn't work because the interprocess communication telling Samba to close the file winds up not being looked at until the file you want to close is done being read.
If there isn't an explicit option in samba, that would be impossible to externally close an open file descriptor with standard unix interfaces.
Generally speaking, you can't meddle with a process file descriptors from the outside. Yet as root you can of course do that as you seen in that phrack article from 1997: http://www.phrack.org/issues.html?issue=51&id=5#article - I wouldn't recommend doing that on a production system though...
The better question in this case would be why? Why do you want to close a file early? What purpose does it ultimately have to close the file? What are you attempting to accomplish?
Samba provides commands for viewing open files and closing them.
To list all open files:
net rpc file -U ADadmin%password
Replace ADadmin and password with the credentials of a Windows AD domain admin. This gives you a file id, username of who's got it open, lock status, and the filename. You'll frequently want to filter the results by piping them through grep.
Once you've found a file you want to close, copy its file id number and use this command:
net rpc file close fileid -U ADadmin%password
I needed to accomplish something like this, so that I could easily unmount devices I happened to be sharing. I wrote this quick bash script:
#!/bin/bash
PIDS_TO_CLOSE=$(smbstatus -L | tail -n-3 | grep "$1" | cut -d' ' -f1 - | sort -u | sed '/^$/$
for PID in $PIDS_TO_CLOSE; do
kill $PID
done
It takes a single argument, the paths to close:
smbclose /media/drive
Any path that matches that argument (by grep) is closed, so you should be pretty specific with it. (Only files open through samba are affected.) Obviously, you need root to close files opened by other users, but it works fine for files you have open. Note that as with any other force closing of a file, data corruption can occur. As long as the files are inactive, it should be fine though.
It's pretty ugly, but for my use-case (closing whole mount points) it works well enough.