Hi,
It is my first post so I want say hello everyone ! What brings me here? I have some trouble with my code.
I want to communicate two programs using pipes.First of all I don't want to use named pipe, just simple dup2(). I have two programs:1) program2.c - want to read from pipes using select (check after 15s if is possibility). I use exec and pass the pipe to argument.
2) program1.c , do a lot but in short - endless loop, waiting for signal, and after signal write to pipe
I know that problem is around the pipe because when I don't use pipe - just simple text file - all work fine. What I get? Information from select - "No communicate so far.." Like select no return any result
I would be grateful for any help
program1.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
sig_atomic_t wyjsc = 0;
int *fd;
void czekaj_czas()
{
struct sigevent evp;
struct itimerspec ts2;
timer_t timer;
int ret2 ;
evp.sigev_value.sival_ptr = &timer;
evp.sigev_notify = SIGEV_SIGNAL;
evp.sigev_signo = SIGALRM;
ret2 = timer_create(CLOCK_MONOTONIC,&evp,&timer);
if(ret2)
perror("Blad funkcji timer_create");
ts2.it_interval.tv_sec = 0;
ts2.it_interval.tv_nsec = 0;
ts2.it_value.tv_sec = 3;
ts2.it_value.tv_nsec = 0;
if(timer_settime(timer,0,&ts2,NULL))
perror("timer_settime");
}
void handler_signal(int signal)
{
sigset_t pending;
int losowy_czas ;
struct timespec ts;
int ret;
char buf[10];
int ret3;
ssize_t ret_out;
int j = 0;
srand((unsigned int) time(NULL));
losowy_czas = rand() % 15 + 5;
ts.tv_nsec=losowy_czas*100000000;
ts.tv_sec=ts.tv_nsec/1000000000;
ts.tv_nsec-=ts.tv_sec*1000000000;
ret = clock_nanosleep(CLOCK_MONOTONIC,0,&ts,NULL);
switch(signal)
{
case SIGUSR1:
wyjsc = 1;
czekaj_czas();
break;
case SIGALRM:
wyjsc = 0;
break;
default:
fprintf(stderr,"Zlapany zly sygnal: %d \n", signal);
return;
}
if(ret)
perror("Funkcja zakonczona, signal dostarczony do procesu");
// fd = open("?", O_RDWR | O_CREAT | O_APPEND); ???
snprintf(buf, 10, "%ld\n", (long) getpid());
while(wyjsc)
{
ret_out = write(fd[0], buf, strlen(buf));
if(ret_out == -1)
perror("blad zapisu do bliku");
}
}
int main(int argc, char *argv[])
{
int i;
long val;
char *endptr;
struct sigaction sa;
if(argc != 2)
{
fprintf(stderr,"Niepoprawna liczba argumetnow procesu P \n");
exit(EXIT_FAILURE);
}
val = strtol(argv[1],&endptr, 0);
if(endptr == argv[1])
{
fprintf(stderr,"Niepoprawny parametr funkcji ! \n");
exit(EXIT_FAILURE);
}
fd = (int *)val; // Can I do like that?
sa.sa_handler = &handler_signal;
sa.sa_flags = SA_RESTART | SA_NODEFER;
//blokowanie wszystkich innych sygnalow
// :sigfillset(&sa.sa_mask);
if(sigaction(SIGUSR1,&sa,NULL) == -1)
{
perror("Nie mozna obsluzyc SIGUSR1");
}
if(sigaction(SIGALRM,&sa,NULL) == -1)
{
perror("Nie mozna obsluzyc SIGALRM");
}
while(1){ }
return;
}
program2.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i ;
pid_t pid;
pid_t pid2;
int val;
char *endptr;
int pipefd[2];
char parametr[32];
if(argc != 2)
{
fprintf(stderr,"Niepoprawna liczba argumetnow procesu P \n");
exit(EXIT_FAILURE);
}
val = strtol(argv[1],&endptr, 0);
if(endptr == argv[1])
{
fprintf(stderr,"Niepoprawny parametr funkcji ! \n");
exit(EXIT_FAILURE);
}
/* pipe
pipe0 - write
pipe1 - read
*/
if(pipe(pipefd) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
sprintf(parametr,"%d",pipefd[0]);
printf("%s \n",parametr);
pid = fork() ;
if(pid < 0)
{
perror("fork!");
}
else if(pid == 0)
{
/* FIRST CHILD !
create all proces in val
*/
for(i = 0;i<val; i++)
{
pid2 = fork();
if(pid2 < 0)
{
perror("Fork");
}
else if(pid2==0)
{
int ret;
/* Child process */
// read
dup2(pipefd[0],STDIN_FILENO); // write
close(pipefd[1]);
ret = execl("program1","program1", parametr,NULL);
if(ret == -1)
perror("Execl");
}
else{
wait(NULL);
}
} /* END OF FOR */
}
else{
/* PARENT */
// select //
fd_set set;
struct timeval timeout;
int sel;
char buf;
close(pipefd[0]) ;
FD_ZERO(&set);
FD_SET(pipefd[1], &set); // READ
timeout.tv_sec = 17;
timeout.tv_usec = 0;
sel = select(FD_SETSIZE,&set,NULL,NULL,&timeout);
if(sel < 0 )
{
perror("Blad funkcji select");
}
else if(sel == 0)
{
printf("Brak komunikatkow \n");
}
else{
// read from pipe -
while(read(pipefd[0], &buf,1) > 0)
write(STDOUT_FILENO, &buf,1);
}
}
}