Fix incorrect use of variable arguments in run_parts() and simplify code

The run_parts() implementation used variable arguments in a bad way,
resulting in it not working properly.  Replaced va_*() code with a
simple cmd argument that's passed to each script called.

Also, the opendir()/readdir() code has been replaced with scandir()
using regular alphasort(). This simplifies the code somewhat as well.

Otherwise, minor cleanups.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2012-10-06 15:45:42 +02:00
1 parent af59174e49
commit f29d2733c7
7 files changed
+46 -64

No files matched your search

+1 -1
View File
@@ -185,7 +185,7 @@ int main(int UNUSED(args), char *argv[])
*/ */
if (rcsd && fisdir(rcsd)) { if (rcsd && fisdir(rcsd)) {
_d("Running startup scripts in %s ...", rcsd); _d("Running startup scripts in %s ...", rcsd);
run_parts(rcsd); run_parts(rcsd, NULL);
} }
/* /*
+36 -56
View File
@@ -566,81 +566,61 @@ pid_t run_getty(char *cmd, char *argv[])
return pid; return pid;
} }
static int cmp(const void *s1, const void *s2) int run_parts(char *dir, char *cmd)
{ {
return strcmp(*(char **)s1, *(char **)s2); struct dirent **e;
} int i, num;
int run_parts(char *dir, ...) num = scandir(dir, &e, NULL, alphasort);
{ if (num < 0) {
DIR *d; _d("No files found in %s, skipping ...", dir);
struct dirent *e;
struct stat st;
char *oldpwd = NULL;
char *ent[NUM_SCRIPTS];
int i, num = 0, argnum = 1;
char *args[NUM_ARGS];
va_list ap;
oldpwd = getcwd (NULL, 0);
if (chdir(dir)) {
if (oldpwd) free(oldpwd);
return -1; return -1;
} }
if ((d = opendir(dir)) == NULL) {
if (oldpwd) free(oldpwd);
return -1;
}
va_start(ap, dir);
while (argnum < NUM_ARGS && (args[argnum++] = va_arg(ap, char *)));
va_end(ap);
while ((e = readdir(d))) {
if (e->d_type == DT_REG && stat(e->d_name, &st) == 0) {
_d("Found %s/%s ...", dir, e->d_name);
if (st.st_mode & S_IXUSR) {
ent[num++] = strdup(e->d_name);
if (num >= NUM_SCRIPTS)
break;
}
}
}
closedir(d);
if (num == 0) {
if (oldpwd) free(oldpwd);
return 0;
}
qsort(ent, num, sizeof(char *), cmp);
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
int j = 0, status; int j = 0, status;
pid_t pid = 0; pid_t pid = 0;
mode_t mode;
char *args[NUM_ARGS];
char *name = e[i]->d_name;
char path[CMD_SIZE];
args[j++] = ent[i]; snprintf(path, sizeof(path), "%s/%s", dir, name);
/* Check if S<NUM>service or K<NUM>service notation is used */ mode = fmode(path);
if (ent[i][0] == 'S' && isdigit(ent[i][1])) { if (!S_ISEXEC(mode) || S_ISDIR(mode)) {
args[j++] = "start"; _d("Skipping %s ...", path);
} else if (ent[i][0] == 'K' && isdigit(ent[i][1])) { continue;
args[j++] = "stop"; }
/* Fill in args[], starting with full path to executable */
args[j++] = path;
/* If the callee didn't supply a run_parts() argument */
if (!cmd) {
/* Check if S<NUM>service or K<NUM>service notation is used */
_d("Checking if %s is a sysvinit startstop script ...", name);
if (name[0] == 'S' && isdigit(name[1])) {
args[j++] = "start";
} else if (name[0] == 'K' && isdigit(name[1])) {
args[j++] = "stop";
}
} else {
args[j++] = cmd;
} }
args[j++] = NULL; args[j++] = NULL;
pid = fork(); pid = fork();
if (!pid) { if (!pid) {
_d("Calling %s ...", ent[i]); _d("Calling %s ...", path);
execv(ent[i], args); execv(path, args);
exit(0); exit(0);
} }
waitpid(pid, &status, 0); waitpid(pid, &status, 0);
free(ent[i]);
} }
chdir(oldpwd); while (num--)
free(oldpwd); free(e[num]);
free(e);
return 0; return 0;
} }
+4 -2
View File
@@ -50,7 +50,9 @@
#ifndef blkdev #ifndef blkdev
# define blkdev(x,m,maj,min) mknod((x), S_IFBLK|(m), makedev((maj),(min))) # define blkdev(x,m,maj,min) mknod((x), S_IFBLK|(m), makedev((maj),(min)))
#endif #endif
#ifndef S_ISEXEC
# define S_ISEXEC(m) (((m) & S_IXUSR) == S_IXUSR)
#endif
#ifndef UNUSED #ifndef UNUSED
#define UNUSED(x) UNUSED_ ## x __attribute__ ((unused)) #define UNUSED(x) UNUSED_ ## x __attribute__ ((unused))
#endif #endif
@@ -87,7 +89,7 @@ void set_hostname (char *hostname);
int run (char *cmd); int run (char *cmd);
int run_interactive (char *cmd, char *fmt, ...); int run_interactive (char *cmd, char *fmt, ...);
pid_t run_getty (char *cmd, char *argv[]); pid_t run_getty (char *cmd, char *argv[]);
int run_parts (char *dir, ...); int run_parts (char *dir, char *cmd);
/* strlcpy.c */ /* strlcpy.c */
size_t strlcpy(char *dst, const char *src, size_t siz); size_t strlcpy(char *dst, const char *src, size_t siz);
+1 -1
View File
@@ -39,7 +39,7 @@ mode_t fmode(char *file)
if (!file) { if (!file) {
errno = EINVAL; errno = EINVAL;
return 0; /* Doesn't exist ... */ return 0;
} }
if (!stat(file, &sb)) if (!stat(file, &sb))
+2 -2
View File
@@ -161,7 +161,7 @@ plugin_t *plugin_find(char *name)
if (name[0] != '/') { if (name[0] != '/') {
int noext; int noext;
char path[256]; char path[CMD_SIZE];
noext = strcmp(name + strlen(name) - 3, ".so"); noext = strcmp(name + strlen(name) - 3, ".so");
snprintf (path, sizeof(path), "%s%s%s%s", plugpath, snprintf (path, sizeof(path), "%s%s%s%s", plugpath,
@@ -262,7 +262,7 @@ static void init_plugins(void)
static int load_one(char *path, char *name) static int load_one(char *path, char *name)
{ {
int noext; int noext;
char plugin[256]; char plugin[CMD_SIZE];
void *handle; void *handle;
if (!path || !fisdir(path) || !name) { if (!path || !fisdir(path) || !name) {
+1 -1
View File
@@ -59,7 +59,7 @@ static void setup(void *UNUSED(arg))
touch("/etc/resolvconf/run/enable-updates"); touch("/etc/resolvconf/run/enable-updates");
chdir("/etc/resolvconf/run/interface"); chdir("/etc/resolvconf/run/interface");
run_parts("/etc/resolvconf/update.d", "-i", NULL); run_parts("/etc/resolvconf/update.d", "-i");
chdir("/"); chdir("/");
#endif /* USE_ETC_RESOLVCONF_RUN */ #endif /* USE_ETC_RESOLVCONF_RUN */
} }
+1 -1
View File
@@ -325,7 +325,7 @@ int svc_start(svc_t *svc)
if (debug) { if (debug) {
int fd; int fd;
char buf[256] = ""; char buf[CMD_SIZE] = "";
fd = open (CONSOLE, O_WRONLY | O_APPEND); fd = open (CONSOLE, O_WRONLY | O_APPEND);
if (-1 != fd) { if (-1 != fd) {