Welcome to mirror list, hosted at ThFree Co, Russian Federation.

node_child_process.h « src - github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c77f68ad8f70b1fd9e4d3237d169ef938b0bb0a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
#ifndef NODE_CHILD_PROCESS_H_
#define NODE_CHILD_PROCESS_H_

#include <node.h>
#include <node_object_wrap.h>

#include <v8.h>
#include <ev.h>

#ifdef __MINGW32__
# include <platform_win32.h> // HANDLE type
#endif

// ChildProcess is a thin wrapper around ev_child. It has the extra
// functionality that it can spawn a child process with pipes connected to
// its stdin, stdout, stderr. This class is not meant to be exposed to but
// wrapped up in a more friendly EventEmitter with streams for each of the
// pipes.
//
// When the child process exits (when the parent receives SIGCHLD) the
// callback child.onexit will be called.

namespace node {

class ChildProcess : ObjectWrap {
 public:
  static void Initialize(v8::Handle<v8::Object> target);

 protected:
  static v8::Handle<v8::Value> New(const v8::Arguments& args);
  static v8::Handle<v8::Value> Spawn(const v8::Arguments& args);
  static v8::Handle<v8::Value> Kill(const v8::Arguments& args);

  ChildProcess() : ObjectWrap() {
#ifdef __POSIX__
    ev_init(&child_watcher_, ChildProcess::on_chld);
    child_watcher_.data = this;
#endif // __POSIX__

    pid_ = -1;

#ifdef __MINGW32__
    InitializeCriticalSection(&info_lock_);
    kill_me_ = false;
    did_start_ = false;
    exit_signal_ = 0;
#endif // __MINGW32__
  }

  ~ChildProcess() {
#ifdef __POSIX__
    Stop();
#endif // __POSIX__
  }

  // Returns 0 on success. stdio_fds will contain file desciptors for stdin,
  // stdout, and stderr of the subprocess. stdin is writable; the other two
  // are readable.
  // The user of this class has responsibility to close these pipes after
  // the child process exits.
  int Spawn(const char *file,
            char *const argv[],
            const char *cwd,
            char **env,
            int stdio_fds[3],
            int custom_fds[3],
            bool do_setsid,
            int custom_uid,
            char *custom_uname,
            int custom_gid,
            char *custom_gname);

  // Simple syscall wrapper. Does not disable the watcher. onexit will be
  // called still.
  int Kill(int sig);

 private:
  void OnExit(int code);

#ifdef __POSIX__ // Shouldn't this just move to node_child_process.cc?
  void Stop(void);

  static void on_chld(EV_P_ ev_child *watcher, int revents) {
    ChildProcess *child = static_cast<ChildProcess*>(watcher->data);
    assert(revents == EV_CHILD);
    assert(child->pid_ == watcher->rpid);
    assert(&child->child_watcher_ == watcher);
    child->OnExit(watcher->rstatus);
  }

  ev_child child_watcher_;
  pid_t pid_;
#endif // __POSIX__

#ifdef __MINGW32__
  static int do_spawn(eio_req *req);
  static int after_spawn(eio_req *req);
  static void watch(ChildProcess *child);
  static void CALLBACK watch_wait_callback(void *data, BOOLEAN didTimeout);
  static void notify_spawn_failure(ChildProcess *child);
  static void notify_exit(EV_P_ ev_async *ev, int revent);
  static int do_kill(ChildProcess *child, int sig);static void close_stdio_handles(ChildProcess *child);

  int pid_;
  int exit_signal_;

  WCHAR *application_;
  WCHAR *arguments_;
  WCHAR *env_win_;
  WCHAR *cwd_;
  const WCHAR *path_;
  const WCHAR *path_ext_;

  HANDLE stdio_handles_[3];
  bool got_custom_fds_[3];

  CRITICAL_SECTION info_lock_;
  bool did_start_;
  bool kill_me_;
  HANDLE wait_handle_;
  HANDLE process_handle_;
#endif // __MINGW32__
};

}  // namespace node
#endif  // NODE_CHILD_PROCESS_H_