I want to create a one level process tree using fork() system call, which looks as follows
for n = 4 process
I have tried this with the following code but this is not working. (here 1 is a child of parent process )
for(i = 0 ;i < n; i++){
chid = fork();
if ( chid == 0 ){
printf("%d\n",getpid());
while(++i < n){
chid = fork();
if(chid == 0){
printf(" %d ",getpid());
break;
}
}
}
else
break;
}
How can I make this ?
#include<stdio.h>
int main()
{
int i;
pid_t pid;
for(i=0; i<5; i++)
{
pid = fork();
if(pid == 0)
break;
}
printf("pid %d ppid %d\n", getpid(), getppid());
if(pid == 0)
{
/* child process */
}
}
Based on the discussion, here is the modified program.
#include<stdio.h>
#include<unistd.h>
int main()
{
int i;
pid_t pidparent, pid;
if( (pidparent = fork()) == 0 )
{
for(i=0; i<3; i++)
{
pid = fork();
if(pid == 0)
break;
}
if(pid == 0)
{
printf("child %d parent %d\n", getpid(), getppid());
}
}
else
{
printf("parent %d \n", pidparent);
}
/* printf("pid %d ppid %d\n", getpid(), getppid()); */
}
Related
I have this code which runs the command I give to it:
pid_t Utils::RunCommand(std::string cmd, int * infp, int * outfp)
{
std::cout << cmd << std::endl;
const char* command = cmd.c_str();
int p_stdin[2];
int p_stdout[2];
pid_t pid;
if (pipe(p_stdin) == -1)
return -1;
if (pipe(p_stdout) == -1) {
close(p_stdin[0]);
close(p_stdin[1]);
return -1;
}
pid = fork();
if (pid < 0) {
close(p_stdin[0]);
close(p_stdin[1]);
close(p_stdout[0]);
close(p_stdout[1]);
return pid;
}
else if (pid == 0) {
close(p_stdin[1]);
dup2(p_stdin[0], 0);
close(p_stdout[0]);
dup2(p_stdout[1], 1);
dup2(::open("/dev/null", O_RDONLY), 2);
/// Close all other descriptors for the safety sake.
for (int i = 3; i < 4096; ++i)
::close(i);
setsid();
execl("/bin/sh", "sh", "-c", command, NULL);
_exit(1);
}
close(p_stdin[0]);
close(p_stdout[1]);
if (infp == NULL) {
close(p_stdin[1]);
}
else {
*infp = p_stdin[1];
}
if (outfp == NULL) {
close(p_stdout[0]);
}
else {
*outfp = p_stdout[0];
}
return pid; }
The problem I am having with this code is the returned process ID is for the shell process that runs my command which prevents me from checking if the command I ran is still running. How can I either modify this function to instead return to me the created process or find the child's PID from the parent PID?
I am writing a code where I have to read from input files and then read the output. One of the files is large and is around 38 MB. I'm not very good at programming so by looking at some tutorials and xillybux programming guide, I wrote the following code to read from two files, write them to the logic and then read them. My motive is to calculate the time of reading and writing for my future project. But when I try to run the program I get the following error
Failed to open Xillybus device file(s), device resource busy
I don't know what I have done wrong. The code which I had written is below
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/time.h>
#include <math.h>
#include <string>
#include <cstdlib>
#define N ((cols+1)*rows + cols)
int main(int argc, char *argv[])
{
int fdr, fdw;
FILE *ftime_rw;
FILE *fp;
FILE *U, *V, *RI;
int rc, donebytes;
int *tologic, *fromlogic;
pid_t pid;
int i,j;
struct timeval tv1, tv2;
double time_rw;
char *buf;
int temp;
int rows= 575;
int cols= 18689;
fdr = open("/dev/xillybus_read_32", O_RDONLY);
fdw = open("/dev/xillybus_write_32", O_WRONLY);
if ((fdr < 0) || (fdw < 0))
{
perror("Failed to open Xillybus device file(s)");
exit(1);
}
U = fopen("U.txt", "r");
V = fopen("V.txt", "r");
RI = fopen("RI.txt", "a");
if(U==NULL || V==NULL || RI==NULL )
{
printf("Write in their respective files!\n");
exit(1);
}
for (i=0; i<rows; i++) // Read
{
fscanf(U,"%d", &temp);
fprintf(RI,"%d\n", temp);
}
for(j=0; j<rows; j++)
{
for (i=0; i<cols; i++) // Read
{
fscanf(V,"%d", &temp);
fprintf(RI,"%d ", temp);
}
fclose(U);
fclose(V);
fclose(RI);
tologic = (int*)malloc(sizeof(int)* N);
if (!tologic)
{
fprintf(stderr, "failed to allocate memory\n");
exit(1);
}
RI = fopen("RI.txt", "r");
for(j=0; j<rows; j++)
{
for (i=0; i<cols; i++)
fscanf(RI,"%d", &tologic[N]);
fclose(RI);
pid = fork(); // writer + reader
if (pid < 0)
{
perror("Failed to fork()");
exit(1);
}
if (pid) // writer process
{
close(fdr);
buf = (char *)tologic;
donebytes=0;
gettimeofday(&tv1, NULL); // start count time
while (donebytes < sizeof(int)*N) // write N integers
{
rc = write(fdw, tologic + donebytes, sizeof(int)*N - donebytes);
if ((rc < 0) && (errno == EINTR))
continue;
if (rc <= 0)
{
perror("write() failed");
exit(1);
}
donebytes += rc;
}
gettimeofday(&tv2, NULL); // stop count time
time_rw = (double) (tv2.tv_usec-tv1.tv_usec);
printf("Writer. Total time = %f usec\n", time_rw);
if(close(fdw)==-1)
printf("ERROR closing write_32 file!\n");
return 0;
}
else // reader process
{
close(fdw);
fromlogic =(int*)malloc(sizeof(int)* N);
if (! fromlogic)
{
fprintf(stderr, "failed to allocate memory\n");
exit(1);
}
buf = (char *)fromlogic;
donebytes = 0;
donebytes = 0;
gettimeofday(&tv1, NULL); // start count time
while (donebytes < sizeof(int)*rows) // read num_rows integers
{
rc = read(fdr, fromlogic + donebytes, sizeof(int)*rows - donebytes);
if ((rc < 0) && (errno == EINTR))
continue;
if (rc < 0)
{
perror("read() failed");
exit(1);
}
if (rc == 0)
{
fprintf(stderr, "Reached read EOF!? Should never happen.\n");
exit(0);
}
donebytes += rc;
}
gettimeofday(&tv2, NULL); // stop count time
time_rw = (double) (tv2.tv_usec-tv1.tv_usec);
printf("Reader. Total time = %f usec\n", time_rw);
for (i=0; i<rows; i++) // Integers read from logic
printf("Reader process : %d\n", fromlogic[i]);
sleep(1); // Let debug output drain (if used)
if(close(fdr)==-1)
printf("ERROR closing read_32 file!\n");
return 0;
}
}
}
}
I want to create a function where I pass a structure which will store the pid of the process that is spawned.
bool spawnHost(string ttyNumber, DeviceData &deviceData)
{
pid_t processID = fork();
pid_t hostProcessID = -1;
if (processID == -1)
{
printf("PID:%d-> Unable to fork a new process. Error: %s", getpid(), strerror(errno));
return false;
}
else if (!processID)
{
printf("PID:%d-> First child spawned. In Parent: %s", getpid(), processID);
signal(SIGCHLD, SIG_IGN);
hostProcessID = fork();
if (hostProcessID == -1)
{
printf("PID:%d-> Unable to fork a new process. Error: %s", getpid(), strerror(errno));
return false;
}
else if (!hostProcessID)
{
printf("PID:%d-> Starting %s at tty:%s", getpid(), hostAppPath.c_str(), ttyNumber.c_str());
char *args[] = { (char *) hostAppPath.c_str(), (char *) ttyNumber.c_str(), NULL };
execvp(hostAppPath.c_str(), args);
}
else
{
printf("PID:%d-> First child spawned. In child: %s", getpid(), hostProcessID);
sleep(5);
exit(0);
}
}
else
{
int childStatus;
waitpid(processID, &childStatus, 0);
if (WIFEXITED(childStatus))
printf("PID:%d has exited with exit code %d\n", processID, WEXITSTATUS(childStatus));
deviceData.setProcessID(hostProcessID);
return true;
}
}
The requirement here is that the host process (spawned in the second fork) shall not die, even if the parent process dies, and the pid of the host process shall be stored in a structure which was passed to the spawnHost() function. currently I am not able to get the pid. Is there something wrong with what I am dong?
I even tried the below approach:
bool spawnHost(string ttyNumber, DeviceData deviceData)
{
string hostAppPath = EXE_PATH;
signal(SIGCHLD, SIG_IGN);
pid_t processID = fork();
if (processID == -1)
{
printf("PID:%d-> Unable to fork a new process. Error: %s", getpid(), strerror(errno));
return false;
}
else if (!processID)
{
signal(SIGCHLD, SIG_IGN);
processID = fork();
if (processID == -1)
{
printf("PID:%d-> Unable to fork a new process. Error: %s", getpid(), strerror(errno));
return false;
}
else if (!processID)
{
if (setsid() < 0)
{
printf("PID:%d-> Unable to set new session ID. Error: %s", getpid(), strerror(errno));
return false;
}
printf("PID:%d-> Starting %s at tty:%s", getpid(), hostAppPath.c_str(), ttyNumber.c_str());
char *args[] = { (char *) hostAppPath.c_str(), (char *) ttyNumber.c_str(), NULL };
execvp(hostAppPath.c_str(), args);
}
else
{
deviceData.setProcessID(processID);
exit(0);
}
}
else
{
return true;
}
return true;
}
So thanks to #o11c The answer that I implemented is:
bool spawnHost(string ttyNumber, DeviceData &deviceData)
{
int pipefd[2];
string hostAppPath = HOST_PATH_PREFIX + HOST_NAME + BUILD_DIR_STRING + HOST_NAME;
if (pipe(pipefd) == -1)
{
printf("PID:%d-> IPC not possible as pipe failed");
return false;
}
signal(SIGCHLD, SIG_IGN);
pid_t processID = fork();
if (processID == -1)
{
printf("PID:%d-> Unable to fork a new process. Error: %s", getpid(), strerror(errno));
return false;
}
else if (!processID)
{
signal(SIGCHLD, SIG_IGN);
processID = fork();
if (processID == -1)
{
return false;
}
else if (!processID)
{
if (setsid() < 0)
{
printf("PID:%d-> Unable to set new session ID. Error: %s", getpid(), strerror(errno));
return false;
}
char *args[] = { (char *) hostAppPath.c_str(), (char *) ttyNumber.c_str(), NULL };
execvp(hostAppPath.c_str(), args);
}
else
{
/// Write the host pid to the pipe
close(pipefd[0]);
write(pipefd[1], &processID, sizeof(processID));
close(pipefd[1]);
exit(0);
}
}
else
{
close(pipefd[1]); /* Close unused write end */
read(pipefd[0], &processID, sizeof(processID));
close(pipefd[0]);
wait(NULL);
deviceData.setProcessID(processID);
return true;
}
return true;
}
I'm trying to implement piping in C++. My method piped takes in an array of arguments along the line of yes | head -10 | wc. It creates pipes number of processes and changes the image of the processes to, following that example, yes, head -10, and wc. Then it creates pipes-2 pipes and redirects the input and output of the processes to the pipes.
It's not working correctly, and just prints each command separately without redirecting input/output.
#include "piped.h"
using namespace std;
void piped(char *stringList[], int pipes)
{
//stringList[] is list of arguments seperated by |
//pipes = number of arguments
pid_t processList[256];
char *curList[256];
//Create a new process for each job using fork
for(int i = 0; i < pipes; i++){
processList[i] = fork();
if (processList[i] < 0) {
cerr << "Couldn't create process\n";
exit(1);
}
}
int j = 0;
//Replace the image of each process with the appropriate commands
for(int i = 0; i < pipes; i++){
pid_t pid = processList[i];
if(pid == 0){
char *check = stringList[j];
int k = 0;
while(true){
curList[k] = check;
j+=1;
k+=1;
check = stringList[j];
if(check == NULL || strcmp(check, "|") == 0){
break;
}
}
j+=1;
curList[k] = NULL;
execvp(curList[0], curList);
cout << "Exec error!\n";
exit(1);
}
}
//Piping
//create n-2 pipes
//redirect the output of job i to the write end of pipe i
//redirect the input of job i to the read end of pipe i
for(int i = 0; i < pipes-1; i++){
int pipefd[2];
if(pipe(pipefd) < 0){
cout << "Pipe error!\n";
}
int pid1 = processList[i];
int pid2 = processList[i+1];
if(0 == pid2){
//Child 2
close(pipefd[1]);
dup2(pipefd[0],1);
close(pipefd[0]);
}
if(0 == pid1){
close(pipefd[0]);
dup2(pipefd[1], 0);
close(pipefd[1]);
}
}
//Wait for all jobs to terminate
for(int i = 0; i < pipes; i++){
pid_t pid = processList[i];
waitpid(pid, NULL, 0);
}
}
I have recently started learning how to program in C under Linux and have written the following code to create some processes:
void generate()
{
int pid;
for(int i=1;i<=10;i++)
{
pid = fork();
}
if (pid<0)
{
printf("Error Fork");
exit(1);
}
if(pid == 0)
{
printf("Fiu pid: %d --- Parinte pid: %d\n", getpid(), getppid());
//count ++;
}
if(pid > 0 )
{
printf("Parinte pid: %d\n", getpid());
//count++;
wait();
}
}
The question is: how should i declare/increment the count variable in order to print the total number of processes the function has created?
It's simple. Fork produces a child for each parent. The answer is therefore 2^10 or 1024.
Put a printf after the fork and comment out the other extraneous output. Run as
./a.out | sort | uniq | wc
The output is is 1024.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
void generate()
{
int pid;
for(int i=1;i<=10;i++)
{
pid = fork();
printf("%d\n", getpid());
}
if (pid<0)
{
//printf("Error Fork");
exit(1);
}
if(pid == 0)
{
//printf("Fiu pid: %d --- Parinte pid: %d\n", getpid(), getppid());
//count ++;
}
if(pid > 0 )
{
//printf("Parinte pid: %d\n", getpid());
//count++;
wait(NULL);
}
}
int main(int argc, char *argv[])
{
generate();
return(0);
}
Probably there are better approaches but.. You can append a new line/character to a temp file every time a child is created. Then you just have to count the lines/characters of the file.