#include <errno.h>
#include <dirent.h>
#include <fnmatch.h>
+#include <time.h>
#include "udev.h"
unsigned int value_off;
union {
unsigned int attr_off;
- int ignore_error;
+ int devlink_unique;
+ int fail_on_error;
unsigned int rule_goto;
mode_t mode;
uid_t uid;
char *line;
envp = udev_device_get_properties_envp(dev);
- if (util_run_program(udev, program, envp, result, sizeof(result), &reslen) != 0)
+ if (util_run_program(udev, program, envp, result, sizeof(result), &reslen, NULL) != 0)
return -1;
line = result;
dbg(udev, "will wait %i sec for '%s'\n", timeout, file);
while (--loop) {
+ const struct timespec duration = { 0, 1000 * 1000 * 1000 / WAIT_LOOP_PER_SECOND };
+
/* lookup file */
if (stat(file, &stats) == 0) {
info(udev, "file '%s' appeared after %i loops\n", file, (timeout * WAIT_LOOP_PER_SECOND) - loop-1);
return -2;
}
info(udev, "wait for '%s' for %i mseconds\n", file, 1000 / WAIT_LOOP_PER_SECOND);
- usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND);
+ nanosleep(&duration, NULL);
}
info(udev, "waiting for '%s' failed\n", file);
return -1;
char *temp;
linepos = *line;
- if (linepos == NULL && linepos[0] == '\0')
+ if (linepos == NULL || linepos[0] == '\0')
return -1;
/* skip whitespace */
case TK_A_GROUP:
case TK_A_MODE:
case TK_A_NAME:
- case TK_A_DEVLINK:
case TK_A_GOTO:
token->key.value_off = add_string(rule_tmp->rules, value);
break;
token->key.value_off = add_string(rule_tmp->rules, value);
token->key.attr_off = add_string(rule_tmp->rules, attr);
break;
+ case TK_A_DEVLINK:
+ token->key.value_off = add_string(rule_tmp->rules, value);
+ token->key.devlink_unique = *(int *)data;
+ break;
case TK_M_TEST:
token->key.value_off = add_string(rule_tmp->rules, value);
if (data != NULL)
break;
case TK_A_RUN:
token->key.value_off = add_string(rule_tmp->rules, value);
- token->key.ignore_error = *(int *)data;
+ token->key.fail_on_error = *(int *)data;
break;
case TK_A_INOTIFY_WATCH:
case TK_A_NUM_FAKE_PART:
for (i = 0; i < rule_tmp->token_cur; i++) {
enum token_type next_val = TK_UNSET;
- unsigned int next_idx;
+ unsigned int next_idx = 0;
unsigned int j;
/* find smallest value */
} else {
if (value[0] == '\0')
info(rules->udev, "name empty, node creation suppressed\n");
+ else if (strcmp(value, "%k") == 0)
+ err(rules->udev, "NAME=\"%%k\" is superfluous and breaks "
+ "kernel supplied names, please remove it from %s:%u\n", filename, lineno);
rule_add_key(&rule_tmp, TK_A_NAME, op, value, NULL);
attr = get_key_attribute(rules->udev, key + sizeof("NAME")-1);
if (attr != NULL) {
continue;
}
- if (strcmp(key, "SYMLINK") == 0) {
- if (op < OP_MATCH_MAX)
+ if (strncmp(key, "SYMLINK", sizeof("SYMLINK")-1) == 0) {
+ if (op < OP_MATCH_MAX) {
rule_add_key(&rule_tmp, TK_M_DEVLINK, op, value, NULL);
- else
- rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, NULL);
+ } else {
+ int flag = 0;
+
+ attr = get_key_attribute(rules->udev, key + sizeof("SYMLINK")-1);
+ if (attr != NULL && strstr(attr, "unique") != NULL)
+ flag = 1;
+ rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, &flag);
+ }
rule_tmp.rule.rule.flags = 1;
continue;
}
first_token = rules->token_cur;
- while(fgets(line, sizeof(line), f) != NULL) {
+ while (fgets(line, sizeof(line), f) != NULL) {
char *key;
size_t len;
while (line[len-2] == '\\') {
if (fgets(&line[len-2], (sizeof(line)-len)+2, f) == NULL)
break;
+ if (strlen(&line[len-2]) < 2)
+ break;
line_nr++;
len = strlen(line);
}
if (stat(filename, &statbuf) == 0 && statbuf.st_size > 0)
parse_file(rules, filename, filename_off);
else
- info(udev, "can not read '%s'\n", filename);
+ err(udev, "can not read '%s'\n", filename);
udev_list_entry_delete(file_loop);
}
program,
&rules->buf[rule->rule.filename_off],
rule->rule.filename_line);
- if (util_run_program(event->udev, program, envp, result, sizeof(result), NULL) != 0) {
+ if (util_run_program(event->udev, program, envp, result, sizeof(result), NULL, NULL) != 0) {
if (cur->key.op != OP_NOMATCH)
goto nomatch;
} else {
while (isspace(pos[0]))
pos++;
next = strchr(pos, ' ');
- while (next) {
+ while (next != NULL) {
next[0] = '\0';
- info(event->udev, "LINK '%s' %s:%u\n",
- pos,
- &rules->buf[rule->rule.filename_off],
- rule->rule.filename_line);
+ info(event->udev, "LINK '%s' %s:%u\n", pos,
+ &rules->buf[rule->rule.filename_off], rule->rule.filename_line);
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(event->udev), "/", pos, NULL);
- udev_device_add_devlink(event->dev, filename);
+ udev_device_add_devlink(event->dev, filename, cur->key.devlink_unique);
while (isspace(next[1]))
next++;
pos = &next[1];
next = strchr(pos, ' ');
}
if (pos[0] != '\0') {
- info(event->udev, "LINK '%s' %s:%u\n",
- pos,
- &rules->buf[rule->rule.filename_off],
- rule->rule.filename_line);
+ info(event->udev, "LINK '%s' %s:%u\n", pos,
+ &rules->buf[rule->rule.filename_off], rule->rule.filename_line);
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(event->udev), "/", pos, NULL);
- udev_device_add_devlink(event->dev, filename);
+ udev_device_add_devlink(event->dev, filename, cur->key.devlink_unique);
}
}
break;
rule->rule.filename_line);
list_entry = udev_list_entry_add(event->udev, &event->run_list,
&rules->buf[cur->key.value_off], NULL, 1, 0);
- if (cur->key.ignore_error)
+ if (cur->key.fail_on_error)
udev_list_entry_set_flag(list_entry, 1);
break;
}