diff --git a/08-writev/writev.c b/08-writev/writev.c
index ff60089..97038e6 100644
--- a/08-writev/writev.c
+++ b/08-writev/writev.c
@@ -13,8 +13,66 @@
 #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++;
+}
+
 int main() {
-    // FIXME: Read in lines (HINT: getline(3))
-    // FIXME: Shuffle lines (HINT: random(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);
+    }
+
+    // Initialize the random number generator with the current time
+    // with gettimeofday(2). We use the nanoseconds within this second
+    // to get some randomness as a seed for srand(3).
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    srand(tv.tv_usec);
+
+    // We shuffle the I/O vector by randomly selecting another element
+    // for each line and swap those entries.
+    for (unsigned int A = 0; A < lines.count; A++) {
+        unsigned int B = random() % lines.count;
+        struct iovec tmp = lines.vec[A];
+        lines.vec[A] = lines.vec[B];
+        lines.vec[B] = tmp;
+    }
+
+    // After shuffling, we use a single system call to dump all lines
+    // in one go.
+    writev(STDOUT_FILENO, lines.vec, lines.count);
+
 }