Mam sobie takiego potworka:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
typedef enum message_t {
EXIT = 0x00000,
LEFT = 0x00001,
RIGHT = 0x00010,
LR_MASK = 0x00011,
/* sender */
PARENT = 0x00100,
CHILD = 0x01000,
LEG = 0x10000,
MASK = 0x11111
} message_t;
#define MSG_S sizeof(message_t)
#define send(TO, MSG) write((TO).fd[1], &(MSG), MSG_S)
/*#define send(TO, MSG) printf("%05x\n", MSG)*/
struct segment_t;
typedef struct leg_t {
int pid;
int fd[2];
struct segment_t *segment;
} leg_t;
typedef struct segment_t {
int pid;
int fd[2];
int id;
leg_t legs[2];
struct segment_t *parent;
} segment_t;
void add_leg(leg_t *leg) {
pipe(leg->fd);
if ((leg->pid = fork()) == -1) {
perror("Cannot fork");
exit(1);
}
if (leg->pid == 0) {
message_t msg;
while (read(leg->fd[0], &msg, MSG_S)) {
msg = (msg & LR_MASK) | LEG;
send(*leg->segment, msg);
}
}
}
void add_segment(segment_t *segment, int counter) {
int childpid;
segment_t next;
if (counter <= 0)
return;
pipe(segment->fd);
if ((segment->pid = fork()) == -1) {
perror("Cannot fork");
exit(1);
}
if (segment->pid == 0) {
segment->legs[0].segment = segment;
segment->legs[1].segment = segment;
add_leg(&segment->legs[0]);
add_leg(&segment->legs[1]);
next.id = segment->id + 1;
next.parent = segment;
add_segment(&next, counter - 1);
int msg = 0;
int ready = TRUE;
while (read(segment->fd[0], &msg, MSG_S)) {
if (msg == (PARENT | LEFT)) {
ready = TRUE;
send(segment->legs[0], msg);
msg ^= LR_MASK;
send(next, msg);
}
if (msg == (PARENT | RIGHT)) {
ready = TRUE;
send(segment->legs[1], msg);
msg ^= LR_MASK;
send(next, msg);
}
if (msg & LEG) {
printf("%s noga z członu %d %s\n", msg & LEFT ? "lewa" : "prawa", segment->id, ready ? "wykonała krok": "potknęła się");
msg = (msg & LR_MASK) | CHILD;
send(*segment->parent, msg);
}
if (msg & CHILD) {
ready = FALSE;
send(*segment->parent, msg);
}
if (msg == EXIT) {
send(next, msg);
kill(segment->legs[0].pid, SIGTERM);
kill(segment->legs[1].pid, SIGTERM);
exit(0);
}
}
}
}
int main(int argc, const char *argv[]) {
int count = 0;
segment_t segment;
segment.id = 1;
if (argc != 2)
exit(3);
sscanf(argv[1], "%d", &count);
add_segment(&segment, count);
message_t msg = PARENT | LEFT;
char c;
while (scanf("%c", &c)) {
if (c == 'k') {
send(segment, msg);
msg ^= LR_MASK;
}
if (c == 'c') {
int msg = EXIT;
send(segment, msg);
return 0;
}
}
return 0;
}
I teraz za każdym razem gdy go odpalam z parametrem 2
wywala mi trochę za dużo. Mianowicie:
lewa noga z członu 1 wykonała krok
prawa noga z członu 1 potknęła się
prawa noga z członu 2 wykonała krok
prawa noga z członu 2 potknęła się
lewa noga z członu 2 potknęła się
Ma ktoś pomysł co jest, źle? Bo ja już zgłupiałem.