Reputation: 1
I am trying to fork a child process put him in sleep and wake him up whenever the user enter a line of text to print number of lines entered.
My code is working fine. But weird thing I found is I have to user two gets(str) statement if I didn't the user will be prompted for 1 time only.
if run the code and comment one gets(str) you will know what I mean.
Your help is appreciated. Thanks
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <wait.h>
#include <unistd.h>
#include <signal.h>
main () {
int n;
char ch;
pid_t child;
int erret;
char str[20];
int c = 0;
if ((child = fork ()) < 0) {
perror ("fork");
exit (0);
}
else {
//waitpid(child,NULL,0);
do {
waitpid (child, NULL, 0);
printf ("Enter a line(s) \n");
//funn();
//fflush(stdin);
//scanf("%d",&n);
gets (str);
gets (str);
erret = kill (child, SIGCHLD);
printf ("Signal %d\n", erret);
if (erret >= 0) {
c++;
printf ("You have entered : %d line(s)\n", c);
//pause();
//waitpid(child,NULL,0);
}
else {
kill (child, SIGKILL);
exit (0);
}
printf ("\nPress 9 to exit :");
fflush (stdin);
scanf ("%d", &n);
fflush (stdin);
} while (n != 9);
kill (child, SIGKILL);
}
}
Upvotes: 0
Views: 76
Reputation: 1884
Your concept is flawed, you're forking with out specifying what the parant and child does. So you have a race conditon on gets
. This is because after the fork
call two copies of the code is run, one copy by the parent and one copy by the child. So the fix is to add a swich
or else if
statement to separate your code into sections for the child and parent. BTW as already stated use fgets
switch(fork()):
case -1:
//Error
case 0:
// Child code
default:
// Parant code
Upvotes: 1
Reputation: 84551
There are a number of ways to get repetitive string input as you are trying to do. One of the standard approaches is to gather input until the user signals EOF
signifying there is no more data to enter. (On Linux EOF
is generated from the terminal with ctrl + d
). Without changing your logic and without commenting on your fork, waitpid, etc..
implementation, the following is one way to handle gathering string input for your program until the users sends an EOF
by pressing ctrl+d
on the keyboard:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <wait.h>
#include <unistd.h>
#include <signal.h>
int main () {
pid_t child;
int erret;
int c = 0;
ssize_t nread = 0; /* number of chars read by getline */
char *lineptr = NULL; /* string read by (NULL forces getline to allocate) */
size_t nbytes = 0; /* number of bytes to read (ignored with lineptr = NULL) */
if ((child = fork ()) < 0) {
perror ("fork");
exit (0);
}
else
{
waitpid (child, NULL, 0);
printf ("\nEnter line(s) of text (ctrl+d to exit):\n\n");
while (printf (" Input: ") && (nread = getline (&lineptr, &nbytes, stdin) != -1))
{
erret = kill (child, SIGCHLD);
printf ("\n Signal %d\n", erret);
if (erret >= 0) {
c++;
printf (" You have entered : %d line(s)\n\n", c);
}
else
{
kill (child, SIGKILL);
exit (0);
}
}
kill (child, SIGKILL);
}
return 0;
}
output:
$ ./bin/ind2
Enter line(s) of text (ctrl+d to exit):
Input: line one
Signal 0
You have entered : 1 line(s)
Input: line 2
Signal 0
You have entered : 2 line(s)
Input: line 3
Signal 0
You have entered : 3 line(s)
Input: Killed
Upvotes: 0