Query if service is running - c

How can I query if a service (dnsmasq) is running, in C?

According to the dnsmasq man page, by default it writes a pid file to /var/run/dnsmasq.pid. This file will be a text file that contains an integer representing the process ID. Open the file, read the integer, and call kill(pid, 0) to see whether the process is alive at that pid. (Although checking for PID existence isn't guaranteed to not find some other process running at that PID, it's usually good enough.)

Related

I donĀ“t know how i can get the pid of an process by process name

I want to get the process id for example of the process "notepad.exe".
I only found threads etc. for how to get process by PID. But I want to get the PID by process name (in this scenario "notepad.exe").
And this with my kernel driver.
There can be more than one process with a process image coming from a file notepad.exe. You must enumerate all the running processes and retrieve the module name from that. It's described in the MSDN: https://learn.microsoft.com/en-us/windows/desktop/psapi/enumerating-all-processes
From the list of processes you then extract all the processes with a module name notepad.exe and get the list of matching PIDs.

How to make a child process use another terminal input and output?

I googled a lot but haven't found any real solution satisfying my needs.
I need the forked child process to use the stdin and stdout of another terminal rather than the one that called it here an example of what I want to do
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int main()
{
pid_t pid;
printf("process parent pid is %d\n",getpid());
pid =fork();
printf("process child pid is %d\n",pid);
if(pid==0)
{
//int exit_status = system("gnome-terminal");
char a[20];
while(1)
{
scanf(" %s",a);
printf("child %s \n",a);
}
}
while(1)
{
char b[20];
scanf(" %s",b);
printf("parent %s \n",b);
}
}
I need the child for example to interact with the user through another terminal.
As I understand your question, you wish fork a child process that does all its interaction with the user through a virtual terminal, namely gnome-terminal.
Then, first of all, read this article about the difference between terminals and shells. Then read this article about Unix Pseudo Terminals. Then read this one about the /dev/pts filesystem. This will give you the background for my answer.
Here is one way to create a child process that connects to a different terminal, a virtual terminal. I admit, I've not done this in a long time, and then it was with a physical TTY, not a pseudo-terminal. But the background information should help you get past any hangups you may run into.
The overall approach is to fork two child processes. One for the virtual terminal and one for the worker process. You will then exec the virtual terminal process in such a way that it does not shut down when the shell exits. You really don't even want it to launch a shell or any program for that matter, because you are going to be supplying the running process that will interact with it. With gnome-terminal, is not very easy to tell it to hang around after the process exits. You should read this to get suggestions on how to keep it around. An alternative would be to use "xterm" which has the "--hold" option which appears suited for that purpose. "xterm" also has the "-S" option which sounds exactly like what you need. To use the "-S" options, you will need to read about PTS
Since XTERM has the options you need, I will describe the approach based upon XTERM instead of gnome-terminal.
In your child program you will need to open /dev/ptmx to get a master pseudo-terminal file descriptor. You then call ptsname() on the FD to get the name of the PTS. You need the name to inform XTERM what slave PTS to use. You have to grant access and unlock the FD by calling grantpt() and unlockpt() on the master FD. Next, fork another process and exec() XTERM with the -S option, which takes the PTS name and file descriptor number in the form of "-S/dev/pts/123/42" or equivalently "-S123/42". In this case, I don't think you need the "--hold", but add it if it turns out that you do. (Refer to the XTERM man page for more information on using -S)
This establishes the terminal as the User I/O device on your child process's master pseuo-terminal file descriptor. So, next you would dup() the file descriptor onto fd 0 and fd 1 (and fd 2 if you want stderr to go there).
I am sorry this is so general. The approach should work, but you may have to tweak it for your specific flavor of Linux/Unix. Please let me know how you do, and if I get a chance, I will get a Linux up and try it out myself.
stdin is file descriptor 0. To attach to another file or stream (or device), your child process must first close file descriptor 0, then open another file (device). Open will return fd 0 (if successful) because it is now the first available. You can use dup() to do this atomically.
You will need permission to open the device.
For example, let's say your input device of interest is /dev/input/tty1...
if(childpid == 0)
{
int fd = open("/dev/input/tty1", open_args);
if(fd >= 0)
{
/* Close stdin, duplicate the fd just opened to stdin */
dup2(0, fd);
// etc...

how to avoid to running program twice

I wondering if there is a way to prevent user to launch many time the program to avoid some problems.
when start my program with
/etc/init.d/myprog start
Next time when the user execute the same command it will not run.
The best way is for the launcher to attempt a launch, capturing the pid of the launch into /var/run
Then on subsequent launches, you read the pid file, and do a process listing (ps) to see if a process with that pid is running. If so, the subsequent launch will report that the process is already running and do nothing.
Read up on pid and lock files to get an idea of what is considered standard under the init.d system.
You need to open a .lock file and lock it with flock.
int fd = open("path/to/file.lock", O_RDWR);
if (fd == -1) {
/* error opening file, abort */
}
if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
/* other process already open, abort */
}
The Linux Standard Base supports a start_daemon function that delivers this feature. Use it from your init script.
The start_daemon, killproc and pidofproc functions shall use this algorithm for determining the status and the pid(s) of the specified program. They shall read the pidfile specified or otherwise /var/run/basename.pid and use the pid(s) herein when determining whether a program is running. The method used to determine the status is implementation defined, but should allow for non-binary programs. 1 Compliant implementations may use other mechanisms besides those based on pidfiles, unless the -p pidfile option has been used. Compliant applications should not rely on such mechanisms and should always use a pidfile. When a program is stopped, it should delete its pidfile. Multiple pid(s) shall be separated by a single space in the pidfile and in the output of pidofproc.
This runs the specified program as a daemon. start_daemon shall check if the program is already running using the algorithm given above. If so, it shall not start another copy of the daemon unless the -f option is given. The -n option specifies a nice level. See nice(1). start_daemon should return the LSB defined exit status codes. It shall return 0 if the program has been successfully started or is running and not 0 otherwise.

Less Hacky Way Than Using System() Call?

So I have this old, nasty piece of C code that I inherited on this project from a software engineer that has moved on to greener pastures. The good news is... IT RUNS! Even better news is that it appears to be bug free.
The problem is that it was designed to run on a server with a set of start up parameters input on the command line. Now, there is a NEW requirement that this server is reconfigurable (didn't see that one coming...). Basically, if the server receives a command over UDP, it either starts this program, stops it, or restarts it with new start up parameters passed in via the UDP port.
Basically the code that I'm considering using to run the obfuscated program is something like this (sorry I don't have the actual source in front of me, it's 12:48AM and I can't sleep, so I hope the pseudo-code below will suffice):
//my "bad_process_manager"
int manage_process_of_doom() {
while(true) {
if (socket_has_received_data) {
int return_val = ParsePacket(packet_buffer);
// if statement ordering is just for demonstration, the real one isn't as ugly...
if (packet indicates shutdown) {
system("killall bad_process"); // process name is totally unique so I'm good?
} else if (packet indicates restart) {
system("killall bad_process"); // stop old configuration
// start with new parameters that were from UDP packet...
system("./my_bad_process -a new_param1 -b new_param2 &");
} else { // just start
system("./my_bad_process -a new_param1 -b new_param2 &");
}
}
}
So as a result of the system() calls that I have to make, I'm wondering if there's a neater way of doing so without all the system() calls. I want to make sure that I've exhausted all possible options without having to crack open the C file. I'm afraid that actually manipulating all these values on the fly would result in having to rewrite the whole file I've inherited since it was never designed to be configurable while the program is running.
Also, in terms of starting the process, am I correct to assume that throwing the "&" in the system() call will return immediately, just like I would get control of the terminal back if I ran that line from the command line? Finally, is there a way to ensure that stderr (and maybe even stdout) gets printed to the same terminal screen that the "manager" is running on?
Thanks in advance for your help.
What you need from the server:
Ideally your server process that you're controlling should be creating some sort of PID file. Also ideally, this server process should hold an exclusive lock on the PID file as long as it is still running. This allows us to know if the PID file is still valid or the server has died.
Receive shutdown message:
Try to get a lock on the PID file, if it succeeds, you have nothing to kill (the server has died, if you proceed to the kill regardless, you may kill the wrong process), just remove the old PID file.
If the lock fails, read the PID file and do a kill() on the PID, remove the old PID file.
Receive start message:
You'll need to fork() a new process, then choose your flavor of exec() to start the new server process. The server itself should of course recreate its PID file and take a lock on it.
Receive restart message:
Same as Shutdown followed by Start.

how to retrieve process status whose procees id is given from c program?

I have to retrieve process status(whether process is running or stopped) whose procees id is given from my c program(i am using linux). i planned to use exec command
and written below statement
execv("ps -el|grep |awk '{print $2}'",NULL);
But it is not giving me desired output.
Please let me know where i am wrong.
The third field in /proc/<pid>/stat contains the process status: R if it's Running, S if it's Sleeping (there's a few others too, like D for Disk Wait and Z for Zombie).
The exec call returns the error code corresponding to whether the execution of the program was successful or not.
If you fork a child process and then exec the command in the child process, you can read the its exit status in the parent process using the waitpid call.
I doubt exec is the family of calls you require here. system(3) might be more ideal.

Resources