23 remove(DAEMON_PID_FILE);
25 remove(DAEMON_BARRIER_FIFO);
38 void Initialise(int argc, char ** argv, Options * o)
42 o->master_addr = NULL;
43 o->shell = "bash"; // choosing other shells seems to not work... for some reason
47 o->port = 4000 + rand() % 1000;
48 o->slavefile = "slaves.swarm";
49 o->dummy_shell = false;
53 o->nCPU = sysconf( _SC_NPROCESSORS_ONLN );
56 o->interactive = true;
59 o->master_pid = getpid();
61 ParseArguments(argc, argv, o);
63 o->endlen = (o->end != NULL) ? strlen(o->end) : 0;
67 FILE * f = fopen(DAEMON_PID_FILE, "r");
71 fscanf(f, "%d", &daemon_pid);
73 if (kill(daemon_pid, 0) != 0)
75 error("Initialise", "There was a daemon [%d] running here, but it's gone for some reason.", daemon_pid);
77 o->daemon_wrapper = true;
82 o->daemon_wrapper = false;
84 if (o->logfile != NULL)
86 if (o->logfile[0] == '+')
87 freopen(o->logfile+1, "a", stderr);
89 freopen(o->logfile, "w", stderr);
94 if (o->outfile != NULL)
96 if (o->outfile[0] == '+')
97 freopen(o->outfile+1, "a", stdout);
99 freopen(o->outfile, "w", stdout);
103 if (o->verbosity >= 3)
105 char buffer[BUFSIZ]; getcwd(buffer, BUFSIZ);
106 char * type = (o->daemon) ? "daemon" : (o->daemon_wrapper) ? "wrapper" : (o->master_addr != NULL) ? "slave" : "interactive";
107 log_print(3, "Initialise", "Directory %s; type of instance: %s", buffer, type);
109 if (o->daemon_wrapper && o->interactive)
111 log_print(1, "Initialise", "There is a daemonised swarm [%d] running in this directory.");
112 log_print(1, "Initialise", "You can only pass commands to the daemon by invoking %s -c [command]", options.program);
113 log_print(1, "Initialise", "Running `swarm -c \"#EXIT#\"' will quit the daemon, unless it is waiting on a BARRIER");
114 error("Initialise", "Can't run an interactive wrapper to a daemon");
119 void ParseArguments(int argc, char ** argv, Options * o)
122 for (int i = 1; i < argc; ++i)
124 if (argv[i][0] == '-' && argv[i][2] == '\0')
131 if (argv[i][1] == 'p')
134 error("ParseArguments", "No argument following %s switch", argv[i]);
135 o->port = atoi(argv[++i]);
137 else if (argv[i][1] == 'n')
140 error("ParseArguments", "No argument following %s switch", argv[i]);
141 o->nCPU = atoi(argv[++i]);
143 else if (argv[i][1] == 'm')
146 error("ParseArguments", "No argument following %s switch", argv[i]);
147 o->master_addr = argv[++i];
149 else if (argv[i][1] == 'c')
153 error("ParseArguments", "No argument following %s switch", argv[i]);
156 error("ParseArguments", "Can't use %s switch in combination with a script", argv[i]);
158 // insert terrible hack here
159 o->interactive = false;
160 FILE * f = fopen(COMMAND_FILE, "a");
161 fprintf(f, "%s\n", argv[++i]);
163 dup2(open(COMMAND_FILE, O_RDONLY), fileno(stdin));
164 atexit(remove_command);
166 else if (argv[i][1] == 's')
169 error("ParseArguments", "No argument following %s switch", argv[i]);
171 o->shell = argv[++i]; // obviously this breaks things
173 else if (argv[i][1] == 'l')
176 error("ParseArguments", "No argument following %s switch", argv[i]);
178 char * l = argv[++i];
179 while (*l != '\0') if (*(l++) == ':') break;
182 o->verbosity = atoi(l);
185 if (argv[i][0] != '\0')
186 o->logfile = argv[i];
189 else if (argv[i][1] == 'o')
192 error("ParseArguments", "No argument following %s switch", argv[i]);
194 o->outfile = argv[++i];
196 else if (argv[i][1] == 'e')
198 else if (argv[i][1] == 'u')
202 fprintf(stderr, "%s : Unrecognised switch \"%s\"\n", argv[0], argv[i]);
206 else if (strcmp(argv[i], "--daemon") == 0)
208 FILE * f = fopen(DAEMON_PID_FILE, "r");
211 int daemon_pid; fscanf(f, "%d\n", &daemon_pid);
214 if (kill(daemon_pid, 0) != 0)
218 log_print(0, "ParseArguments", "It looks like a daemon [%d] failed to exit cleanly. Starting a new daemon.", daemon_pid);
223 error("ParseArguments", "Couldn't determine whether a daemon [%d] was already running : %s", daemon_pid, strerror(errno));
227 error("ParseArguments", "A daemon is already running!");
233 //setbuf(stdout, NULL);
234 //fprintf(stdout, "%d\n", pid);
235 exit(EXIT_SUCCESS); // fork off into daemon
237 atexit(remove_daemon);
239 f = fopen(DAEMON_PID_FILE, "w");
241 error("ParseArguments", "Couldn't open %s : %s", DAEMON_PID_FILE, strerror(errno));
242 fprintf(f, "%d", getpid()); fclose(f);
244 fprintf(stdout, "%d\n", getpid());
245 freopen("/dev/null", "w", stdout);
246 freopen("/dev/null", "w", stderr);
248 mkfifo(DAEMON_FIFO, 0600);
249 mkfifo(DAEMON_BARRIER_FIFO, 0600);
250 freopen(DAEMON_FIFO, "r", stdin);
256 else if (o->interactive)
258 o->interactive = false;
259 dup2(open(argv[i], O_RDONLY), fileno(stdin)); // replace stdin
263 fprintf(stderr, "%s : Usage %s [options] [script]\n", argv[0], argv[0]);
264 fprintf(stderr, "%s : (extra argv[%d] %s)\n", argv[0], i, argv[i]);
271 char * strdup(const char * str)
273 int n = strlen(str) + 1;
274 char * dup = (char*)(calloc(n, sizeof(char)));