From 01bd32e0e46ab8d9b6aeda77a550ec08074728a6 Mon Sep 17 00:00:00 2001
From: Christopher Ferris <cferris@google.com>
Date: Tue, 5 Aug 2014 12:19:27 -0700
Subject: [PATCH] Create a distinct temp directory for each run.

Modify make__NR_name so that only __ARM_NR_ is exempted from the
__NR_ being prepended. This avoids a case where using a name starting
with __ but is not a valid syscall name in SYSCALLS.TXT does not generate
code that will compile but references the function itself and causes
link errors.

Fix all of the directory references from dir_part1 + dir_part2 to
use os.path.join() instead.

Change-Id: Ib9527eba6f25f26a30c5cb0ad431f3f88a7683cf
---
 libc/tools/gensyscalls.py | 61 ++++++++++++++++++++++-----------------
 1 file changed, 34 insertions(+), 27 deletions(-)

diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 96583d69d..42f2c916b 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -4,6 +4,7 @@
 # the header files listing all available system calls, and the
 # makefiles used to build all the stubs.
 
+import atexit
 import commands
 import filecmp
 import glob
@@ -12,13 +13,16 @@ import re
 import shutil
 import stat
 import sys
+import tempfile
 
 from bionic_utils import *
 
-bionic_libc_root = os.environ["ANDROID_BUILD_TOP"] + "/bionic/libc/"
-
 # temp directory where we store all intermediate files
-bionic_temp = "/tmp/bionic_gensyscalls/"
+bionic_temp = tempfile.mkdtemp(prefix="bionic_gensyscalls");
+# Make sure the directory is deleted when the script exits.
+atexit.register(shutil.rmtree, bionic_temp)
+
+bionic_libc_root = os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libc")
 
 warning = "Generated by gensyscalls.py. Do not edit."
 
@@ -34,9 +38,10 @@ def make_dir(path):
 
 
 def create_file(relpath):
-    dir = os.path.dirname(bionic_temp + relpath)
+    full_path = os.path.join(bionic_temp, relpath)
+    dir = os.path.dirname(full_path)
     make_dir(dir)
-    return open(bionic_temp + relpath, "w")
+    return open(full_path, "w")
 
 
 syscall_stub_header = "/* " + warning + " */\n" + \
@@ -265,7 +270,7 @@ def count_generic_param_registers64(params):
 # This lets us support regular system calls like __NR_write and also weird
 # ones like __ARM_NR_cacheflush, where the NR doesn't come at the start.
 def make__NR_name(name):
-    if name.startswith("__"):
+    if name.startswith("__ARM_NR_"):
         return name
     else:
         return "__NR_%s" % (name)
@@ -444,15 +449,15 @@ class State:
         glibc_fp.write("#define _BIONIC_GLIBC_SYSCALLS_H_\n")
 
         glibc_fp.write("#if defined(__aarch64__)\n")
-        self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-generic/unistd.h")
+        self.scan_linux_unistd_h(glibc_fp, os.path.join(bionic_libc_root, "kernel/uapi/asm-generic/unistd.h"))
         glibc_fp.write("#elif defined(__arm__)\n")
-        self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-arm/asm/unistd.h")
+        self.scan_linux_unistd_h(glibc_fp, os.path.join(bionic_libc_root, "kernel/uapi/asm-arm/asm/unistd.h"))
         glibc_fp.write("#elif defined(__mips__)\n")
-        self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-mips/asm/unistd.h")
+        self.scan_linux_unistd_h(glibc_fp, os.path.join(bionic_libc_root, "kernel/uapi/asm-mips/asm/unistd.h"))
         glibc_fp.write("#elif defined(__i386__)\n")
-        self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-x86/asm/unistd_32.h")
+        self.scan_linux_unistd_h(glibc_fp, os.path.join(bionic_libc_root, "kernel/uapi/asm-x86/asm/unistd_32.h"))
         glibc_fp.write("#elif defined(__x86_64__)\n")
-        self.scan_linux_unistd_h(glibc_fp, bionic_libc_root + "/kernel/uapi/asm-x86/asm/unistd_64.h")
+        self.scan_linux_unistd_h(glibc_fp, os.path.join(bionic_libc_root, "kernel/uapi/asm-x86/asm/unistd_64.h"))
         glibc_fp.write("#endif\n")
 
         glibc_fp.write("#endif /* _BIONIC_GLIBC_SYSCALLS_H_ */\n")
@@ -476,14 +481,13 @@ class State:
     def regenerate(self):
         D("scanning for existing architecture-specific stub files...")
 
-        bionic_libc_root_len = len(bionic_libc_root)
-
         for arch in all_arches:
-            arch_path = bionic_libc_root + "arch-" + arch
-            D("scanning " + arch_path)
-            files = glob.glob(arch_path + "/syscalls/*.S")
-            for f in files:
-                self.old_stubs.append(f[bionic_libc_root_len:])
+            arch_dir = "arch-" + arch
+            D("scanning " + os.path.join(bionic_libc_root, arch_dir))
+            rel_path = os.path.join(arch_dir, "syscalls")
+            for file in os.listdir(os.path.join(bionic_libc_root, rel_path)):
+                if file.endswith(".S"):
+                  self.old_stubs.append(os.path.join(rel_path, file))
 
         D("found %d stub files" % len(self.old_stubs))
 
@@ -501,13 +505,15 @@ class State:
         edits   = []
 
         for stub in self.new_stubs + self.other_files:
-            if not os.path.exists(bionic_libc_root + stub):
+            tmp_file = os.path.join(bionic_temp, stub)
+            libc_file = os.path.join(bionic_libc_root, stub)
+            if not os.path.exists(libc_file):
                 # new file, git add it
                 D("new file:     " + stub)
-                adds.append(bionic_libc_root + stub)
-                shutil.copyfile(bionic_temp + stub, bionic_libc_root + stub)
+                adds.append(libc_file)
+                shutil.copyfile(tmp_file, libc_file)
 
-            elif not filecmp.cmp(bionic_temp + stub, bionic_libc_root + stub):
+            elif not filecmp.cmp(tmp_file, libc_file):
                 D("changed file: " + stub)
                 edits.append(stub)
 
@@ -515,7 +521,7 @@ class State:
         for stub in self.old_stubs:
             if not stub in self.new_stubs:
                 D("deleted file: " + stub)
-                deletes.append(bionic_libc_root + stub)
+                deletes.append(os.path.join(bionic_libc_root, stub))
 
         if not DRY_RUN:
             if adds:
@@ -524,10 +530,11 @@ class State:
                 commands.getoutput("git rm " + " ".join(deletes))
             if edits:
                 for file in edits:
-                    shutil.copyfile(bionic_temp + file, bionic_libc_root + file)
-                commands.getoutput("git add " + " ".join((bionic_libc_root + file) for file in edits))
+                    shutil.copyfile(os.path.join(bionic_temp, file),
+                                    os.path.join(bionic_libc_root, file))
+                commands.getoutput("git add " + " ".join((os.path.join(bionic_libc_root, file)) for file in edits))
 
-            commands.getoutput("git add %s%s" % (bionic_libc_root,"SYSCALLS.TXT"))
+            commands.getoutput("git add %s" % (os.path.join(bionic_libc_root, "SYSCALLS.TXT")))
 
         if (not adds) and (not deletes) and (not edits):
             D("no changes detected!")
@@ -537,5 +544,5 @@ class State:
 D_setlevel(1)
 
 state = State()
-state.process_file(bionic_libc_root+"SYSCALLS.TXT")
+state.process_file(os.path.join(bionic_libc_root, "SYSCALLS.TXT"))
 state.regenerate()