I have an assignment to do which requires me to use fork(), wait and execv(). However, every time I try to use them I get an error that they aren't defined. Here is my code:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
fork();
printf("Hello world!\n");
return 0;
}
Here is the errors I get:
I would appreciate it if anyone could help.
Related
i am struggling and your input would be really appreciated. i'm trying to chain arguments to the command line using exec and an array to hold the arguments. the problem comes when I try to chain more than one command. tried using an ";" to separate each command but that does not seem to be working.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>enter code here
int main(){
int proc1 = fork();
char*myargv[16];
myargv[0]="/bin/ls";
myargv[1]="-F;";
myargv[2]="pwd";
myargv[3]=NULL;
if(proc1==0){
execve(myargv[0],myargv,NULL);
exit(1);
}else{
wait(NULL);
printf("This wlways last");
}
return 0;
}
The getpid() gives me PID of a process. But now I want to find the PID using the execlp() command and also print the PID. But I am unable to solve it. Help.
#include <stdio.h> //my code so far
#include <unistd.h>
#include <sys/types.h>
int main()
{
execlp("/usr/include","/usr/include",getpid(),(char *)0);
}
I think your missing a step in your design. You are trying to use execlp() to call a library function getpid() and this just won't work. If you need to get the PID of the process through a call to execlp() then you need a program to call.
So start by creating a simple program that prints out its PID:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
printf( "%s %d\n", argv[1], getpid()) ;
}
Call this printpid.c and compile it to an executable called printpid. Then you can have a program that does this:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
pid_t pid = fork() ;
if ( pid == 0 )
{
execlp("./printpid", "printpid", "child", (char *)0) ;
} else {
execlp("./printpid", "printpid", "parent", (char *)0) ;
}
return 0 ;
}
Compile this to be an executable called forkprocess say and make sure that it and the printpid program are in the same directory. When you run forkprocess it runs printpid twice and printpid displays the PID of the process. To make it clear what is going on I'm passing a parameter to printpid to show if it's being called from the parent process or the child process created by the call to fork().
I am trying to understand processes in C. I currently want to create shell-like structure which - after pressing a shortcut like Ctrl+C or Ctrl+Z will kill all its subprocesses but will stay alive. My code looks like this:
#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/signal.h>
pid_t pid;
void send_signal(int signum){
kill(pid, signum);
}
void init_signals(){
signal(SIGINT, send_signal);
signal(SIGTSTP, send_signal);
}
int main(){
init_signals();
pid = fork();
if(pid > 0){
//Parent Process
wait(NULL);
} else {
// Child Process
while(1){
usleep(300000);
}
}
return 0;
}
Problem here is that, when I press Ctrl+C, parent redirects it to child and kills it but when I press Ctrl+Z (even though child process is stopped) parent still hangs on wait(NULL). Any suggestions on how to fix this?
You can check here how to use wait in C . Long story short:
The wait system-call puts the process to sleep and waits for a child-process to end. It then fills in the argument with the exit code of the child-process (if the argument is not NULL).
wait doesn't get signaled until the child process ends, so just by sending the child to sleep there is no reason for the main process to continue. If you want any setup where the main process still works while the child does as well (including when it sleeps!) you can't wait on the child.
Wouldn't make sense for a shell either - it's always active in the background. Instead you need a better handler on main - like waiting on a condition. That way, when sending a child to sleep, you can signal the condition and keep going.
Apart from the solution at https://stackoverflow.com/a/49346549/5694959 I would like to suggest one more solution as to handle signals for parent process only.This way parent will execute signal handler and default action will be performed for child process. Use waitpid() to get the status of child.
waitpid(pid, NULL, WUNTRACED);
Now parent will resume its execution when child process changes its state i.e. either terminated or stopped.
Update your code as follows:
#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/signal.h>
pid_t pid;
void send_signal(int signum){
kill(pid, signum);
}
void init_signals(){
signal(SIGINT, send_signal);
signal(SIGTSTP, send_signal);
}
int main(){
pid = fork();
if(pid > 0){
//Parent Process
init_signals();
waitpid(pid, NULL, WUNTRACED);
printf("I think this is what you are expecting...\n");
} else {
// Child Process
while(1){
usleep(300000);
}
}
return 0;
}
Just one thing to keep in mind that please make sure that parent process
has handled signal before you press ctrl + c or ctrl + z otherwise, default action of signal will be performed for parent as well.
I serached it but i can't find anything i am looking for. Can anyone give a simple example how to pause for a while (not for given time, like sleep()) and proceed programme ? I tried something but it just pause, and then the only thing i can do is to terminate the program before the second printf:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include<termios.h>
#include<signal.h>
#include <sys/wait.h>
struct sigaction act;
sigset_t to_start, to_stop;
int main(int argc, char *argv[])
{
int i=0;
printf("BEFORE SIGSUSPEND");
sigemptyset(&to_stop);
sigsuspend(&to_stop);
printf("AFTER SIGSUSPEND");
fflush(stdout)
return 0;
}
Your child process should start with the signal you want to send
blocked.
Then you need to make sure:
a delivery of the signal won't kill the process (=> you need to set up a signal handler for it (an empty one will do))
the signal can be delivered (=> sigsuspend will do that)
In code:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void handler(int X) { }
int main(void)
{
sigset_t to_stop;
sigemptyset(&to_stop);
sigaction(SIGINT /*you'd probably use SIGUSR1 here*/,
&(struct sigaction){ .sa_handler = handler }, 0);
puts("BEFORE");
/*SIGINT will now wake up the process without killing it*/
sigsuspend(&to_stop);
puts("AFTER");
}
You should be able to try this out with Ctrl+C. In real code, you probably should be using SIGUSR1/SIGUSR1 or one of the realtime signals for this.
I am new to Linux. I am trying to use waitid() to wait for a child process.
When I try to compile a file including the following lines using gcc:
id_t cpid = fork();
siginfo_t status;
waitid(P_PID, cpid, &status, WEXITED);
The following error was generated:
error: ‘P_PID’ undeclared (first use in this function)
I included the following libraries:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <time.h>
Did I miss something?
Another question is that how can I use WIFSIGNALED() to retrieve information from type siginfo_t?
You need to include <sys/wait.h> and define _XOPEN_SOURCE, as documented in the manual.
The WIFSIGNALED macro must be used with the integer status obtained from wait, waitpid or waitid. In the case of waitpid, the status is available as the si_status member of the siginfo_t structure. In other words, you would use WIFSIGNALED(info.si_status), info being a structure of type siginfo_t whose address you previously passed to waitid().