23 remove(DAEMON_PID_FILE);
25 remove(DAEMON_BARRIER_FIFO);
40 void Initialise(int argc, char ** argv, Options * o)
44 o->master_addr = NULL;
45 o->shell = "bash"; // choosing other shells seems to not work... for some reason
53 o->nCPU = sysconf( _SC_NPROCESSORS_ONLN );
56 o->interactive = true;
58 gethostname(name, sizeof(name));
59 o->name = strdup(name);
61 o->master_pid = getpid();
63 ParseArguments(argc, argv, o);
65 o->endlen = (o->end != NULL) ? strlen(o->end) : 0;
69 FILE * f = fopen(DAEMON_PID_FILE, "r");
73 fscanf(f, "%d", &daemon_pid);
75 if (kill(daemon_pid, 0) != 0)
77 error("Initialise", "There was a daemon [%d] running here, but it's gone for some reason.", daemon_pid);
79 o->daemon_wrapper = true;
84 o->daemon_wrapper = false;
86 if (o->logfile != NULL)
88 if (o->logfile[0] == '+')
89 freopen(o->logfile+1, "a", stderr);
91 freopen(o->logfile, "w", stderr);
96 if (o->outfile != NULL)
98 if (o->outfile[0] == '+')
99 freopen(o->outfile+1, "a", stdout);
101 freopen(o->outfile, "w", stdout);
105 if (o->verbosity >= 3)
107 char buffer[BUFSIZ]; getcwd(buffer, BUFSIZ);
108 char * type = (o->daemon) ? "daemon" : (o->daemon_wrapper) ? "wrapper" : (o->master_addr != NULL) ? "slave" : "interactive";
109 log_print(3, "Initialise", "Directory %s; type of instance: %s", buffer, type);
111 if (o->daemon_wrapper && o->interactive)
113 log_print(1, "Initialise", "There is a daemonised swarm [%d] running in this directory.");
114 log_print(1, "Initialise", "You can only pass commands to the daemon by invoking %s -c [command]", options.program);
115 log_print(1, "Initialise", "Running `swarm -c \"#EXIT#\"' will quit the daemon, unless it is waiting on a BARRIER");
116 error("Initialise", "Can't run an interactive wrapper to a daemon");
121 void ParseArguments(int argc, char ** argv, Options * o)
124 for (int i = 1; i < argc; ++i)
126 if (argv[i][0] == '-' && argv[i][2] == '\0')
133 if (argv[i][1] == 'p')
136 error("ParseArguments", "No argument following %s switch", argv[i]);
137 o->port = atoi(argv[++i]);
139 else if (argv[i][1] == 'n')
142 error("ParseArguments", "No argument following %s switch", argv[i]);
143 o->nCPU = atoi(argv[++i]);
145 else if (argv[i][1] == 'r')
148 error("ParseArguments", "No argument following %s switch", argv[i]);
149 o->master_addr = argv[++i];
150 char * p = strstr(o->master_addr, ":");
157 else if (argv[i][1] == 'c')
161 error("ParseArguments", "No argument following %s switch", argv[i]);
164 error("ParseArguments", "Can't use %s switch in combination with a script", argv[i]);
166 // insert terrible hack here
167 o->interactive = false;
168 FILE * f = fopen(COMMAND_FILE, "a");
169 fprintf(f, "%s\n", argv[++i]);
171 dup2(open(COMMAND_FILE, O_RDONLY), fileno(stdin));
172 atexit(remove_command);
174 else if (argv[i][1] == 's')
177 error("ParseArguments", "No argument following %s switch", argv[i]);
179 o->shell = argv[++i]; // obviously this breaks things
181 else if (argv[i][1] == 'l')
184 error("ParseArguments", "No argument following %s switch", argv[i]);
186 char * l = argv[++i];
187 while (*l != '\0') if (*(l++) == ':') break;
190 o->verbosity = atoi(l);
193 if (argv[i][0] != '\0')
194 o->logfile = argv[i];
197 else if (argv[i][1] == 'o')
200 error("ParseArguments", "No argument following %s switch", argv[i]);
202 o->outfile = argv[++i];
204 else if (argv[i][1] == 'e')
206 else if (argv[i][1] == 'u')
210 fprintf(stderr, "%s : Unrecognised switch \"%s\"\n", argv[0], argv[i]);
214 else if (strcmp(argv[i], "--daemon") == 0)
216 FILE * f = fopen(DAEMON_PID_FILE, "r");
219 int daemon_pid; fscanf(f, "%d\n", &daemon_pid);
222 if (kill(daemon_pid, 0) != 0)
226 log_print(0, "ParseArguments", "It looks like a daemon [%d] failed to exit cleanly. Starting a new daemon.", daemon_pid);
231 error("ParseArguments", "Couldn't determine whether a daemon [%d] was already running : %s", daemon_pid, strerror(errno));
235 error("ParseArguments", "A daemon is already running!");
241 //setbuf(stdout, NULL);
242 //fprintf(stdout, "%d\n", pid);
243 exit(EXIT_SUCCESS); // fork off into daemon
245 atexit(remove_daemon);
247 f = fopen(DAEMON_PID_FILE, "w");
249 error("ParseArguments", "Couldn't open %s : %s", DAEMON_PID_FILE, strerror(errno));
250 fprintf(f, "%d", getpid()); fclose(f);
252 fprintf(stdout, "%d\n", getpid());
253 freopen("/dev/null", "w", stdout);
254 freopen("/dev/null", "w", stderr);
256 mkfifo(DAEMON_FIFO, 0600);
257 mkfifo(DAEMON_BARRIER_FIFO, 0600);
258 freopen(DAEMON_FIFO, "r", stdin);
264 else if (o->interactive)
266 o->interactive = false;
267 dup2(open(argv[i], O_RDONLY), fileno(stdin)); // replace stdin
271 fprintf(stderr, "%s : Usage %s [options] [script]\n", argv[0], argv[0]);
272 fprintf(stderr, "%s : (extra argv[%d] %s)\n", argv[0], i, argv[i]);
279 char * strdup(const char * str)
281 int n = strlen(str) + 1;
282 char * dup = (char*)(calloc(n, sizeof(char)));