From 2cbdab903fc0a66f246647f4d79e92b3e1778b82 Mon Sep 17 00:00:00 2001
From: antirez <antirez@gmail.com>
Date: Sat, 7 Apr 2012 12:11:23 +0200
Subject: [PATCH] For coverage testing use exit() instead of _exit() when
 termiating saving children.

---
 src/Makefile |  2 +-
 src/aof.c    |  4 ++--
 src/rdb.c    |  2 +-
 src/redis.c  | 12 ++++++++++++
 src/redis.h  |  1 +
 5 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/src/Makefile b/src/Makefile
index 8e9f0e345..e94d03fd6 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -263,7 +263,7 @@ gprof:
 	$(MAKE) PROF="-pg"
 
 gcov:
-	$(MAKE) PROF="-fprofile-arcs -ftest-coverage"
+	$(MAKE) PROF="-fprofile-arcs -ftest-coverage -DCOVERAGE_TEST"
 
 noopt:
 	$(MAKE) OPTIMIZATION=""
diff --git a/src/aof.c b/src/aof.c
index 3f7cd10ff..115da29ba 100644
--- a/src/aof.c
+++ b/src/aof.c
@@ -803,9 +803,9 @@ int rewriteAppendOnlyFileBackground(void) {
         if (server.sofd > 0) close(server.sofd);
         snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) getpid());
         if (rewriteAppendOnlyFile(tmpfile) == REDIS_OK) {
-            _exit(0);
+            exitFromChild(0);
         } else {
-            _exit(1);
+            exitFromChild(1);
         }
     } else {
         /* Parent */
diff --git a/src/rdb.c b/src/rdb.c
index 6736d8fcb..abb966e02 100644
--- a/src/rdb.c
+++ b/src/rdb.c
@@ -686,7 +686,7 @@ int rdbSaveBackground(char *filename) {
         if (server.ipfd > 0) close(server.ipfd);
         if (server.sofd > 0) close(server.sofd);
         retval = rdbSave(filename);
-        _exit((retval == REDIS_OK) ? 0 : 1);
+        exitFromChild((retval == REDIS_OK) ? 0 : 1);
     } else {
         /* Parent */
         server.stat_fork_time = ustime()-start;
diff --git a/src/redis.c b/src/redis.c
index bdbec7a39..84221adda 100644
--- a/src/redis.c
+++ b/src/redis.c
@@ -356,6 +356,18 @@ long long mstime(void) {
     return ustime()/1000;
 }
 
+/* After an RDB dump or AOF rewrite we exit from children using _exit() instead of
+ * exit(), because the latter may interact with the same file objects used by
+ * the parent process. However if we are testing the coverage normal exit() is
+ * used in order to obtain the right coverage information. */
+void exitFromChild(int retcode) {
+#ifdef COVERAGE_TEST
+    exit(retcode);
+#else
+    _exit(retcode);
+#endif
+}
+
 /*====================== Hash table type implementation  ==================== */
 
 /* This is an hash table type that uses the SDS dynamic strings libary as
diff --git a/src/redis.h b/src/redis.h
index b386f16c9..ba209c7b9 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -828,6 +828,7 @@ long long ustime(void);
 long long mstime(void);
 void getRandomHexChars(char *p, unsigned int len);
 uint64_t crc64(const unsigned char *s, uint64_t l);
+void exitFromChild(int retcode);
 
 /* networking.c -- Networking and Client related operations */
 redisClient *createClient(int fd);