chiark / gitweb /
add udev_rules_run() to handle RUN list
[elogind.git] / udev_utils_run.c
index 31363588c86386da0302779575b879c38c7474dd..69b54f47a79e3400380701ff0dc15433d43da6ec 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * udev_utils_run.c - execute programs from udev and read its output
- *
  * Copyright (C) 2004-2005 Kay Sievers <kay.sievers@vrfy.org>
  *
  *     This program is free software; you can redistribute it and/or modify it
@@ -14,7 +12,7 @@
  * 
  *     You should have received a copy of the GNU General Public License along
  *     with this program; if not, write to the Free Software Foundation, Inc.,
- *     675 Mass Ave, Cambridge, MA 02139, USA.
+ *     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
  */
 
@@ -26,6 +24,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <ctype.h>
+#include <syslog.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <sys/wait.h>
@@ -71,9 +70,8 @@ int pass_env_to_socket(const char *sockname, const char *devpath, const char *ac
 }
 
 int run_program(const char *command, const char *subsystem,
-               char *result, size_t ressize, size_t *reslen, int log)
+               char *result, size_t ressize, size_t *reslen)
 {
-       int retval = 0;
        int status;
        int outpipe[2] = {-1, -1};
        int errpipe[2] = {-1, -1};
@@ -83,17 +81,20 @@ int run_program(const char *command, const char *subsystem,
        char *argv[(sizeof(arg) / 2) + 1];
        int devnull;
        int i;
+       int retval = 0;
 
+       /* build argv from comand */
        strlcpy(arg, command, sizeof(arg));
        i = 0;
-       if (strchr(arg, ' ')) {
+       if (strchr(arg, ' ') != NULL) {
                char *pos = arg;
+
                while (pos != NULL) {
                        if (pos[0] == '\'') {
                                /* don't separate if in apostrophes */
                                pos++;
                                argv[i] = strsep(&pos, "\'");
-                               while (pos && pos[0] == ' ')
+                               while (pos != NULL && pos[0] == ' ')
                                        pos++;
                        } else {
                                argv[i] = strsep(&pos, " ");
@@ -102,22 +103,20 @@ int run_program(const char *command, const char *subsystem,
                        i++;
                }
                argv[i] = NULL;
-               info("'%s'", command);
        } else {
                argv[0] = arg;
-               argv[1] = (char *) subsystem;
-               argv[2] = NULL;
-               info("'%s' '%s'", arg, argv[1]);
+               argv[1] = NULL;
        }
+       info("'%s'", command);
 
        /* prepare pipes from child to parent */
-       if (result || log) {
+       if (result != NULL || udev_log_priority >= LOG_INFO) {
                if (pipe(outpipe) != 0) {
                        err("pipe failed: %s", strerror(errno));
                        return -1;
                }
        }
-       if (log) {
+       if (udev_log_priority >= LOG_INFO) {
                if (pipe(errpipe) != 0) {
                        err("pipe failed: %s", strerror(errno));
                        return -1;
@@ -151,14 +150,22 @@ int run_program(const char *command, const char *subsystem,
                        close(devnull);
                } else
                        err("open /dev/null failed: %s", strerror(errno));
-               if (outpipe[WRITE_END] > 0)
+               if (outpipe[WRITE_END] > 0) {
                        dup2(outpipe[WRITE_END], STDOUT_FILENO);
-               if (errpipe[WRITE_END] > 0)
+                       close(outpipe[WRITE_END]);
+               }
+               if (errpipe[WRITE_END] > 0) {
                        dup2(errpipe[WRITE_END], STDERR_FILENO);
+                       close(errpipe[WRITE_END]);
+               }
                execv(argv[0], argv);
-
-               /* we should never reach this */
-               err("exec of program '%s' failed", argv[0]);
+               if (errno == ENOENT || errno == ENOTDIR) {
+                       /* may be on a filesytem which is not mounted right now */
+                       info("program '%s' not found", argv[0]);
+               } else {
+                       /* other problems */
+                       err("exec of program '%s' failed", argv[0]);
+               }
                _exit(1);
        case -1:
                err("fork of '%s' failed: %s", argv[0], strerror(errno));