about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--nitro.c35
2 files changed, 24 insertions, 13 deletions
diff --git a/README.md b/README.md
index 78a2fd0..c721d63 100644
--- a/README.md
+++ b/README.md
@@ -50,6 +50,8 @@ can contain several files:
   of `run` is connected to the standard input by a pipe.
 - `down`, an optional file that causes nitro to not bring up this
   service by default.
+- Service directories ending with '@' are ignored; they can be used
+  for parameterized services.
 
 You may find runit's `chpst` useful when writing `run` scripts.
 
diff --git a/nitro.c b/nitro.c
index 1718832..abe9989 100644
--- a/nitro.c
+++ b/nitro.c
@@ -259,12 +259,28 @@ stat_slash_to_at(const char *dir, const char *name, struct stat *st)
 	char *instance = strchr(dir, '@');
 	if (instance)
 		*instance = 0;
-	sprn(buf, buf + sizeof buf, "%s/%s", dir, name);
+	sprn(buf, buf + sizeof buf, "%s%s/%s", dir, "@"+!instance, name);
 	if (instance)
 		*instance = '@';
 	return stat(buf, st);
 }
 
+static char *
+chdir_at(char *dir)
+{
+	char *instance = strchr(dir, '@');
+	char s = 0;
+	if (instance) {
+		instance++;
+		s = *instance;
+		*instance = 0;
+	}
+	chdir(dir);
+	if (instance)
+		*instance = s;
+	return instance;
+}
+
 void process_step(int i, enum process_events ev);
 void notify(int);
 
@@ -293,10 +309,7 @@ proc_launch(int i)
 
 	pid_t child = fork();
 	if (child == 0) {
-		char *instance = strchr(services[i].name, '@');
-		if (instance)
-			*instance++ = 0;
-		chdir(services[i].name);
+		char *instance = chdir_at(services[i].name);
 
 		setsid();
 
@@ -366,10 +379,7 @@ proc_setup(int i)
 
 	pid_t child = fork();
 	if (child == 0) {
-		char *instance = strchr(services[i].name, '@');
-		if (instance)
-			*instance++ = 0;
-		chdir(services[i].name);
+		char *instance = chdir_at(services[i].name);
 
 		setsid();
 
@@ -438,10 +448,7 @@ proc_finish(int i)
 
 	pid_t child = fork();
 	if (child == 0) {
-		char *instance = strchr(services[i].name, '@');
-		if (instance)
-			*instance++ = 0;
-		chdir(services[i].name);
+		char *instance = chdir_at(services[i].name);
 
 		dup2(nullfd, 0);
 		if (services[i].logpipe[1] != -1)
@@ -837,6 +844,8 @@ rescan(int first)
 			continue;
 		if (!S_ISDIR(st.st_mode))
 			continue;
+		if (name[strlen(name) - 1] == '@')
+			continue;
 
 		// ignore magic bootup/shutdown service
 		if (strcmp(name, "SYS") == 0)