diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2006-02-08 05:38:38 +0000 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2006-02-08 05:38:38 +0000 |
commit | 85cc0c57e4fd0e44c3b270aba4f87eb28151b1a2 (patch) | |
tree | 224ae692ccbed28ac1b5657835849a5e96b267dc /common | |
parent | 9b993dda376d1c74575ed8984b0cf07d1d671f8c (diff) |
Add textfile_foreach() function
Diffstat (limited to 'common')
-rw-r--r-- | common/test_textfile.c | 24 | ||||
-rw-r--r-- | common/textfile.c | 89 | ||||
-rw-r--r-- | common/textfile.h | 3 |
3 files changed, 99 insertions, 17 deletions
diff --git a/common/test_textfile.c b/common/test_textfile.c index c2b2c993..5a5b22c5 100644 --- a/common/test_textfile.c +++ b/common/test_textfile.c @@ -34,6 +34,11 @@ #include "textfile.h" +static void print_entry(char *key, char *value, void *data) +{ + printf("%s %s\n", key, value); +} + int main(int argc, char *argv[]) { char filename[] = "/tmp/textfile"; @@ -109,15 +114,8 @@ int main(int argc, char *argv[]) printf("\n"); - for (i = 1; i < max + 1; i++) { - sprintf(key, "00:00:00:00:00:%02X", i); + textfile_foreach(filename, print_entry, NULL); - str = textfile_get(filename, key); - if (str) { - printf("%s %s\n", key, str); - free(str); - } - } sprintf(key, "00:00:00:00:00:%02X", 1); @@ -136,15 +134,7 @@ int main(int argc, char *argv[]) printf("\n"); - for (i = 1; i < max + 1; i++) { - sprintf(key, "00:00:00:00:00:%02X", i); - - str = textfile_get(filename, key); - if (str) { - printf("%s %s\n", key, str); - free(str); - } - } + textfile_foreach(filename, print_entry, NULL); return 0; } diff --git a/common/textfile.c b/common/textfile.c index 3aa74d9a..2ed929a3 100644 --- a/common/textfile.c +++ b/common/textfile.c @@ -296,3 +296,92 @@ close: return str; } + +int textfile_foreach(char *pathname, + void (*func)(char *key, char *value, void *data), void *data) +{ + struct stat st; + char *map, *off, *end, *key, *value; + off_t size; size_t len; + int fd, err = 0; + + fd = open(pathname, O_RDONLY); + if (fd < 0) + return -errno; + + if (flock(fd, LOCK_SH) < 0) { + err = errno; + goto close; + } + + if (fstat(fd, &st) < 0) { + err = errno; + goto unlock; + } + + size = st.st_size; + + map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (!map || map == MAP_FAILED) { + err = errno; + goto unlock; + } + + off = map; + + while (1) { + end = strpbrk(off, " "); + if (!end) { + err = EILSEQ; + break; + } + + len = end - off; + + key = malloc(len + 1); + if (!key) { + err = errno; + break; + } + + memset(key, 0, len + 1); + memcpy(key, off, len); + + off = end + 1; + + end = strpbrk(off, "\r\n"); + if (!end) { + err = EILSEQ; + break; + } + + len = end - off; + + value = malloc(len + 1); + if (!value) { + err = errno; + break; + } + + memset(value, 0, len + 1); + memcpy(value, off, len); + + func(key, value, data); + + free(key); + free(value); + + off = end + 1; + } + + munmap(map, size); + +unlock: + flock(fd, LOCK_UN); + +close: + close(fd); + errno = err; + + return 0; +} diff --git a/common/textfile.h b/common/textfile.h index 62ad4b80..3c8b6841 100644 --- a/common/textfile.h +++ b/common/textfile.h @@ -27,3 +27,6 @@ int create_file(char *filename, mode_t mode); int textfile_put(char *pathname, char *key, char *value); int textfile_del(char *pathname, char *key); char *textfile_get(char *pathname, char *key); + +int textfile_foreach(char *pathname, + void (*func)(char *key, char *value, void *data), void *data); |