+
+void session_source_add(int fd, int events, int timeout,
+ receive_data_callback callback, void *user_data)
+{
+ struct source *new_sources, *s;
+
+ new_sources = calloc(1, sizeof(struct source) * (num_sources + 1));
+
+ if (sources) {
+ memcpy(new_sources, sources,
+ sizeof(struct source) * num_sources);
+ free(sources);
+ }
+
+ s = &new_sources[num_sources++];
+ s->fd = fd;
+ s->events = events;
+ s->timeout = timeout;
+ s->cb = callback;
+ s->user_data = user_data;
+ sources = new_sources;
+
+ if (timeout != source_timeout && timeout > 0
+ && (source_timeout == -1 || timeout < source_timeout))
+ source_timeout = timeout;
+}
+
+void session_source_remove(int fd)
+{
+ struct source *new_sources;
+ int old, new;
+
+ if (!sources)
+ return;
+
+ new_sources = calloc(1, sizeof(struct source) * num_sources);
+ for (old = 0; old < num_sources; old++)
+ if (sources[old].fd != fd)
+ memcpy(&new_sources[new++], &sources[old],
+ sizeof(struct source));
+
+ if (old != new) {
+ free(sources);
+ sources = new_sources;
+ num_sources--;
+ } else {
+ /* Target fd was not found. */
+ free(new_sources);
+ }
+}
+