diff --git a/stmhal/input.c b/stmhal/input.c
index 6bd9e6c4f0b7db6b8afe7c6ff4c923ba4985901e..94f66b97f104431de0aee1fd2851dc15e68c40f0 100644
--- a/stmhal/input.c
+++ b/stmhal/input.c
@@ -36,7 +36,7 @@
 
 STATIC mp_obj_t mp_builtin_input(uint n_args, const mp_obj_t *args) {
     if (n_args == 1) {
-        mp_obj_print(args[0], PRINT_REPR);
+        mp_obj_print(args[0], PRINT_STR);
     }
     vstr_t line;
     vstr_init(&line, 16);
diff --git a/unix/Makefile b/unix/Makefile
index 304f09062d17c7d5f657d51a1f2c81abd4e157a5..05cdfb5b390cb6e1768bac1c2699fe0b02454640 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -65,6 +65,7 @@ endif
 SRC_C = \
 	main.c \
 	gccollect.c \
+	input.c \
 	file.c \
 	modsocket.c \
 	$(SRC_MOD)
diff --git a/unix/input.c b/unix/input.c
new file mode 100644
index 0000000000000000000000000000000000000000..0774503d9084dd20cef69a5c4b59ce80bfa952b4
--- /dev/null
+++ b/unix/input.c
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013, 2014 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mpconfig.h"
+#include "nlr.h"
+#include "misc.h"
+#include "qstr.h"
+#include "obj.h"
+#include "input.h"
+
+#if MICROPY_USE_READLINE
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif
+
+#define CTRL_D  '\x04'
+
+char *prompt(char *p) {
+#if MICROPY_USE_READLINE
+    char *line = readline(p);
+    if (line) {
+        add_history(line);
+    }
+#else
+    static char buf[256];
+    fputs(p, stdout);
+    char *s = fgets(buf, sizeof(buf), stdin);
+    if (!s) {
+        return NULL;
+    }
+    int l = strlen(buf);
+    if (buf[l - 1] == '\n') {
+        buf[l - 1] = 0;
+    } else {
+        l++;
+    }
+    char *line = malloc(l);
+    memcpy(line, buf, l);
+#endif
+    return line;
+}
+
+STATIC mp_obj_t mp_builtin_input(uint n_args, const mp_obj_t *args) {
+    if (n_args == 1) {
+        mp_obj_print(args[0], PRINT_STR);
+    }
+
+    char *line = prompt("");
+    if (line == NULL) {
+        nlr_raise(mp_obj_new_exception(&mp_type_EOFError));
+    }
+    mp_obj_t o = mp_obj_new_str((const byte*)line, strlen(line), false);
+    free(line);
+    return o;
+}
+
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_input_obj, 0, 1, mp_builtin_input);
diff --git a/unix/input.h b/unix/input.h
new file mode 100644
index 0000000000000000000000000000000000000000..7623a8718cbdf77b8b118e4734364de40abbb39c
--- /dev/null
+++ b/unix/input.h
@@ -0,0 +1,2 @@
+char *prompt(char *p);
+
diff --git a/unix/main.c b/unix/main.c
index 5a7ea1c038c619715da83b4ec9971262a2aa0e3c..cc80811503f0d6abbea294d948bbe8ad3b6cf579 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -49,11 +49,7 @@
 #include "repl.h"
 #include "gc.h"
 #include "genhdr/py-version.h"
-
-#if MICROPY_USE_READLINE
-#include <readline/readline.h>
-#include <readline/history.h>
-#endif
+#include "input.h"
 
 // Command line options, with their defaults
 bool compile_only = false;
@@ -143,31 +139,6 @@ STATIC char *strjoin(const char *s1, int sep_char, const char *s2) {
     return s;
 }
 
-STATIC char *prompt(char *p) {
-#if MICROPY_USE_READLINE
-    char *line = readline(p);
-    if (line) {
-        add_history(line);
-    }
-#else
-    static char buf[256];
-    fputs(p, stdout);
-    char *s = fgets(buf, sizeof(buf), stdin);
-    if (!s) {
-        return NULL;
-    }
-    int l = strlen(buf);
-    if (buf[l - 1] == '\n') {
-        buf[l - 1] = 0;
-    } else {
-        l++;
-    }
-    char *line = malloc(l);
-    memcpy(line, buf, l);
-#endif
-    return line;
-}
-
 STATIC void do_repl(void) {
     printf("Micro Python " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; UNIX version\n");
 
diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h
index 41bc6a3937d428c360d312873b39ff875d8e4822..ca470d9c29f341ac23f3dbaeeb0e5b60b6512860 100644
--- a/unix/mpconfigport.h
+++ b/unix/mpconfigport.h
@@ -72,6 +72,8 @@ typedef unsigned int machine_uint_t; // must be pointer size
 typedef void *machine_ptr_t; // must be of pointer size
 typedef const void *machine_const_ptr_t; // must be of pointer size
 
+extern const struct _mp_obj_fun_native_t mp_builtin_input_obj;
 extern const struct _mp_obj_fun_native_t mp_builtin_open_obj;
 #define MICROPY_EXTRA_BUILTINS \
+    { MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&mp_builtin_input_obj }, \
     { MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
diff --git a/unix/qstrdefsport.h b/unix/qstrdefsport.h
index ea820af2becfcac0f5d636467fb144531ef6b8d6..55a82ec06726b3481e60726725ce47bc70911c67 100644
--- a/unix/qstrdefsport.h
+++ b/unix/qstrdefsport.h
@@ -43,6 +43,7 @@ Q(callback)
 Q(func)
 Q(var)
 
+Q(input)
 Q(time)
 Q(clock)
 Q(sleep)