Here my code:
extern int errno;
pid_t system1(const char * command)
{
pid_t pid;
pid = fork();
cout<<"PID in child "<<(int)pid<<endl;
if (pid < 0) {
return pid;
} else if (pid == 0) {
execl("/bin/sh", "sh", "-c", command, (char*)NULL);
_exit(1);
}
int stat_val;
pid_t child_pid;
cout << "Hello1" << endl;
child_pid = wait(&stat_val);
cout << "child_pid = " <<(int)child_pid<< endl;//LINE 1
if(WIFEXITED(stat_val))
printf("Child has terminated with exit code %d\n", WIFEXITED(stat_val));
else
printf("Child has existed abnormally\n");
return child_pid;
}
int main( )
{
int pid_1 = system1("setup.csh &");;
struct stat status;
sleep(10);
cout<<"errno = "<<errno<<endl;
int i = kill(pid_1,0);
cout<<"Pid id = "<<pid_1<<endl;
cout<<"i === "<<i<<endl;
cout<<"errno = "<<errno<<endl;
if(errno == ESRCH)
{
cout<<"process does not exist";
}
else
{
cout<<"process exist"<<endl;
}
return 0;
}
In above code I am getting different PID of child at LINE 1 and PID of process setup.csh . Can anybody please help me out. I want to get PID of my process setup.csh.
I am looking other PID value using ps -u user | grep setup.csh in console.
When you run:
sh -c 'setup.csh &'
the original shell process forks another child process to run csh. The process hierarchy is:
YourProgram
sh -c 'setup.csh &'
csh setup.csh
There's no way to get this PID directly in the original program. Why don't you run setup.csh directly from your program, instead of going through the shell?
Actually, there's a way you can accomplish this. If you use the exec shell command, it runs the specified command in its own process, rather than forking a child:
system1('exec setup.csh &');
Related
I wrote a program which stops the time of a child process calling execvp(). The next task is to occasionally stop the child process for a given time and continue it.
pid_t child = fork();
if(child == 0){
// In child process
execvp(); // e.g. sleep 10
} else {
// In parent process
kill(child, SIGSTOP);
// Do stuff
kill(child, SIGCONT);
}
What i think is happening here is, that kill(child, SIGSTOP) is pausing the child process but not the execvp() process within it. Is there a way to get the pid of the execvp() process and stop it directly?
Edit example:
int main(int argsc, char *argv[]) {
int status;
// Fork for processB
pid_t processB = fork();
if (processB == 0) {
system("~/loop.sh");
} else {
for (;;) {
sleep(5);
kill(processB, SIGSTOP);
std::cout << "Should have stopped counting" << std::endl;
sleep(3);
kill(processB, SIGCONT);
// If loop process ended, exit watchDog
if (waitpid(processB, &status, WNOHANG) == processB)
_exit(1);
}
}
return 0;
}
Loop.sh
counter=0;
while :;
counter=$((counter+1));
do echo $counter;
sleep 1;
done
return 0;
I am writing a program in C++ which reads text from command line and then passes that to another program which uses this text.
Now, I am reading text in program 1 like so:
std::string line;
std::getline(std::cin, line);
And then I am using forks to open a child process and using execl command to run the executable of the program 2. Now I don't know how to make program 2 read this text and use it.
pid_t pid = fork();
if (pid < 0) {
perror("Fork failed");
exit(1);
}else if (pid == 0) {
// Execute the rgen here after parent is done
execl("./program2",".program2", NULL);
}
The above code works and runs the program 2. However, I just don't know how to pass the text read from terminal.
This is the full code:
int main(int argc, const char * argv[]) {
std::string line;
std::getline(std::cin, line);
pid_t pid = fork();
if (pid < 0) {
perror("Fork failed");
exit(1);
}else if (pid == 0) {
execl(".program2",".program2", NULL);
}
return 0;
}
Any help will be appreciated. Thanks.
This is the code
pid_t pid;
srand(time(NULL));
for (int i=0; i < 2; i++)
{
pid = fork();
if (pid < 0)
{
std::cout<< "fork failed";
return -1;
}
else if (pid == 0)
{
std::cout<< "Process "<< i+1 << " ID: " << pid <<std::endl;
std::thread one (threadFunction, 0);
std::thread two (threadFunction, 1);
std::thread three (threadFunction, 2);
one.join();
two.join();
three.join();
}
else
{
wait (NULL);
exit(0);
}
}
The loop is supposed to create two different processes but whenever I run this the output pid is always 0. Does this mean it the same process
if pid == 0 your code is executing the child process. If pid is different than 0 your code execute the parent process
see section return value of the man
http://man7.org/linux/man-pages/man2/fork.2.html
you can find out the real pid of the child with function getpid
http://man7.org/linux/man-pages/man2/getpid.2.html
I'm writing a simple pipe program that will ask for two commands then run the programs as if they were entered into bash as cmd1 | cmd2. Then it should loop and ask again until one of the commands is quit.
I've already written this much:
#include<iostream>
#include<string>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<signal.h>
using namespace std;
int main(int argc, char *argv[])
{
int pid1, pid2, errchk;
int pip[2];
char cmd1[128];
char cmd2[128];
int i = 0;
int status;
errchk = pipe(pip);//make pipe
if(errchk == -1)//check for error in pipe
{
perror("pipe");
exit(1);
}
while(i<3)
{
i++;
//Enter commands here
cout<<"Enter cmd1: ";
cin>>cmd1;
cout<<"Enter cmd2: ";
cin>>cmd2;
//if a command is quit... quit
if(strcmp(cmd1,"quit")==0 || strcmp(cmd2,"quit") == 0)
{
cout<<"Quitting...\n";
exit(1);
}
pid1 = fork();
cout<<"first fork makes pids: "<<pid1<<endl;
if(pid1 < 0)
{
perror("fork");
exit(1);
}
else if(pid1 == 0) //MAIN CHILD
{
cout<<"In main child with pid: "<<pid1<<endl;
pid2 = fork();
cout<<"second fork makes pids: "<<pid2<<endl;
if(pid2 == 0)//SUB CHILD 2 to run cmd2
{
cout<<"In child of second fork"<<endl;
close(0);
close(pip[1]);
dup(pip[0]);
execvp(cmd2,argv);//execute command2 and die
}
else if(pid2 > 0)//SUB CHILD 1 to run cmd1
{
cout<<"In parent of second fork"<<endl;
close(1);
close(pip[0]);
dup(pip[1]);
execvp(cmd1,argv);//execute command1 and die
}
}
else if(pid1 > 0) //MAIN PARENT
{
wait(NULL);//wait for cmd1
wait(NULL);//wait for cmd2
cout<<"DONE executing"<<endl; //keep going
}
}
return 0;
}
When I run it and enter ls and wc
The output I get is:
Enter cmd1: ls
Enter cmd2: wc
first fork makes pids: 5785
first fork makes pids: 0
In main child with pid: 0
second fork makes pids: 5786
In parent of second fork
second fork makes pids: 0
In child of second fork
DONE executing
5 5 54
The main problem I have is that I should have Done executing come after ls|wc not the other way around.
I'm thinking the wait(NULL) isn't working but I'm not sure.
Please advise.
And Thank you.
You have:
parent
1. child1
2. child2
2. exec()
1. exec()
When you exec in child1, child2 gets reparented to init, and you can no longer wait for child2 to terminate.
So we need to do a little bit of refactoring to get something looking like:
parent
1. child1
1. exec()
2. child2
2. exec()
wait() x 2
Basing this on your own code, with the refactoring to accomplish something like the look-alike code (some comments in-line):
#include<iostream>
#include<string>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<signal.h>
using namespace std;
int main(int argc, char *argv[])
{
int pid1, pid2, errchk;
int pip[2];
char cmd1[128];
char cmd2[128];
int status;
while(true)
{
errchk = pipe(pip);//make pipe
if(errchk == -1)//check for error in pipe
{
perror("pipe");
exit(1);
}
//Enter commands here
cout<<"Enter cmd1: ";
cin>>cmd1;
cout<<"Enter cmd2: ";
cin>>cmd2;
//if a command is quit... quit
if(strcmp(cmd1,"quit")==0 || strcmp(cmd2,"quit") == 0)
{
cout<<"Quitting...\n";
exit(1);
}
pid1 = fork();
cout<<"first fork makes pids: "<<pid1<<endl;
if(pid1 < 0)
{
perror("fork");
exit(1);
}
if (pid1 == 0) // in child
{
cout<<"In child of first fork"<<endl;
close(pip[0]); // close read-end of pipe
close(0); // close stdin
close(1); // close stdout
dup2(pip[1], 1); // write-end of pipe is stdout of cmd1
argv[0] = cmd1; // make it look like the command in the ps output
execvp(cmd1,argv);//execute command1 and die
fprintf(stderr, "execvp(1): `%s': %s\n", cmd1, strerror(errno));
return 0;
}
pid2 = fork();
cout<<"second fork makes pids: "<<pid2<<endl;
if (pid2 < 0)
{
perror("fork2");
exit(1);
}
if (pid2 == 0)
{
cout<<"In child of second fork"<<endl;
close(pip[1]); // close write-end of pipe
close(0); // close stdin
dup2(pip[0], 0); // read-end of pipe is stdin of cmd2
argv[0] = cmd2; // update ps output
execvp(cmd2,argv);//execute command2 and die
fprintf(stderr, "execvp(1): `%s': %s\n", cmd2, strerror(errno));
return 0;
}
if(pid1 > 0) //MAIN PARENT
{
// close remaining pipe handles in parent
close(pip[0]);
close(pip[1]);
wait(0);//wait for one command to run
wait(0);//wait for a second command to run
cout<<"DONE executing"<<endl; //keep going
}
}
return 0;
}
I'm not going to lie. This is a homework question. However, as far as I'm concerned, the points are gone baby gone. Right now, I'm just looking for an answer, because I -think- I might be insane.
The goal of this program is to execute the command ps -A | grep (inputstring) | wc -l in a way similar to how the shell does it. So, I spawn the processes, and have them wait on each other. The newest process, the great-grandchild, execlp("ps","ps","-A",NULL) which replaces itself with the ps -A process. Before it execlp, I make sure its standard output is going to the pipe output. The next process in line is wait()ing, and already has itself set up so that the input pipe goes to standard in, and standard out goes to the output pipe, and it will execute grep, and so on.
I'm almost positive I have it set up correctly. And yet... the program does. Not. Work.
#include <stdlib.h>
#include <iostream>
#include <string>
#define MAXLINE 1500
#define READ 0
#define WRITE 1
using namespace std;
int main( int argc, char** argv ) {
//* start of input block
if ( argc != 2 ) {
cout << "Usage: ./a.out arg1" << endl;
return 0;
}
string in = argv[1];
// end of input block */
int pipeA[2], pipeB[2], pid, stat;
// get our first set of pipes
if ( pipe(pipeA) < 0 ) {
cerr << "Pipe error.\n";
exit(-1);
}
if ( pipe(pipeB) < 0 ) {
cerr << "Pipe error.\n";
exit(-1);
}
// make the first fork
if ( (pid = fork() ) < 0 ) { cerr << "Fork error.\n"; exit(-1); }
if ( pid > 0 ) { // parent case
wait(&stat);
} else { // child case
if ( (pid = fork()) < 0 ) { cerr << "Fork Error\n"; exit(-1); }
if ( pid > 0 ) { // child
wait(&stat);
dup2(pipeA[READ],READ);
execlp("wc","wc","-l",NULL);
} else { // grand-child
if ( (pid = fork()) < 0 ) { cerr << "Fork Error\n"; exit(-1); }
if ( pid > 0 ) { // still grand-child
wait(&stat);
dup2(pipeB[READ],READ);
dup2(pipeA[WRITE],WRITE);
close(pipeB[READ]);
execlp("grep","grep",in.c_str(),NULL);
} else { // great grand-child
dup2(pipeB[WRITE],WRITE); // t now goes to pipeB[1]
close(READ);
close(pipeB[READ]);
execlp("ps", "ps", "-A", NULL);
}
}
}
return 0;
}
EDIT: Changed to the two-pipe variant of my code.
I'm virtually certain this is what you're trying to do. Apologies in advance for the sloppy coding. its somewhat late here and I really should be sleeping right now:
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#define READ 0
#define WRITE 1
// ps -A | grep argv[1] | wc -l
int main( int argc, char** argv )
{
// start of input block
if ( argc != 2 )
{
std::cout << "Usage: ./a.out arg1" << std::endl;
return 0;
}
// make local copy of argument
std::string in = argv[1];
int fd1[2], fd2[2], pid;
// allocate two pipe sets
if (pipe(fd1) < 0 || pipe(fd2) < 0)
{
perror("Failed to create pipe.");
return EXIT_FAILURE;
}
// launch first child process.
if ((pid = fork()) < 0)
{
perror("Failed to fork child(1)");
return EXIT_FAILURE;
}
if (pid == 0)
{
// wc -l process.
// stdin = fd2(read)
close(fd1[READ]);
close(fd1[WRITE]);
close(fd2[WRITE]);
dup2(fd2[READ],STDIN_FILENO);
execlp("wc","wc","-l",NULL);
}
// fork again. this time for grep
if ((pid = fork()) < 0)
{
perror("Failed to fork child(2)");
return EXIT_FAILURE;
}
if (pid == 0)
{
// grep argv[1] process.
// stdin = fd1(read)
// stdout = fd2(write)
close(fd1[WRITE]);
close(fd2[READ]);
dup2(fd2[WRITE], STDOUT_FILENO);
dup2(fd1[READ], STDIN_FILENO);
execlp("grep", "grep", in.c_str(), NULL);
}
// fork once more. this time for ps -A
if ((pid = fork()) < 0)
{
perror("Failed to fork child(3)");
return EXIT_FAILURE;
}
if (pid == 0)
{
// ps -A process.
// stdout = fd1(write)
close(fd2[WRITE]);
close(fd2[READ]);
close(fd1[READ]);
dup2(fd1[WRITE], STDOUT_FILENO);
execlp("ps", "ps", "-A", NULL);
}
int stat=0;
wait(&stat);
return EXIT_SUCCESS;
}
On my system, ps -A reports 141 lines, of those 41 have the word System somewhere within, verified by simply running ps -A | grep System | wc -l. The above code generates precisely the same output.
I'm not sure but maybe calling dup2 before waiting on the child would fix the pipe problem.
The reason I'm not sure is that it normally stdin and stdout are bufferized so I suppose that even if you hook your pipe up with them after the child has finish running you should get the same results but maybe (if someone knows the answer to this please correct me) the buffers for stdin and stdout get wiped with the end of the child process.
Also, could you update the code in your question to contain the modified code with two sets of pipes ?