diff --git a/08-writev/writev.c b/08-writev/writev.c
index afedf30..2fec074 100644
--- a/08-writev/writev.c
+++ b/08-writev/writev.c
@@ -13,8 +13,63 @@
 #define die(msg) do { perror(msg); exit(EXIT_FAILURE); } while(0)
 
 
+// We define ourselves a helper structure to have a growable iovec
+// structure. If we would use C++, we could simply use std::vector.
+struct dynamic_iovec {
+    struct iovec *vec; // An heap allocated iovector
+    int count;         // ... that currently contains count elements
+    int capacity;      // ... that can hold up to capacity elements
+};
+
+// An initializer list to correctly initialize an dynamic_iovec instance
+#define DYNAMIC_IOVEC_INIT() {.vec = NULL, .count=0, .capacity=0}
+
+// Adds an element to our dynamic iovector. Grow it if there is not enough capacity.
+void dynamic_iovec_add(struct dynamic_iovec *vec, void* data, ssize_t len) {
+    // Resize our I/O vector if the capacity is not sufficiently
+    // large. This test also works if capacity and count are zero.
+    if ((vec->count + 1) > vec->capacity) {
+        vec->capacity = 2 * (vec->count + 1);
+        vec->vec = realloc(vec->vec, vec->capacity * sizeof(struct iovec));
+        if (!vec) die("realloc");
+    }
+
+    // Add the element to the I/O vector
+    vec->vec[vec->count].iov_base = data;
+    vec->vec[vec->count].iov_len  = len;
+    vec->count++;
+}
+
+// We cast the pointers from void to struct iovec
+// and utilize strcmp(3) with their iov_bases for comparison
+int compare_lines(const void *p1, const void *p2) {
+    struct iovec *v1 = (struct iovec *)p1;
+    struct iovec *v2 = (struct iovec *)p2;
+    
+    return strcmp((char *)v1->iov_base, (char *)v2->iov_base);
+}
+
 int main() {
-    // FIXME: Read in lines (HINT: getline(3))
-    // FIXME: Sort lines (HINT: qsort(3))
-    // FIXME: Dump lines with writev(2)
+    // We stack-allocate an dynamic_iovec to hold our lines.
+    // (one line = tuple of char * and length).
+    struct dynamic_iovec lines = DYNAMIC_IOVEC_INIT();
+    
+    // We use getline(3) to read lines from stdin. Please consult the
+    // man page to understand the semantic of dummy!
+    ssize_t nread;
+    size_t dummy;
+    char *line;
+    while ((dummy = 0, nread = getline(&line, &dummy, stdin)) != -1) {
+        // Add the line to the dynamic vector
+        dynamic_iovec_add(&lines, line, nread);
+    }
+
+    // We sort the I/O vectors by using qsort(3) with compare_lines 
+    // as the comparison function.
+    qsort((void *)lines.vec, (size_t)lines.count, sizeof(struct iovec), compare_lines);
+
+    // After sorting, we use a single system call to dump all lines
+    // in one go.
+    writev(STDOUT_FILENO, lines.vec, lines.count);
+
 }