1 #define _XOPEN_SOURCE 700
21 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <netinet/tcp.h>
32 void Slave_shell(int i, char * shell);
36 void Slave_main(Options * o)
40 setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL);
42 dup2(fileno(stdout), fileno(stderr)); // yes, this works, apparently
44 slave = (Slave*)(calloc(o->nCPU, sizeof(slave)));
45 atexit(Slave_cleanup);
48 if (strcmp(o->master_addr, "-") != 0)
53 //log_print(2, "Slave_main", "Using unsecured networking; connect to %s:%d", o->master_addr, o->port);
54 //log_print(2, "Slave_main", "Connecting to %s:%d", o->master_addr, o->port);
55 int net_fd = Network_client(o->master_addr, o->port, 100);
56 dup2(net_fd, fileno(stdin));
57 dup2(net_fd, fileno(stdout));
58 dup2(net_fd, fileno(stderr));
63 o->master_addr = "localhost";
64 //log_print(2, "Slave_main", "Using port forwarding; connect to %s", o->master_addr);
69 fgets(name, sizeof(name), stdin);
70 name[strlen(name)-1] = '\0';
71 //log_print(2, "Slave_main", "Got name %s", name);
73 fprintf(stdout, "%d\n", o->nCPU);
74 //log_print(2, "Slave_main", "Wrote nCPU %d", o->nCPU);
78 for (int i = 0; i < o->nCPU; ++i)
80 //log_print(2, "Slave_main", "Waiting for port number...");
81 fgets(buffer, sizeof(buffer), stdin);
83 buffer[strlen(buffer)-1] = '\0';
84 sscanf(buffer, "%d", &port);
85 //log_print(2, "Slave_main", "Port number %d", port);
86 slave[i].in = Network_client(o->master_addr, port,20);
87 //log_print(2, "Slave_main", "Connected to %s:%d\n", o->master_addr, port);
88 slave[i].out = slave[i].in;
90 Slave_shell(i, o->shell);
99 void Slave_shell(int i, char * shell)
101 slave[i].pid = fork();
105 if (slave[i].pid == 0)
107 dup2(slave[i].in, fileno(stdin));
108 dup2(slave[i].out, fileno(stdout));
109 //dup2(error_socket[1], fileno(stderr));
111 execlp(shell, shell, NULL);
114 // if the input is a network socket, this message gets sent to the master
115 // which will then echo it back to the socket and hence the shell
116 FILE * f = fdopen(slave[i].in, "w"); setbuf(f, NULL);
117 fprintf(f, "name=\"%s:%d\"\n", name,i);
120 void Slave_loop(Options * o)
127 int p = -1; int s = 0;
132 FD_SET(fileno(stdin), &readSet);
133 p = waitpid(-1, &s, 0);
136 //log_print(0, "Slave_loop", "waitpid : %s", strerror(errno));
140 //log_print(3, "Slave_loop", "Detected child %d exiting...", p);
142 // check for an exit command from the master
143 select(fileno(stdin) + 1, &readSet, NULL, NULL, &tv);
145 if (FD_ISSET(fileno(stdin), &readSet))
147 fgets(buffer, sizeof(buffer), stdin);
148 if (strcmp(buffer, "exit\n") == 0)
150 log_print(2, "Slave_loop", "Received notification of exit.\n");
156 for (i = 0; i < o->nCPU; ++i)
158 if (slave[i].pid == p) break;
161 error("Slave_loop", "No child matches pid %d", p);
165 fprintf(stderr,"Unexpected exit of slave %s:%d", name, i);
168 int sig = WTERMSIG(s);
169 fprintf(stderr," due to %s", strsignal(sig));
172 fprintf(stderr," - %s committing suicide\n", name);
178 fprintf(stderr," return code %d.", s);
182 // cancel any tasks at the master for this slave
185 len = strlen(o->end);
186 write(slave[i].out, o->end, len);
188 Slave_shell(i, o->shell);
196 for (int i = 0; i < options.nCPU; ++i)
198 kill(slave[i].pid, SIGTERM);
201 for (int i = 0; i < options.nCPU; ++i)
203 kill(slave[i].pid, SIGKILL);