I need to kill java process, that runs main class blabla.class. I can use function kill(pid_t, SIGKILL) for this reason, but I need to get PID ID.
I could run linux command ps-ax | grep blabla to find PID ID. What is the best way to do this using C ?
Adapting the link given by Marco https://stackoverflow.com/a/8166467/1967396:
#define LEN 100
char line[LEN];
FILE *cmd = popen("ps -ax | grep blabla", "r");
fgets(line, LEN, cmd);
// now parse `line` for the information you want, using sscanf perhaps?
// I believe the pid is the first word on the line returned, and it fits in an int:
int pid;
sscanf(line, "%d", &pid);
pclose(cmd);
Related
procfs.c
for(i=0;i<10;i++)
{
//linux command to check process status
sprintf(cmd, "cat /proc/%d/status", pid[i]);
pf = popen(cmd,"r");
fread(data, 1024, 1, pf);
pclose(pf);
//......big chunk of code afterwards
}
This is part of the code I'm running on my ubuntu. Basically, pid array has some the process id's, and I want those data to be parsed in some sort of way - which did succeed, so this isn't the problem.
The problem is with some part of the structure. Initially when I saved the pid array, I used "ls /proc/" command - the same way I used "cat /proc/%d/status" command in the above code - to check the /proc/ folder for all the processes that are currently running. The above code runs some time later, so when I use the pid array list for execution, some programs are no longer running, and thus, is not in /proc/ folder (for example, the program itself). So while all the pid data are printed out the way I want them to, some data come out as below:
In order to cope with this I added a line of code like this:
if(!pf) continue;
I thought that this would see that the command has failed, and skip this iteration, but it didn't change anything.
Is there any way to deal with that error message?
edit: I also tried if(pf < 0), but this didn't work either.
Use the stat function to see if a file exists, which works perfectly well for /proc files.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
struct stat buf;
int ret = stat("/proc/2023", &buf);
if(ret == -1) {
//file doesn't exist, so proc with pid 2023 isn't running
}
else {
//file exists, so proc with pid 2023 is running
}
Incorporating this into your loop, we have:
for(i=0;i<10;i++)
{
struct stat buf;
sprintf(cmd, "/proc/%d", pid[i]);
int ret = stat(cmd, &buf);
if(ret == -1) continue;
//linux command to check process status
sprintf(cmd, "cat /proc/%d/status", pid[i]);
pf = popen(cmd,"r");
fread(data, 1024, 1, pf);
pclose(pf);
//......big chunk of code afterwards
}
I read cat /proc/[pid]/maps gives the informaion about its address space.
So I want to write a program which will print its own address space.
My program is this;
pid_t pid;
int fd;
char *buf;
pid = getpid();
fd = open("/proc/????/maps", O_RDONLY);
I'm getting the PID, but it won't help me to open the file.
How to convert the pid from pid_t to string and add it to open call?
Or is there any other way to open the file?
All modern procfs systems implement "/proc/self/" for the running process. Just
fd = open("/proc/self/maps", O_RDONLY);
If you still wish to create the path string yourself then you have to use sprintf
char filename[128];
sprintf(filename, "/proc/%d/maps", getpid());
fd = open(filename, O_RDONLY);
If you just want to print mapping information for review, one simple method:
you can use system library call to execute cat /proc/[pid]/maps
A simple C code is as follows:
char command[256];
sprintf(command, "cat /proc/%d/maps", getpid());
system(command);
You can refer to one example in my Gist.
I'm trying to execute other programs within my C program. My first attempt was with popen. When I try to read from pipe I only get a reply of 1 byte and nothing in buf. I'm not sure as to the reasoning behind this.
popen example:
#include<stdio.h>
#include<unistd.h>
int main(int argc, char* argv[])
{
FILE* pipe;
if ((pipe=(FILE*)popen("./test.php","r"))==NULL)
printf("this is not working\n");
char buf[1024] = {'\0'};
int fd=fileno(pipe);
int bytes = read(fd, buf, 1024);
printf("bytes read %d\n", bytes);
printf("The program: %s\n", buf);
if(pclose(pipe)<0)
printf("not working\n");
return 0;
}
php example
#!/usr/bin/php
<?php
echo "THIS IS A TEST THAT WORKED\n";
?>
The output:
bytes read 1
The program:
The output of ls:
ls -l test.php
-rwxr-xr-x+ 1 tpar44 user 62 Nov 10 14:42 test.php
Any help in this would be greatly appreciated!
Thanks!
You need to execute the php interpreter and pass the name of the script as argument, when using popen if your script does not have the shebang because the shell won't know which interpreter to use:
fp = popen("php /path/to/script/test.php", "r");
If the script has the shebang line you can just execute it, because popen uses the shell to execute commands and it can find out which one to use, so you could just do this:
fp = popen("/path/to/script/test.php", "r");
However, make sure the script is executable:
chmod +x test.php
you could also use execl() but you have to specify the path to the binary because execl doesn't use the shell:
execl("/usr/bin/php", "/usr/bin/php", "-q",
"/path/to/script/test.php", (char *) NULL);
Don't forget to actually read from the pipe ;)
fread(buf, 1, 1024, pipe);
I'm just starting to learn C programming and I have some uncertainty about fork(), exec(), pipe(), etc.
I've developed this code, but when I execute it, the variable c remains empty, so I don't know if the child isn't writing to the pipe, or the parent isn't reading from it.
Could you help me please? This is the code:
int main() {
int pid=0;
int pipefd[2];
char* c=(char *)malloc(sizeof(char));
FILE *fp;
pipe(pipefd);
pid=fork();
if (pid==0){
close(pipefd[0]);
dup2(pipefd[1],1);
close(pipefd[1]);
execl("ls -l | cut -c28","ls -l | cut -c28", (char *) 0);
}
else{
close(pipefd[1]);
read(pipefd[0], c, 1);
char* path="/home/random";
char* txt=".txt";
char* root=malloc(strlen(path) + strlen(txt) + sizeof(char));
strcpy(root,path);
strcat(root,c);
strcat(root,txt);
close(pipefd[0]);
fp=fopen(root,"w+");
(...)
}
The problem is that the final root string its only "/home/random.txt" because there is nothing in the char c, and what I want is to open the file "/home/random(number stored in char c).txt".
execl executes a single command, and is not aware of shell concepts such as pipes. If you want to execute a shell command, you will have to execute a shell, as follows:
execl("/bin/sh","/bin/sh","-c","ls -l | cut -c28", (char*) 0);
Always check the return value of the system calls (like execve(2) and derived functions like execl(3)), and use the errno(3) to figure out what went wrong.
In your case the execl line fails.
Using strcpy/strcat seems a bit excessively complex. snprintf can turn those 3 lines into one.
snprintf( root, size_of_buf, "/home/random%s", c );
Additionally, check your error codes. As noted, execl is failing and you don't know it. fork, dup2, ...,can also fail, you want to know sooner rather than later.
I need to kill a process using the kill API. For that I need the process id of the process. I tried to get it using:
ret = system("pidof -s raj-srv");
but it is not returning the correct value. I dont want to kill the process using this:
ret = system("pkill raj");
Is there any API that could be used to get the process id?
You are getting the return status of system. That's not the pid. You want something like this:
char line[LEN];
FILE *cmd = popen("pidof...", "r");
fgets(line, LEN, cmd);
pid_t pid = strtoul(line, NULL, 10);
pclose(cmd);
There could be multiple instances of processes running in that case , pidof returns strings of pid seperated by space .
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
main()
{
char pidline[1024];
char *pid;
int i =0;
int pidno[64];
FILE *fp = popen("pidof bash","r");
fgets(pidline,1024,fp);
printf("%s",pidline);
pid = strtok (pidline," ");
while(pid != NULL)
{
pidno[i] = atoi(pid);
printf("%d\n",pidno[i]);
pid = strtok (NULL , " ");
i++;
}
pclose(fp);
}
The system() call doesn't return the output of pidof, it returns pidof's return code, which is zero if it succeeds.
You could consume the output of pidof using popen() instead of system(), but I'm sure there's a better way (the way pidof itself uses). Perhaps it wanders through /proc.
What is returned by the system function is the return code from the command being executed.
What you can do is something like this:
system("pidof -s raj-srv > /tmp/pid-of-raj-srv");
And then read the contents of the file /tmp/pid-of-raj-srv.
I know it is not a fresh thread, but as I have only recently faced the same question, I will ask you. Did you see one of this:
Get process id by name in C
C function to find a process ID and kill it
man sysctl(3)
You can use sysctl to give you the needed information without having to pass through a system( "bla, bla" ) call.
It seems to be far more complicated at first, but may be worth depending on your needs.