From 177ba8cb42ed6d232e7c8bcad5e6ee21fc51a0e8 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Fri, 8 Apr 2011 08:50:48 +0200 Subject: Prevent deadlock when using fork When forking of a new process in bionic, it is critical that it does not allocate any memory according to the comment in java_lang_ProcessManager.c: "Note: We cannot malloc() or free() after this point! A no-longer-running thread may be holding on to the heap lock, and an attempt to malloc() or free() would result in deadlock." However, as fork is using standard lib calls when tracing it a bit, they might allocate memory, and thus causing the deadlock. This is a rewrite so that the function cpuacct_add, that fork calls, will use system calls instead of standard lib calls. Signed-off-by: christian bejram Change-Id: Iff22ea6b424ce9f9bf0ac8e9c76593f689e0cc86 --- libc/bionic/cpuacct.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/libc/bionic/cpuacct.c b/libc/bionic/cpuacct.c index 7317073..1321d0e 100644 --- a/libc/bionic/cpuacct.c +++ b/libc/bionic/cpuacct.c @@ -30,16 +30,19 @@ #include #include #include "cpuacct.h" +#include int cpuacct_add(uid_t uid) { int count; - FILE *fp; + int fd; char buf[80]; + ssize_t n; + int ret = 0; count = snprintf(buf, sizeof(buf), "/acct/uid/%d/tasks", uid); - fp = fopen(buf, "w+"); - if (!fp) { + fd = open(buf, O_RDWR | O_CREAT, 0666); + if (fd == -1) { /* Note: sizeof("tasks") returns 6, which includes the NULL char */ buf[count - sizeof("tasks")] = 0; if (mkdir(buf, 0775) < 0) @@ -47,14 +50,19 @@ int cpuacct_add(uid_t uid) /* Note: sizeof("tasks") returns 6, which includes the NULL char */ buf[count - sizeof("tasks")] = '/'; - fp = fopen(buf, "w+"); + fd = open(buf, O_RDWR | O_CREAT, 0666); } - if (!fp) + if (fd == -1) return -errno; - fprintf(fp, "0"); - if (fclose(fp)) + n = TEMP_FAILURE_RETRY(write(fd, "0", 1)); + if (n < 0) + ret = -errno; + else if (n == 0) + ret = -EIO; + + if (TEMP_FAILURE_RETRY(close(fd)) == -1) return -errno; - return 0; + return ret; } -- cgit v1.1