From 9c2d22a6ceff4aa49de6a4e14973ac7b8994261c Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Mon, 6 Jul 2015 20:26:05 +0200
Subject: Handle EINTR in trace_file_drv

---
 lib/runtime_tools/c_src/trace_file_drv.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

(limited to 'lib')

diff --git a/lib/runtime_tools/c_src/trace_file_drv.c b/lib/runtime_tools/c_src/trace_file_drv.c
index 08bace80ef..f5980b4a57 100644
--- a/lib/runtime_tools/c_src/trace_file_drv.c
+++ b/lib/runtime_tools/c_src/trace_file_drv.c
@@ -326,9 +326,11 @@ static ErlDrvData trace_file_start(ErlDrvPort port, char *buff)
 		   | O_BINARY
 #endif
 		   , 0777)) < 0) {
+	int saved_errno = errno;
 	if (wrap)
 	    driver_free(wrap);
 	driver_free(data);
+	errno = saved_errno;
 	return ERL_DRV_ERROR_ERRNO;
     } 
 
@@ -524,14 +526,19 @@ static void *my_alloc(size_t size)
 ** A write wrapper that regards it as an error if not all data was written.
 */
 static int do_write(FILETYPE fd, unsigned char *buff, int siz) {
-    int w = write(fd, buff, siz);
-    if (w != siz) {
-	if (w >= 0) {
-	    errno = ENOSPC;
+    int w;
+    while (1) {
+	w = write(fd, buff, siz);
+	if (w < 0 && errno == EINTR)
+	    continue;
+	else if (w != siz) {
+	    if (w >= 0) {
+		errno = ENOSPC;
+	    }
+	    return -1;
 	}
-	return -1;
+	return siz;
     }
-    return siz;
 }
 
 /*
@@ -626,8 +633,10 @@ static void close_unlink_port(TraceFileData *data)
 */
 static int wrap_file(TraceFileData *data) {
     if (my_flush(data) < 0) {
+	int saved_errno = errno;
 	close(data->fd);
 	data->fd = -1;
+	errno = saved_errno;
 	return -1;
     }
     close(data->fd);
@@ -643,12 +652,15 @@ static int wrap_file(TraceFileData *data) {
 	next_name(&data->wrap->del);
     }
     next_name(&data->wrap->cur);
+try_open:
     data->fd = open(data->wrap->cur.name, O_WRONLY | O_TRUNC | O_CREAT
 #ifdef O_BINARY
 	      | O_BINARY
 #endif
 	      , 0777);
     if (data->fd < 0) {
+	if (errno == EINTR)
+	    goto try_open;
 	data->fd = -1;
 	return -1;
     }
-- 
cgit v1.2.3