Port to FreeBSD.

This is mostly just moving code over to checking OS_POSIX where it's
using a POSIX interface. The only substantial FreeBSD-specific code
is the function for getting the path to the executable, which is
different on every platform.

Change-Id: I338d9bef9b0cbb7500f366352edb45e0cdb4d480
Reviewed-on: https://gn-review.googlesource.com/c/3920
Reviewed-by: Petr Hosek <phosek@google.com>
Commit-Queue: Petr Hosek <phosek@google.com>
diff --git a/base/files/file_posix.cc b/base/files/file_posix.cc
index 4faf77b..ed9a5e2 100644
--- a/base/files/file_posix.cc
+++ b/base/files/file_posix.cc
@@ -86,14 +86,7 @@
   is_symbolic_link = S_ISLNK(stat_info.st_mode);
   size = stat_info.st_size;
 
-#if defined(OS_LINUX)
-  time_t last_modified_sec = stat_info.st_mtim.tv_sec;
-  int64_t last_modified_nsec = stat_info.st_mtim.tv_nsec;
-  time_t last_accessed_sec = stat_info.st_atim.tv_sec;
-  int64_t last_accessed_nsec = stat_info.st_atim.tv_nsec;
-  time_t creation_time_sec = stat_info.st_ctim.tv_sec;
-  int64_t creation_time_nsec = stat_info.st_ctim.tv_nsec;
-#elif defined(OS_MACOSX)
+#if defined(OS_MACOSX)
   time_t last_modified_sec = stat_info.st_mtimespec.tv_sec;
   int64_t last_modified_nsec = stat_info.st_mtimespec.tv_nsec;
   time_t last_accessed_sec = stat_info.st_atimespec.tv_sec;
@@ -107,6 +100,13 @@
   int64_t last_accessed_nsec = 0;
   time_t creation_time_sec = stat_info.st_ctime;
   int64_t creation_time_nsec = 0;
+#elif defined(OS_POSIX)
+  time_t last_modified_sec = stat_info.st_mtim.tv_sec;
+  int64_t last_modified_nsec = stat_info.st_mtim.tv_nsec;
+  time_t last_accessed_sec = stat_info.st_atim.tv_sec;
+  int64_t last_accessed_nsec = stat_info.st_atim.tv_nsec;
+  time_t creation_time_sec = stat_info.st_ctim.tv_sec;
+  int64_t creation_time_nsec = stat_info.st_ctim.tv_nsec;
 #else
 #error
 #endif
diff --git a/build/gen.py b/build/gen.py
index 77fe5b5..96dafb9 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -39,6 +39,8 @@
       self._platform = 'aix'
     elif self._platform.startswith('fuchsia'):
       self._platform = 'fuchsia'
+    elif self._platform.startswith('freebsd'):
+      self._platform = 'freebsd'
 
   @staticmethod
   def known_platforms():
@@ -66,7 +68,7 @@
     return self._platform == 'aix'
 
   def is_posix(self):
-    return self._platform in ['linux', 'darwin', 'aix']
+    return self._platform in ['linux', 'freebsd', 'darwin', 'aix']
 
 
 def main(argv):
@@ -169,6 +171,7 @@
       'msvc': 'build_win.ninja.template',
       'darwin': 'build_mac.ninja.template',
       'linux': 'build_linux.ninja.template',
+      'freebsd': 'build_linux.ninja.template',
       'aix': 'build_aix.ninja.template',
   }[platform.platform()])
 
@@ -320,18 +323,18 @@
           '-static-libstdc++',
           '-Wl,--as-needed',
       ])
-      libs.extend([
-          # These are needed by libc++.
-          '-ldl',
-          '-lpthread',
-      ])
+      # This is needed by libc++.
+      libs.append('-ldl')
     elif platform.is_darwin():
       min_mac_version_flag = '-mmacosx-version-min=10.9'
       cflags.append(min_mac_version_flag)
       ldflags.append(min_mac_version_flag)
     elif platform.is_aix():
       cflags_cc.append('-maix64')
-      ldflags.extend(['-maix64', '-pthread'])
+      ldflags.append('-maix64')
+
+    if platform.is_posix():
+      ldflags.append('-pthread')
 
     if options.use_lto:
       cflags.extend(['-flto', '-fwhole-program-vtables'])
diff --git a/tools/gn/args.cc b/tools/gn/args.cc
index aa42ff3..5889c8f 100644
--- a/tools/gn/args.cc
+++ b/tools/gn/args.cc
@@ -294,6 +294,8 @@
   os = "mac";
 #elif defined(OS_LINUX)
   os = "linux";
