This is my code and I'm trying to write a pid in a file, I'm using fprintf but it doesn't work
This is my code :
int write_pid_in_file(struct config *conf, pid_t pid)
{
//conf->global->pid_file = /tmp/HTTPd.pid
FILE *file_opened = fopen(conf->global->pid_file,"w+");
if (!file_opened)
return 2;
printf("%d\n",pid); //check if it's the good pid
fprintf(file_opened, "%d\n",pid);
fclose(file_opened);
return 0;
}
In this function I call the write function and I get the pid from the demone
int daemon_start(struct config *conf)
{
pid_t cpid;
cpid = fork();
if (cpid == -1)
{
perror("fork");
exit(0);
}
write_pid_in_file(conf,cpid);
if (cpid > 0)
{
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
exit(0);
}
serv(conf->vhosts); //infinite loop
return 0;
}
I'm doing this bc later I need to make a function who stop this deamon ^^
Given the code
int daemon_start(struct config *conf)
{
pid_t cpid;
cpid = fork();
if (cpid == -1)
{
perror("fork");
exit(0);
}
write_pid_in_file(conf,cpid); <-- both parent and child will call this
.
.
.
There will be two processes that call write_pid_in_file() - the parent process will write the pid of the child process, and the child process will write 0.
Related
I have picked the following example from APUE :
void daemonize(const char* cmd)
{
int i,fd0,fd1,fd2;
pid_t pid;
struct rlimit r1;
struct sigaction sa;
//clear all file masks
umask(0);
//get max number of file descriptors
if(getrlimit(RLIMIT_NOFILE,&r1) < 0)
{
perror("error getting file descriptor size");
return;
}
//become a session leader
if((pid = fork()) < 0)
{
perror("error forking");
return;
}
else if(pid == 0)
{
setsid();
}
else
{
exit(0); //parent exits
}
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if(sigaction(SIGHUP,&sa,NULL) < 0)
{
return;
}
if((pid = fork()) < 0)
{
return;
}
else if(pid != 0)
{
exit(0); //parent
}
//child continues
syslog(LOG_ERR,"chile continuing with pid : %d",getpid());
//change the working directory
if(chdir("/") < 0)
{
return;
}
if(r1.rlim_max == RLIM_INFINITY)
r1.rlim_max = 1024;
for(i=0;i<r1.rlim_max;i++)
close(i);
//attach the file descriptors to /dev/null
fd0 = open("/dev/null",O_RDWR);
fd1 = dup(0);
fd2 = dup(0);
//initialize the log file
openlog(cmd, LOG_CONS,LOG_DAEMON);
if(fd0!=0 || fd1!=1 || fd2!=2)
{
syslog(LOG_ERR,"unexpected file descriptors %d %d %d\n",fd0,fd1,fd2);
exit(1);
}
}
int main()
{
daemonize("date");
pause(); //how is this working???
}
What I don't understand is how the pause() from the main function is working? What I was expecting is that since we have done exit(0) for the parent process in daemonize(), it should have exited and resulted in the normal termination of the main() process. It should have never returned to the main() and the call to pause() should not even happen. Why it did not terminate and why the pause() got called?
The code forks twice, producing a parent, a child, and a grandchild. The first two each exit(0); the last returns from daemonize.
I have written the below method to fork and execute commands separated by multiple pipes( test with : ls -lrt | grep "check" | wc -l . However it is not resulting in any output, could any one please spot my mistake. Thanks.
void execCmd (pInfo *info)
{
int i, j, k, m;
struct comType *comm, *comm1, *comm2;
if(info->noOfPipes > 2)
{
// DOES NOT WORK
printf("Start\n");
comm=&(info->cArr[0]);
comm2=&(info->cArr[(info->ppNum)-1]);
int fds[2];
pipe(fds);
pid_t pid = fork();
if(pid == -1)
{
perror("fork failed");
exit(1);
}
if(pid == 0)
{
printf("1st child execution here\n");
close(fds[0]);
dup2(fds[1], STDOUT_FILENO);
close(fds[1]);
execvp(comm->cmd,comm->parms);
}
for (k=1;k<=((info->ppNum)-1);k++)
{
printf("For loop executionn number %d",k);
comm1=&(info->cArr[k]);
printf ("comm 1 : %s\n",comm1->cmd);
pid = fork();
if(pid == -1)
{
perror("fork failed");
exit(1);
}
if(pid == 0)
{
//2nd to n-1 child process
dup2(fds[0], STDIN_FILENO);
close(fds[0]);
dup2(fds[1], STDOUT_FILENO);
close(fds[1]);
execvp(comm1->cmd,comm1->parms);
}
wait(NULL);
}
pid = fork();
if(pid == -1)
{
perror("fork failed");
exit(1);
}
if(pid == 0)
{
//nth child process
printf("Last child execution\n");
close(fds[1]);
dup2(fds[0], STDIN_FILENO);
close(fds[0]);
execvp(comm2->cmd,comm2->parms);
}
close(fds[0]);
close(fds[1]);
wait(NULL);
wait(NULL);
}
}
This following code should give you an idea how to implement the pipelining:
#define STDIN 0
#define STDOUT 1
void exec_cmd(struct comType cmd) {
execvp(cmd->cmd, cmd->params);
}
void pipeCmds(struct comType* cmds) {
int fd[cmds_length * 2] = {0};
pid_t pid = 0;
for (int i = 0; i < cmds_length; i++) {
if (pid = fork() == 0) {
//child: make this cmd's output the other cmd's input
pipe(fd + (2*i) );
close(STDOUT);
dup(fd[i]);
if(i > 0) {
close(STDIN);
dup(fd[i-1]);
}
exec_cmd(cmds[i]);
close(fd[i]);
}
}
}
Note that the main idea is that each command is executed in a separate process (via fork) and the output goes to the next command's input rather than to the default stdout(with file descriptor 1), and the same for the input - stdin (file descriptor 0).
I'm writing a program that executes the word count command on the child process. The father process should send a sequence of lines entered by the user trough a pipeline to the child process.
I tried to do this but I ended up with an error.
This is my code:
int main ()
{
int fd[2];
char buff;
int pid;
int pip;
pid = fork();
pip = pipe(fd);
if (pid != 0)
{
pip = pipe(fd);
if (pipe == 0)
{
while (read(fd[0], &buff,1) > 0 )
{
write (fd[1],&buff,1);
}
close(fd[0]);
_exit(0);
}
}
else
{
dup2(fd[1],1);
close(fd[1]);
execlp ("wc","wc",NULL);
_exit(-1);
}
return 0;
}
I've also tried to use dup2 to associate the standard input from the child to the read descriptor of the pipe created by the father process.
But I get this error : wc: standard input: Input/output error.
How can I solve this?
UPDATED (the error is solved but I get an infinite loop)
int main ()
{
int fd[2];
char buff;
int pid;
int pip;
pip = pipe(fd);
if (pip == 0)
{
pid = fork();
if (pid != 0)
{
while (read(fd[0], &buff,1) > 0 )
{
write (fd[1],&buff,1);
}
close(fd[0]);
}
else {
dup2(fd[1],1);
close(fd[1]);
execlp ("wc","wc",NULL);
_exit(-1);
}
}
return 0;
}
#include <unistd.h>
int main ()
{
int fd[2];
char buff;
int pid;
int pip;
int status;
pip = pipe(fd);
if (pip == 0)
{
pid = fork();
if (pid != 0)
{
close(fd[0]);
while (read(0, &buff,1) > 0 )
{
write (fd[1],&buff,1); /* your old loop forwarded internally in the pipe only*/
}
close(fd[1]);
} else {
dup2(fd[0],0); /* you had dup2(fd[1], 1), replacing stdout of wc with the write end from wc */
close(fd[0]);
close(fd[1]);
execlp ("wc","wc",NULL);
_exit(-1);
}
}
wait(&status); /* reap the child process */
return 0;
}
Hello i have such problem
pid_t pid1;
pid_t pid2;
void switch_files(int sig_type)
{
printf("%d %d\n", pid1, pid2);
}
int main(int argc, char **argv)
{
pid_t lpid1,lpid2;
if ((lpid1 = fork()) == 0)
{
signal(SIGUSR1, switch_files);
//Some work
} else {
pid1 = lpid1;
}
if ((lpid2 = fork()) == 0)
{
signal(SIGUSR2, switch_files);
//Some work
} else {
pid2 = lpid2;
}
while(scanf("%s", input) > 0)
{
write(pipe1[1], input, strlen(input) + 1);
kill(pid1, SIGUSR1);
}
waitpid(pid1, 0, 0);
waitpid(pid2, 0, 0);
}
So i need to have value of pid1 and pid2 in my callback for signals, and at printf i have 0 0 but in main i have normal value of pids. How i can fix this, thank you for any help.
If you want the child to have the pid, simply ask for it:
if ((lpid1 = fork()) == 0)
{
pid1 = getpid();
pid2 = -1; // other child doesn't even exist yet
signal(SIGUSR1, switch_files);
//Some work
exit(0); // you don't want the child to go executing parent code, do you?
}
And
if ((lpid2 = fork()) == 0)
{
//pid1 already set with pid of 1st child
pid2 = getpid();
signal(SIGUSR2, switch_files);
//Some work
exit(0); // you don't want the child to go executing parent code, do you?
}
If you need to the 1st child to have the pid of the 2nd child, then you need to use some form of IPC, so you can communicate to the the 1st child after also 2nd child has been started and its pid is known.
If you want the children to have information, you have to communicate that information to them somehow. You can use a file, a pipe, shared memory, or any mechanism you want. But you have to pass the information somehow.
I am trying to learn programming on and I don’t understand why I can't get child 2 to print hello. I have also closed both read and write ends of the pipe for the parent because I don’t want the parent to communicate. Any help is much appreciated.
int main ()
{
int fd[2];
pid_t child_pid, child_pid1;
if (pipe(fd) < 0)
{
printf("Pipe error");
}
child_pid = fork (); // child 1
if (child_pid != 0)
{
printf("im child 1");
dup2 (fd[1], STDIN_FILENO);
printf("greetings");
child_pid1 = fork (); //child 2
if (child_pid1 != 0)
{
printf("im child 2");
dup2(fd[0], STDOUT_FILENO);
printf("hello");
}
else if (child_pid1 > 0) //Parent Code
{
close (fd[0]);
close (fd[1]);
}
}
return 0;
}
Your first if clause is wrong.
child_pid = fork (); // child 1
if (child_pid != 0)
{
printf("im child 1");
}
This is not the child but the parent. If it is the child, then pid will be 0, only on the parent you have child_pid != 0.
The same happens in the second if clause as well.
You should do if(child_pid == 0) in both cases, if you want that code to be executed in the child process.