X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=udev_lib.c;h=7fb45f0b5fb6b6549de364d3a6357e30abb518e2;hp=e9c16c863a3407ac0705923c375b8264441b3f39;hb=2b41e68a08548ce44b4d145900dab2bb04cd34f7;hpb=4a539daf1e5daa17b52239478d97f8dc7a6506b6 diff --git a/udev_lib.c b/udev_lib.c index e9c16c863..7fb45f0b5 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -29,7 +29,6 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" #include "udev.h" #include "logging.h" #include "udev_lib.h" @@ -58,15 +57,15 @@ char *get_devpath(void) return devpath; } -char *get_devnode(void) +char *get_devname(void) { - char *devnode; + char *devname; - devnode = getenv("DEVNODE"); - if (devnode != NULL && strlen(devnode) > NAME_SIZE) - devnode[NAME_SIZE-1] = '\0'; + devname = getenv("DEVNAME"); + if (devname != NULL && strlen(devname) > NAME_SIZE) + devname[NAME_SIZE-1] = '\0'; - return devnode; + return devname; } char *get_seqnum(void) @@ -86,22 +85,68 @@ char *get_subsystem(char *subsystem) return subsystem; } +#define BLOCK_PATH "/block/" +#define CLASS_PATH "/class/" +#define NET_PATH "/class/net/" + char get_device_type(const char *path, const char *subsystem) { - if (strcmp(subsystem, "block") == 0 || - strstr(path, "/block/") != NULL) + if (strcmp(subsystem, "block") == 0) return 'b'; - if (strcmp(subsystem, "net") == 0 || - strstr(path, "/class/net/") != NULL) + if (strcmp(subsystem, "net") == 0) return 'n'; - if (strstr(path, "/class/") != NULL) + if (strncmp(path, BLOCK_PATH, strlen(BLOCK_PATH)) == 0 && + strlen(path) > strlen(BLOCK_PATH)) + return 'b'; + + if (strncmp(path, NET_PATH, strlen(NET_PATH)) == 0 && + strlen(path) > strlen(NET_PATH)) + return 'n'; + + if (strncmp(path, CLASS_PATH, strlen(CLASS_PATH)) == 0 && + strlen(path) > strlen(CLASS_PATH)) return 'c'; return '\0'; } +void udev_set_values(struct udevice *udev, const char* devpath, const char *subsystem) +{ + memset(udev, 0x00, sizeof(struct udevice)); + strfieldcpy(udev->devpath, devpath); + strfieldcpy(udev->subsystem, subsystem); + udev->type = get_device_type(devpath, subsystem); +} + +int create_path(const char *path) +{ + char p[NAME_SIZE]; + char *pos; + struct stat stats; + + strcpy (p, path); + pos = strrchr(p, '/'); + if (pos == p || pos == NULL) + return 0; + + while (pos[-1] == '/') + pos--; + + pos[0] = '\0'; + + dbg("stat '%s'\n", p); + if (stat (p, &stats) == 0 && (stats.st_mode & S_IFMT) == S_IFDIR) + return 0; + + if (create_path (p) != 0) + return -1; + + dbg("mkdir '%s'\n", p); + return mkdir(p, 0755); +} + int file_map(const char *filename, char **buf, size_t *bufsize) { struct stat stats; @@ -113,11 +158,13 @@ int file_map(const char *filename, char **buf, size_t *bufsize) } if (fstat(fd, &stats) < 0) { + close(fd); return -1; } *buf = mmap(NULL, stats.st_size, PROT_READ, MAP_SHARED, fd, 0); if (*buf == MAP_FAILED) { + close(fd); return -1; } *bufsize = stats.st_size; @@ -141,6 +188,15 @@ size_t buf_get_line(char *buf, size_t buflen, size_t cur) return count - cur; } +void no_trailing_slash(char *path) +{ + int len; + + len = strlen(path); + if (len > 0 && path[len-1] == '/') + path[len-1] = '\0'; +} + struct files { struct list_head list; char name[NAME_SIZE]; @@ -169,7 +225,7 @@ static int file_list_insert(char *filename, struct list_head *file_list) return 0; } -/* calls function for file or every file found in directory */ +/* calls function for every file found in specified directory */ int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix) { struct dirent *ent; @@ -209,9 +265,8 @@ int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix) /* call function for every file in the list */ list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) { - strfieldcpy(file, dirname); - strfieldcat(file, "/"); - strfieldcat(file, loop_file->name); + snprintf(file, NAME_SIZE-1, "%s/%s", dirname, loop_file->name); + file[NAME_SIZE-1] = '\0'; fnct(file); @@ -222,3 +277,22 @@ int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix) closedir(dir); return 0; } + +/* Set the FD_CLOEXEC flag of desc if value is nonzero, + or clear the flag if value is 0. + Return 0 on success, or -1 on error with errno set. */ + +int set_cloexec_flag (int desc, int value) +{ + int oldflags = fcntl (desc, F_GETFD, 0); + /* If reading the flags failed, return error indication now. */ + if (oldflags < 0) + return oldflags; + /* Set just the flag we want to set. */ + if (value != 0) + oldflags |= FD_CLOEXEC; + else + oldflags &= ~FD_CLOEXEC; + /* Store modified flag word in the descriptor. */ + return fcntl (desc, F_SETFD, oldflags); +}