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)
38 //fprintf(stderr, "%d\n", o->nCPU);
42 setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL);
44 dup2(fileno(stdout), fileno(stderr)); // yes, this works, apparently
46 slave = (Slave*)(calloc(o->nCPU, sizeof(Slave)));
47 atexit(Slave_cleanup);
50 if (strcmp(o->master_addr, "-") != 0)
55 //log_print(2, "Slave_main", "Using unsecured networking; connect to %s:%d", o->master_addr, o->port);
56 //log_print(2, "Slave_main", "Connecting to %s:%d", o->master_addr, o->port);
57 int net_fd = Network_client(o->master_addr, o->port, 100);
58 dup2(net_fd, fileno(stdin));
59 dup2(net_fd, fileno(stdout));
60 dup2(net_fd, fileno(stderr));
65 o->master_addr = "localhost";
66 //log_print(2, "Slave_main", "Using port forwarding; connect to %s", o->master_addr);
71 fgets(name, sizeof(name), stdin);
72 name[strlen(name)-1] = '\0';
73 //log_print(LOGINFO, "Slave_main", "Started remote swarm \"%s\"", name);
76 fprintf(stdout, "%d\n", o->nCPU);
77 //log_print(2, "Slave_main", "Wrote nCPU %d", o->nCPU);
81 for (int i = 0; i < o->nCPU; ++i)
83 //log_print(2, "Slave_main", "Waiting for port number...");
84 fgets(buffer, sizeof(buffer), stdin);
86 buffer[strlen(buffer)-1] = '\0';
87 sscanf(buffer, "%d", &port);
88 //log_print(2, "Slave_main", "Port number %d", port);
89 slave[i].in = Network_client(o->master_addr, port,20);
90 //log_print(2, "Slave_main", "Connected to %s:%d\n", o->master_addr, port);
91 slave[i].out = slave[i].in;
93 Slave_shell(i, o->shell);
102 void Slave_shell(int i, char * shell)
104 slave[i].pid = fork();
108 if (slave[i].pid == 0)
110 dup2(slave[i].in, fileno(stdin));
111 dup2(slave[i].out, fileno(stdout));
112 //dup2(error_socket[1], fileno(stderr));
114 execlp(shell, shell, NULL);
117 // if the input is a network socket, this message gets sent to the master
118 // which will then echo it back to the socket and hence the shell
119 FILE * f = fdopen(slave[i].in, "w"); setbuf(f, NULL);
120 fprintf(f, "name=\"%s:%d\"\n", name,i);
123 void Slave_loop(Options * o)
130 int p = -1; int s = 0;
135 FD_SET(fileno(stdin), &readSet);
136 p = waitpid(-1, &s, 0);
139 //log_print(0, "Slave_loop", "waitpid : %s", strerror(errno));
143 //log_print(3, "Slave_loop", "Detected child %d exiting...", p);
145 // check for an exit command from the master
146 select(fileno(stdin) + 1, &readSet, NULL, NULL, &tv);
148 if (FD_ISSET(fileno(stdin), &readSet))
150 fgets(buffer, sizeof(buffer), stdin);
151 if (strcmp(buffer, "exit\n") == 0)
153 log_print(2, "Slave_loop", "Received notification of exit.\n");
159 for (i = 0; i < o->nCPU; ++i)
161 if (slave[i].pid == p) break;
164 error("Slave_loop", "No child matches pid %d", p);
166 sigchld_respond(s, name, i);
169 // cancel any tasks at the master for this slave
171 write(slave[i].out, SHELL_OUTPUT_FINISHED, SHELL_OUTPUT_FINISHED_LENGTH);
173 Slave_shell(i, o->shell);
181 for (int i = 0; i < options.nCPU; ++i)
183 kill(slave[i].pid, SIGTERM);
186 for (int i = 0; i < options.nCPU; ++i)
188 kill(slave[i].pid, SIGKILL);