+#elif defined(OS_FREEBSD)
+  os = "freebsd";
 #elif defined(OS_AIX)
   os = "aix";
 #else
diff --git a/tools/gn/exec_process.cc b/tools/gn/exec_process.cc
index 5c0619c..6c13558 100644
--- a/tools/gn/exec_process.cc
+++ b/tools/gn/exec_process.cc
@@ -21,6 +21,7 @@
 #else
 #include <errno.h>
 #include <fcntl.h>
+#include <sys/signal.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
diff --git a/util/exe_path.cc b/util/exe_path.cc
index f2adab5..2f80d5a 100644
--- a/util/exe_path.cc
+++ b/util/exe_path.cc
@@ -13,6 +13,9 @@
 #include <mach-o/dyld.h>
 #elif defined(OS_WIN)
 #include <windows.h>
+#elif defined(OS_FREEBSD)
+#include <sys/sysctl.h>
+#include <sys/types.h>
 #endif
 
 #if defined(OS_MACOSX)
@@ -46,6 +49,18 @@
   return base::FilePath(system_buffer);
 }
 
+#elif defined(OS_FREEBSD)
+
+base::FilePath GetExePath() {
+  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
+  char buf[PATH_MAX];
+  size_t buf_size = PATH_MAX;
+  if (sysctl(mib, 4, buf, &buf_size, nullptr, 0) == -1) {
+    return base::FilePath();
+  }
+  return base::FilePath(buf);
+}
+
 #else
 
 base::FilePath GetExePath() {
diff --git a/util/semaphore.cc b/util/semaphore.cc
index 2ae7b7b..d5c82be 100644
--- a/util/semaphore.cc
+++ b/util/semaphore.cc
@@ -36,7 +36,7 @@
   }
 }
 
-#elif defined(OS_LINUX) || defined(OS_AIX)
+#elif defined(OS_POSIX)
 
 Semaphore::Semaphore(int count) {
   DCHECK_GE(count, 0);
diff --git a/util/semaphore.h b/util/semaphore.h
index 2de2759..92a1df6 100644
--- a/util/semaphore.h
+++ b/util/semaphore.h
@@ -15,7 +15,7 @@
 #include <windows.h>
 #elif defined(OS_MACOSX)
 #include <mach/mach.h>
-#elif defined(OS_LINUX) || defined(OS_AIX)
+#elif defined(OS_POSIX)
 #include <semaphore.h>
 #else
 #error Port.
@@ -35,7 +35,7 @@
 
 #if defined(OS_MACOSX)
   typedef semaphore_t NativeHandle;
-#elif defined(OS_LINUX) || defined(OS_AIX)
+#elif defined(OS_POSIX)
   typedef sem_t NativeHandle;
 #elif defined(OS_WIN)
   typedef HANDLE NativeHandle;
diff --git a/util/ticks.cc b/util/ticks.cc
index 2a90c90..f26b5d8 100644
--- a/util/ticks.cc
+++ b/util/ticks.cc
@@ -11,7 +11,7 @@
 #include <windows.h>
 #elif defined(OS_MACOSX)
 #include <mach/mach_time.h>
-#elif defined(OS_LINUX) || defined(OS_AIX)
+#elif defined(OS_POSIX)
 #include <time.h>
 #else
 #error Port.
@@ -27,7 +27,7 @@
 #elif defined(OS_MACOSX)
 mach_timebase_info_data_t g_timebase;
 uint64_t g_start;
-#elif defined(OS_LINUX) || defined(OS_AIX)
+#elif defined(OS_POSIX)
 uint64_t g_start;
 #else
 #error Port.
@@ -44,7 +44,7 @@
 #elif defined(OS_MACOSX)
   mach_timebase_info(&g_timebase);
   g_start = (mach_absolute_time() * g_timebase.numer) / g_timebase.denom;
-#elif defined(OS_LINUX) || defined(OS_AIX)
+#elif defined(OS_POSIX)
   struct timespec ts;
   clock_gettime(CLOCK_MONOTONIC, &ts);
   g_start = static_cast<uint64_t>(ts.tv_sec) * kNano +
@@ -74,7 +74,7 @@
 #elif defined(OS_MACOSX)
   now =
       ((mach_absolute_time() * g_timebase.numer) / g_timebase.denom) - g_start;
-#elif defined(OS_LINUX) || defined(OS_AIX)
+#elif defined(OS_POSIX)
   struct timespec ts;
   clock_gettime(CLOCK_MONOTONIC, &ts);
   now = (static_cast<uint64_t>(ts.tv_sec) * kNano +