Browse Source

Fix passing fd across modules

Cheng Zhao 9 years ago
parent
commit
e609a5bee2
4 changed files with 58 additions and 6 deletions
  1. 6 6
      atom/common/asar/archive.cc
  2. 19 0
      atom/node/osfhandle.cc
  3. 28 0
      atom/node/osfhandle.h
  4. 5 0
      common.gypi

+ 6 - 6
atom/common/asar/archive.cc

@@ -4,10 +4,6 @@
 
 #include "atom/common/asar/archive.h"
 
-#if defined(OS_WIN)
-#include <io.h>
-#endif
-
 #include <string>
 #include <vector>
 
@@ -20,6 +16,10 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 
+#if defined(OS_WIN)
+#include "atom/node/osfhandle.h"
+#endif
+
 namespace asar {
 
 namespace {
@@ -118,7 +118,7 @@ Archive::Archive(const base::FilePath& path)
     : path_(path),
       file_(path_, base::File::FLAG_OPEN | base::File::FLAG_READ),
 #if defined(OS_WIN)
-      fd_(_open_osfhandle(
+      fd_(node::open_osfhandle(
               reinterpret_cast<intptr_t>(file_.GetPlatformFile()), 0)),
 #elif defined(OS_POSIX)
       fd_(file_.GetPlatformFile()),
@@ -131,7 +131,7 @@ Archive::Archive(const base::FilePath& path)
 Archive::~Archive() {
 #if defined(OS_WIN)
   if (fd_ != -1) {
-    _close(fd_);
+    node::close(fd_);
     // Don't close the handle since we already closed the fd.
     file_.TakePlatformFile();
   }

+ 19 - 0
atom/node/osfhandle.cc

@@ -0,0 +1,19 @@
+// Copyright (c) 2016 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include "osfhandle.h"
+
+#include <io.h>
+
+namespace node {
+
+int open_osfhandle(intptr_t osfhandle, int flags) {
+  return _open_osfhandle(osfhandle, flags);
+}
+
+int close(int fd) {
+  return _close(fd);
+}
+
+}  // namespace node

+ 28 - 0
atom/node/osfhandle.h

@@ -0,0 +1,28 @@
+// Copyright (c) 2016 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#ifndef ATOM_NODE_OSFHANDLE_H_
+#define ATOM_NODE_OSFHANDLE_H_
+
+#include <windows.h>
+
+#include "node_extern.h"
+
+namespace node {
+
+// The _open_osfhandle and _close functions on Windows are provided by the
+// Visual C++ library, so the fd returned by them can only be used in the
+// same instance of VC++ library.
+// However Electron is linking with VC++ library statically, so electron.exe
+// shares a different instance of VC++ library with node.exe. This results
+// in fd created in electron.exe not usable in node.dll, so we have to ensure
+// we always create fd in one instance of VC++ library.
+// Followings wrappers are compiled in node.dll, and all code in electron.exe
+// should call these wrappers instead of calling _open_osfhandle directly.
+NODE_EXTERN int open_osfhandle(intptr_t osfhandle, int flags);
+NODE_EXTERN int close(int fd);
+
+}  // namespace node
+
+#endif  // ATOM_NODE_OSFHANDLE_H_

+ 5 - 0
common.gypi

@@ -118,7 +118,12 @@
         ],
       }],
       ['_target_name=="node"', {
+        'sources': [
+          '<(DEPTH)/atom/node/osfhandle.cc',
+          '<(DEPTH)/atom/node/osfhandle.h',
+        ],
         'include_dirs': [
+          '<(DEPTH)/atom/node',
           '<(libchromiumcontent_src_dir)/v8',
           '<(libchromiumcontent_src_dir)/v8/include',
         ],