diff options
| -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); | 
