#include <stdio.h>
#include <string.h>
+#include <dirent.h>
+#include <stdlib.h>
#include "procfs.h"
#include "log.h"
#define STAT_FILEPATH "/proc/stat"
#define PIDSTAT_FILEPATH "/proc/%d/stat"
#define SMAPS_FILEPATH "/proc/%d/smaps"
+#define PROC_DIR_PATH "/proc/"
+
+struct procfs_pid_iterator
+{
+ DIR *dir;
+ int current_pid;
+};
int procfs_read_system_load_average(struct procfs_load_average_info *info)
{
return 0;
}
+
+bool _procfs_dirname_parse_pid(const char *dirname, int *pid)
+{
+ int parsed_pid;
+
+ if (sscanf(dirname, "%d", &parsed_pid) != 1) {
+ return false;
+ }
+ *pid = parsed_pid;
+ return true;
+}
+
+/**
+ * @brief returns true if pid_iterator could successfully read
+ * next pid from /proc directory, false otherwise
+ */
+bool _procfs_pid_iterator_next_internal(procfs_pid_iterator_t *iter)
+{
+ struct dirent *entry;
+ int pid;
+ bool ret = false;
+
+ // According to POSIX docs readdir is not-thread safe.
+ // however in glib recent implementations readdir
+ // is thread safe, so we can avoid using locks here.
+ while ((entry = readdir(iter->dir)) != NULL) {
+ if (_procfs_dirname_parse_pid(entry->d_name, &pid)) {
+ iter->current_pid = pid;
+ ret = true;
+ break;
+ } else {
+ continue;
+ }
+ }
+
+ return ret;
+}
+
+procfs_pid_iterator_t *procfs_get_pid_iterator()
+{
+ procfs_pid_iterator_t *ret = calloc(1, sizeof(struct procfs_pid_iterator));
+ if (!ret) {
+ ERR("calloc failed.");
+ return NULL;
+ }
+ ret->dir = opendir(PROC_DIR_PATH);
+ if (!ret->dir) {
+ ERR("opendir failed.");
+ procfs_pid_iterator_free(ret);
+ return NULL;
+ }
+ if (!_procfs_pid_iterator_next_internal(ret)) {
+ ERR("_procfs_pid_iterator_next_internal failed");
+ procfs_pid_iterator_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+bool procfs_pid_iterator_next(procfs_pid_iterator_t *iterator)
+{
+ return _procfs_pid_iterator_next_internal(iterator);
+}
+
+int procfs_pid_iterator_get_pid(procfs_pid_iterator_t *iterator)
+{
+ return iterator->current_pid;
+}
+
+void procfs_pid_iterator_free(procfs_pid_iterator_t *iterator)
+{
+ if (!iterator) return;
+ if (iterator->dir) closedir(iterator->dir);
+ free(iterator);
+}
#define __PROCFS_H_
#include <stddef.h>
+#include <stdbool.h>
/**
* @brief System memory information.
*/
int procfs_read_cpu_count(int *cpu_count);
+/**
+ * @brief Iterator over pids in /proc/ directory.
+ */
+typedef struct procfs_pid_iterator procfs_pid_iterator_t;
+
+/**
+ * @brief Move iterator to next entry.
+ *
+ * @param[in]: itearator
+ *
+ * @return returns true if there are more entries available, false otherwise
+ */
+bool procfs_pid_iterator_next(procfs_pid_iterator_t *iterator);
+
+/**
+ * @brief Gets current pid from iterator
+ *
+ * @param[in]: itearator
+ *
+ * @not User should always check validity of pid, since it not guaranteed that
+ * returned pid is still valid after function returns.
+ */
+int procfs_pid_iterator_get_pid(procfs_pid_iterator_t *iterator);
+
+/**
+ * @brief Frees procfs_pid_iterator_t
+ *
+ * @param[in]: itearator
+ */
+void procfs_pid_iterator_free(procfs_pid_iterator_t *iterator);
+
+/**
+ * @brief Gets pid iterator
+ *
+ * @return new procfs_pid_iterator_t or NULL or error or no pids is available.
+ *
+ * @note the returned value should be released wiht procfs_pid_iterator_free
+ */
+procfs_pid_iterator_t *procfs_get_pid_iterator();
+
#endif