annotate hgext/fsmonitor/pywatchman/__init__.py @ 31110:7fec37746417

color: add a 'ui.color' option to control color behavior This new option control whether or not color will be used. It mirror the behavior of '--color'. I usually avoid adding new option to '[ui]' as the section is already filled with many option. However, I feel like 'color' is central enough to deserves a spot in this '[ui]' section. For now the option is not documented so it is still marked as experimental. Once it get documented and official, we should be able to deprecate the color extensions. There is more cleanup to do before that documentation is written, but we need this option early to made them. Having that option will allow for more cleanup of the initialisation process and proper separation between color configuration.
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
date Sat, 25 Feb 2017 19:44:23 +0100
parents 16f4b341288d
children dd35abc409ee
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1 # Copyright 2014-present Facebook, Inc.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
2 # All rights reserved.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
3 #
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
4 # Redistribution and use in source and binary forms, with or without
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
5 # modification, are permitted provided that the following conditions are met:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
6 #
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
7 # * Redistributions of source code must retain the above copyright notice,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
8 # this list of conditions and the following disclaimer.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
9 #
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
10 # * Redistributions in binary form must reproduce the above copyright notice,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
11 # this list of conditions and the following disclaimer in the documentation
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
12 # and/or other materials provided with the distribution.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
13 #
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
14 # * Neither the name Facebook nor the names of its contributors may be used to
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
15 # endorse or promote products derived from this software without specific
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
16 # prior written permission.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
17 #
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
19 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
20 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
21 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
22 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
23 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
24 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
25 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
26 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
28
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
29 from __future__ import absolute_import
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
30 from __future__ import division
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
31 from __future__ import print_function
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
32 # no unicode literals
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
33
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
34 import inspect
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
35 import math
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
36 import os
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
37 import socket
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
38 import subprocess
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
39 import time
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
40
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
41 # Sometimes it's really hard to get Python extensions to compile,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
42 # so fall back to a pure Python implementation.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
43 try:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
44 from . import bser
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
45 # Demandimport causes modules to be loaded lazily. Force the load now
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
46 # so that we can fall back on pybser if bser doesn't exist
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
47 bser.pdu_info
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
48 except ImportError:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
49 from . import pybser as bser
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
50
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
51 from . import (
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
52 capabilities,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
53 compat,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
54 encoding,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
55 load,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
56 )
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
57
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
58
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
59 if os.name == 'nt':
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
60 import ctypes
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
61 import ctypes.wintypes
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
62
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
63 wintypes = ctypes.wintypes
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
64 GENERIC_READ = 0x80000000
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
65 GENERIC_WRITE = 0x40000000
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
66 FILE_FLAG_OVERLAPPED = 0x40000000
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
67 OPEN_EXISTING = 3
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
68 INVALID_HANDLE_VALUE = -1
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
69 FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
70 FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
71 FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
72 WAIT_FAILED = 0xFFFFFFFF
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
73 WAIT_TIMEOUT = 0x00000102
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
74 WAIT_OBJECT_0 = 0x00000000
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
75 WAIT_IO_COMPLETION = 0x000000C0
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
76 INFINITE = 0xFFFFFFFF
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
77
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
78 # Overlapped I/O operation is in progress. (997)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
79 ERROR_IO_PENDING = 0x000003E5
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
80
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
81 # The pointer size follows the architecture
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
82 # We use WPARAM since this type is already conditionally defined
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
83 ULONG_PTR = ctypes.wintypes.WPARAM
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
84
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
85 class OVERLAPPED(ctypes.Structure):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
86 _fields_ = [
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
87 ("Internal", ULONG_PTR), ("InternalHigh", ULONG_PTR),
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
88 ("Offset", wintypes.DWORD), ("OffsetHigh", wintypes.DWORD),
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
89 ("hEvent", wintypes.HANDLE)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
90 ]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
91
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
92 def __init__(self):
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
93 self.Internal = 0
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
94 self.InternalHigh = 0
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
95 self.Offset = 0
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
96 self.OffsetHigh = 0
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
97 self.hEvent = 0
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
98
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
99 LPDWORD = ctypes.POINTER(wintypes.DWORD)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
100
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
101 CreateFile = ctypes.windll.kernel32.CreateFileA
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
102 CreateFile.argtypes = [wintypes.LPSTR, wintypes.DWORD, wintypes.DWORD,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
103 wintypes.LPVOID, wintypes.DWORD, wintypes.DWORD,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
104 wintypes.HANDLE]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
105 CreateFile.restype = wintypes.HANDLE
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
106
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
107 CloseHandle = ctypes.windll.kernel32.CloseHandle
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
108 CloseHandle.argtypes = [wintypes.HANDLE]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
109 CloseHandle.restype = wintypes.BOOL
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
110
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
111 ReadFile = ctypes.windll.kernel32.ReadFile
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
112 ReadFile.argtypes = [wintypes.HANDLE, wintypes.LPVOID, wintypes.DWORD,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
113 LPDWORD, ctypes.POINTER(OVERLAPPED)]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
114 ReadFile.restype = wintypes.BOOL
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
115
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
116 WriteFile = ctypes.windll.kernel32.WriteFile
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
117 WriteFile.argtypes = [wintypes.HANDLE, wintypes.LPVOID, wintypes.DWORD,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
118 LPDWORD, ctypes.POINTER(OVERLAPPED)]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
119 WriteFile.restype = wintypes.BOOL
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
120
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
121 GetLastError = ctypes.windll.kernel32.GetLastError
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
122 GetLastError.argtypes = []
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
123 GetLastError.restype = wintypes.DWORD
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
124
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
125 SetLastError = ctypes.windll.kernel32.SetLastError
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
126 SetLastError.argtypes = [wintypes.DWORD]
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
127 SetLastError.restype = None
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
128
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
129 FormatMessage = ctypes.windll.kernel32.FormatMessageA
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
130 FormatMessage.argtypes = [wintypes.DWORD, wintypes.LPVOID, wintypes.DWORD,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
131 wintypes.DWORD, ctypes.POINTER(wintypes.LPSTR),
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
132 wintypes.DWORD, wintypes.LPVOID]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
133 FormatMessage.restype = wintypes.DWORD
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
134
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
135 LocalFree = ctypes.windll.kernel32.LocalFree
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
136
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
137 GetOverlappedResult = ctypes.windll.kernel32.GetOverlappedResult
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
138 GetOverlappedResult.argtypes = [wintypes.HANDLE,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
139 ctypes.POINTER(OVERLAPPED), LPDWORD,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
140 wintypes.BOOL]
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
141 GetOverlappedResult.restype = wintypes.BOOL
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
142
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
143 GetOverlappedResultEx = getattr(ctypes.windll.kernel32,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
144 'GetOverlappedResultEx', None)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
145 if GetOverlappedResultEx is not None:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
146 GetOverlappedResultEx.argtypes = [wintypes.HANDLE,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
147 ctypes.POINTER(OVERLAPPED), LPDWORD,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
148 wintypes.DWORD, wintypes.BOOL]
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
149 GetOverlappedResultEx.restype = wintypes.BOOL
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
150
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
151 WaitForSingleObjectEx = ctypes.windll.kernel32.WaitForSingleObjectEx
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
152 WaitForSingleObjectEx.argtypes = [wintypes.HANDLE, wintypes.DWORD, wintypes.BOOL]
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
153 WaitForSingleObjectEx.restype = wintypes.DWORD
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
154
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
155 CreateEvent = ctypes.windll.kernel32.CreateEventA
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
156 CreateEvent.argtypes = [LPDWORD, wintypes.BOOL, wintypes.BOOL,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
157 wintypes.LPSTR]
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
158 CreateEvent.restype = wintypes.HANDLE
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
159
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
160 # Windows Vista is the minimum supported client for CancelIoEx.
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
161 CancelIoEx = ctypes.windll.kernel32.CancelIoEx
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
162 CancelIoEx.argtypes = [wintypes.HANDLE, ctypes.POINTER(OVERLAPPED)]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
163 CancelIoEx.restype = wintypes.BOOL
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
164
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
165 # 2 bytes marker, 1 byte int size, 8 bytes int64 value
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
166 sniff_len = 13
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
167
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
168 # This is a helper for debugging the client.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
169 _debugging = False
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
170 if _debugging:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
171
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
172 def log(fmt, *args):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
173 print('[%s] %s' %
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
174 (time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime()),
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
175 fmt % args[:]))
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
176 else:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
177
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
178 def log(fmt, *args):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
179 pass
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
180
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
181
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
182 def _win32_strerror(err):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
183 """ expand a win32 error code into a human readable message """
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
184
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
185 # FormatMessage will allocate memory and assign it here
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
186 buf = ctypes.c_char_p()
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
187 FormatMessage(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
188 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
189 | FORMAT_MESSAGE_IGNORE_INSERTS, None, err, 0, buf, 0, None)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
190 try:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
191 return buf.value
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
192 finally:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
193 LocalFree(buf)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
194
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
195
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
196 class WatchmanError(Exception):
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
197 def __init__(self, msg=None, cmd=None):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
198 self.msg = msg
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
199 self.cmd = cmd
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
200
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
201 def setCommand(self, cmd):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
202 self.cmd = cmd
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
203
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
204 def __str__(self):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
205 if self.cmd:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
206 return '%s, while executing %s' % (self.msg, self.cmd)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
207 return self.msg
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
208
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
209
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
210 class WatchmanEnvironmentError(WatchmanError):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
211 def __init__(self, msg, errno, errmsg, cmd=None):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
212 super(WatchmanEnvironmentError, self).__init__(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
213 '{0}: errno={1} errmsg={2}'.format(msg, errno, errmsg),
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
214 cmd)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
215
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
216
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
217 class SocketConnectError(WatchmanError):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
218 def __init__(self, sockpath, exc):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
219 super(SocketConnectError, self).__init__(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
220 'unable to connect to %s: %s' % (sockpath, exc))
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
221 self.sockpath = sockpath
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
222 self.exc = exc
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
223
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
224
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
225 class SocketTimeout(WatchmanError):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
226 """A specialized exception raised for socket timeouts during communication to/from watchman.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
227 This makes it easier to implement non-blocking loops as callers can easily distinguish
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
228 between a routine timeout and an actual error condition.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
229
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
230 Note that catching WatchmanError will also catch this as it is a super-class, so backwards
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
231 compatibility in exception handling is preserved.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
232 """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
233
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
234
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
235 class CommandError(WatchmanError):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
236 """error returned by watchman
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
237
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
238 self.msg is the message returned by watchman.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
239 """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
240 def __init__(self, msg, cmd=None):
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
241 super(CommandError, self).__init__(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
242 'watchman command error: %s' % (msg, ),
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
243 cmd,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
244 )
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
245
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
246
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
247 class Transport(object):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
248 """ communication transport to the watchman server """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
249 buf = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
250
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
251 def close(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
252 """ tear it down """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
253 raise NotImplementedError()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
254
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
255 def readBytes(self, size):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
256 """ read size bytes """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
257 raise NotImplementedError()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
258
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
259 def write(self, buf):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
260 """ write some data """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
261 raise NotImplementedError()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
262
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
263 def setTimeout(self, value):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
264 pass
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
265
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
266 def readLine(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
267 """ read a line
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
268 Maintains its own buffer, callers of the transport should not mix
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
269 calls to readBytes and readLine.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
270 """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
271 if self.buf is None:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
272 self.buf = []
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
273
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
274 # Buffer may already have a line if we've received unilateral
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
275 # response(s) from the server
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
276 if len(self.buf) == 1 and b"\n" in self.buf[0]:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
277 (line, b) = self.buf[0].split(b"\n", 1)
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
278 self.buf = [b]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
279 return line
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
280
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
281 while True:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
282 b = self.readBytes(4096)
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
283 if b"\n" in b:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
284 result = b''.join(self.buf)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
285 (line, b) = b.split(b"\n", 1)
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
286 self.buf = [b]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
287 return result + line
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
288 self.buf.append(b)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
289
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
290
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
291 class Codec(object):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
292 """ communication encoding for the watchman server """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
293 transport = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
294
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
295 def __init__(self, transport):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
296 self.transport = transport
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
297
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
298 def receive(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
299 raise NotImplementedError()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
300
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
301 def send(self, *args):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
302 raise NotImplementedError()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
303
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
304 def setTimeout(self, value):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
305 self.transport.setTimeout(value)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
306
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
307
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
308 class UnixSocketTransport(Transport):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
309 """ local unix domain socket transport """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
310 sock = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
311
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
312 def __init__(self, sockpath, timeout):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
313 self.sockpath = sockpath
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
314 self.timeout = timeout
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
315
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
316 sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
317 try:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
318 sock.settimeout(self.timeout)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
319 sock.connect(self.sockpath)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
320 self.sock = sock
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
321 except socket.error as e:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
322 sock.close()
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
323 raise SocketConnectError(self.sockpath, e)
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
324
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
325 def close(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
326 self.sock.close()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
327 self.sock = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
328
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
329 def setTimeout(self, value):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
330 self.timeout = value
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
331 self.sock.settimeout(self.timeout)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
332
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
333 def readBytes(self, size):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
334 try:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
335 buf = [self.sock.recv(size)]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
336 if not buf[0]:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
337 raise WatchmanError('empty watchman response')
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
338 return buf[0]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
339 except socket.timeout:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
340 raise SocketTimeout('timed out waiting for response')
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
341
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
342 def write(self, data):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
343 try:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
344 self.sock.sendall(data)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
345 except socket.timeout:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
346 raise SocketTimeout('timed out sending query command')
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
347
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
348
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
349 def _get_overlapped_result_ex_impl(pipe, olap, nbytes, millis, alertable):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
350 """ Windows 7 and earlier does not support GetOverlappedResultEx. The
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
351 alternative is to use GetOverlappedResult and wait for read or write
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
352 operation to complete. This is done be using CreateEvent and
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
353 WaitForSingleObjectEx. CreateEvent, WaitForSingleObjectEx
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
354 and GetOverlappedResult are all part of Windows API since WindowsXP.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
355 This is the exact same implementation that can be found in the watchman
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
356 source code (see get_overlapped_result_ex_impl in stream_win.c). This
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
357 way, maintenance should be simplified.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
358 """
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
359 log('Preparing to wait for maximum %dms', millis )
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
360 if millis != 0:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
361 waitReturnCode = WaitForSingleObjectEx(olap.hEvent, millis, alertable)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
362 if waitReturnCode == WAIT_OBJECT_0:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
363 # Event is signaled, overlapped IO operation result should be available.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
364 pass
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
365 elif waitReturnCode == WAIT_IO_COMPLETION:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
366 # WaitForSingleObjectEx returnes because the system added an I/O completion
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
367 # routine or an asynchronous procedure call (APC) to the thread queue.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
368 SetLastError(WAIT_IO_COMPLETION)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
369 pass
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
370 elif waitReturnCode == WAIT_TIMEOUT:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
371 # We reached the maximum allowed wait time, the IO operation failed
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
372 # to complete in timely fashion.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
373 SetLastError(WAIT_TIMEOUT)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
374 return False
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
375 elif waitReturnCode == WAIT_FAILED:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
376 # something went wrong calling WaitForSingleObjectEx
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
377 err = GetLastError()
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
378 log('WaitForSingleObjectEx failed: %s', _win32_strerror(err))
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
379 return False
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
380 else:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
381 # unexpected situation deserving investigation.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
382 err = GetLastError()
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
383 log('Unexpected error: %s', _win32_strerror(err))
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
384 return False
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
385
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
386 return GetOverlappedResult(pipe, olap, nbytes, False)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
387
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
388
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
389 class WindowsNamedPipeTransport(Transport):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
390 """ connect to a named pipe """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
391
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
392 def __init__(self, sockpath, timeout):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
393 self.sockpath = sockpath
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
394 self.timeout = int(math.ceil(timeout * 1000))
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
395 self._iobuf = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
396
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
397 self.pipe = CreateFile(sockpath, GENERIC_READ | GENERIC_WRITE, 0, None,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
398 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
399
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
400 if self.pipe == INVALID_HANDLE_VALUE:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
401 self.pipe = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
402 self._raise_win_err('failed to open pipe %s' % sockpath,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
403 GetLastError())
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
404
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
405 # event for the overlapped I/O operations
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
406 self._waitable = CreateEvent(None, True, False, None)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
407 if self._waitable is None:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
408 self._raise_win_err('CreateEvent failed', GetLastError())
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
409
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
410 self._get_overlapped_result_ex = GetOverlappedResultEx
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
411 if (os.getenv('WATCHMAN_WIN7_COMPAT') == '1' or
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
412 self._get_overlapped_result_ex is None):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
413 self._get_overlapped_result_ex = _get_overlapped_result_ex_impl
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
414
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
415 def _raise_win_err(self, msg, err):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
416 raise IOError('%s win32 error code: %d %s' %
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
417 (msg, err, _win32_strerror(err)))
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
418
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
419 def close(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
420 if self.pipe:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
421 log('Closing pipe')
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
422 CloseHandle(self.pipe)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
423 self.pipe = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
424
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
425 if self._waitable is not None:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
426 # We release the handle for the event
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
427 CloseHandle(self._waitable)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
428 self._waitable = None
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
429
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
430 def setTimeout(self, value):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
431 # convert to milliseconds
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
432 self.timeout = int(value * 1000)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
433
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
434 def readBytes(self, size):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
435 """ A read can block for an unbounded amount of time, even if the
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
436 kernel reports that the pipe handle is signalled, so we need to
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
437 always perform our reads asynchronously
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
438 """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
439
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
440 # try to satisfy the read from any buffered data
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
441 if self._iobuf:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
442 if size >= len(self._iobuf):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
443 res = self._iobuf
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
444 self.buf = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
445 return res
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
446 res = self._iobuf[:size]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
447 self._iobuf = self._iobuf[size:]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
448 return res
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
449
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
450 # We need to initiate a read
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
451 buf = ctypes.create_string_buffer(size)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
452 olap = OVERLAPPED()
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
453 olap.hEvent = self._waitable
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
454
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
455 log('made read buff of size %d', size)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
456
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
457 # ReadFile docs warn against sending in the nread parameter for async
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
458 # operations, so we always collect it via GetOverlappedResultEx
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
459 immediate = ReadFile(self.pipe, buf, size, None, olap)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
460
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
461 if not immediate:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
462 err = GetLastError()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
463 if err != ERROR_IO_PENDING:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
464 self._raise_win_err('failed to read %d bytes' % size,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
465 GetLastError())
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
466
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
467 nread = wintypes.DWORD()
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
468 if not self._get_overlapped_result_ex(self.pipe, olap, nread,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
469 0 if immediate else self.timeout,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
470 True):
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
471 err = GetLastError()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
472 CancelIoEx(self.pipe, olap)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
473
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
474 if err == WAIT_TIMEOUT:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
475 log('GetOverlappedResultEx timedout')
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
476 raise SocketTimeout('timed out after waiting %dms for read' %
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
477 self.timeout)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
478
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
479 log('GetOverlappedResultEx reports error %d', err)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
480 self._raise_win_err('error while waiting for read', err)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
481
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
482 nread = nread.value
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
483 if nread == 0:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
484 # Docs say that named pipes return 0 byte when the other end did
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
485 # a zero byte write. Since we don't ever do that, the only
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
486 # other way this shows up is if the client has gotten in a weird
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
487 # state, so let's bail out
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
488 CancelIoEx(self.pipe, olap)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
489 raise IOError('Async read yielded 0 bytes; unpossible!')
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
490
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
491 # Holds precisely the bytes that we read from the prior request
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
492 buf = buf[:nread]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
493
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
494 returned_size = min(nread, size)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
495 if returned_size == nread:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
496 return buf
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
497
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
498 # keep any left-overs around for a later read to consume
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
499 self._iobuf = buf[returned_size:]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
500 return buf[:returned_size]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
501
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
502 def write(self, data):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
503 olap = OVERLAPPED()
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
504 olap.hEvent = self._waitable
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
505
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
506 immediate = WriteFile(self.pipe, ctypes.c_char_p(data), len(data),
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
507 None, olap)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
508
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
509 if not immediate:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
510 err = GetLastError()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
511 if err != ERROR_IO_PENDING:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
512 self._raise_win_err('failed to write %d bytes' % len(data),
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
513 GetLastError())
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
514
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
515 # Obtain results, waiting if needed
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
516 nwrote = wintypes.DWORD()
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
517 if self._get_overlapped_result_ex(self.pipe, olap, nwrote,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
518 0 if immediate else self.timeout,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
519 True):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
520 log('made write of %d bytes', nwrote.value)
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
521 return nwrote.value
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
522
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
523 err = GetLastError()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
524
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
525 # It's potentially unsafe to allow the write to continue after
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
526 # we unwind, so let's make a best effort to avoid that happening
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
527 CancelIoEx(self.pipe, olap)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
528
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
529 if err == WAIT_TIMEOUT:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
530 raise SocketTimeout('timed out after waiting %dms for write' %
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
531 self.timeout)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
532 self._raise_win_err('error while waiting for write of %d bytes' %
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
533 len(data), err)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
534
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
535
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
536 class CLIProcessTransport(Transport):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
537 """ open a pipe to the cli to talk to the service
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
538 This intended to be used only in the test harness!
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
539
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
540 The CLI is an oddball because we only support JSON input
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
541 and cannot send multiple commands through the same instance,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
542 so we spawn a new process for each command.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
543
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
544 We disable server spawning for this implementation, again, because
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
545 it is intended to be used only in our test harness. You really
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
546 should not need to use the CLI transport for anything real.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
547
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
548 While the CLI can output in BSER, our Transport interface doesn't
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
549 support telling this instance that it should do so. That effectively
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
550 limits this implementation to JSON input and output only at this time.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
551
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
552 It is the responsibility of the caller to set the send and
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
553 receive codecs appropriately.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
554 """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
555 proc = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
556 closed = True
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
557
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
558 def __init__(self, sockpath, timeout):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
559 self.sockpath = sockpath
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
560 self.timeout = timeout
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
561
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
562 def close(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
563 if self.proc:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
564 if self.proc.pid is not None:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
565 self.proc.kill()
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
566 self.proc.stdin.close()
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
567 self.proc.stdout.close()
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
568 self.proc = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
569
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
570 def _connect(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
571 if self.proc:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
572 return self.proc
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
573 args = [
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
574 'watchman',
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
575 '--sockname={0}'.format(self.sockpath),
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
576 '--logfile=/BOGUS',
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
577 '--statefile=/BOGUS',
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
578 '--no-spawn',
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
579 '--no-local',
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
580 '--no-pretty',
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
581 '-j',
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
582 ]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
583 self.proc = subprocess.Popen(args,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
584 stdin=subprocess.PIPE,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
585 stdout=subprocess.PIPE)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
586 return self.proc
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
587
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
588 def readBytes(self, size):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
589 self._connect()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
590 res = self.proc.stdout.read(size)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
591 if res == '':
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
592 raise WatchmanError('EOF on CLI process transport')
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
593 return res
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
594
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
595 def write(self, data):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
596 if self.closed:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
597 self.close()
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
598 self.closed = False
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
599 self._connect()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
600 res = self.proc.stdin.write(data)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
601 self.proc.stdin.close()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
602 self.closed = True
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
603 return res
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
604
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
605
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
606 class BserCodec(Codec):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
607 """ use the BSER encoding. This is the default, preferred codec """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
608
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
609 def _loads(self, response):
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
610 return bser.loads(response) # Defaults to BSER v1
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
611
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
612 def receive(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
613 buf = [self.transport.readBytes(sniff_len)]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
614 if not buf[0]:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
615 raise WatchmanError('empty watchman response')
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
616
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
617 _1, _2, elen = bser.pdu_info(buf[0])
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
618
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
619 rlen = len(buf[0])
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
620 while elen > rlen:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
621 buf.append(self.transport.readBytes(elen - rlen))
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
622 rlen += len(buf[-1])
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
623
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
624 response = b''.join(buf)
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
625 try:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
626 res = self._loads(response)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
627 return res
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
628 except ValueError as e:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
629 raise WatchmanError('watchman response decode error: %s' % e)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
630
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
631 def send(self, *args):
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
632 cmd = bser.dumps(*args) # Defaults to BSER v1
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
633 self.transport.write(cmd)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
634
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
635
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
636 class ImmutableBserCodec(BserCodec):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
637 """ use the BSER encoding, decoding values using the newer
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
638 immutable object support """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
639
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
640 def _loads(self, response):
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
641 return bser.loads(response, False) # Defaults to BSER v1
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
642
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
643
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
644 class Bser2WithFallbackCodec(BserCodec):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
645 """ use BSER v2 encoding """
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
646
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
647 def __init__(self, transport):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
648 super(Bser2WithFallbackCodec, self).__init__(transport)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
649 # Once the server advertises support for bser-v2 we should switch this
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
650 # to 'required' on Python 3.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
651 self.send(["version", {"optional": ["bser-v2"]}])
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
652
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
653 capabilities = self.receive()
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
654
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
655 if 'error' in capabilities:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
656 raise Exception('Unsupported BSER version')
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
657
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
658 if capabilities['capabilities']['bser-v2']:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
659 self.bser_version = 2
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
660 self.bser_capabilities = 0
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
661 else:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
662 self.bser_version = 1
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
663 self.bser_capabilities = 0
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
664
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
665 def _loads(self, response):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
666 return bser.loads(response)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
667
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
668 def receive(self):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
669 buf = [self.transport.readBytes(sniff_len)]
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
670 if not buf[0]:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
671 raise WatchmanError('empty watchman response')
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
672
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
673 recv_bser_version, recv_bser_capabilities, elen = bser.pdu_info(buf[0])
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
674
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
675 if hasattr(self, 'bser_version'):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
676 # Readjust BSER version and capabilities if necessary
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
677 self.bser_version = max(self.bser_version, recv_bser_version)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
678 self.capabilities = self.bser_capabilities & recv_bser_capabilities
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
679
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
680 rlen = len(buf[0])
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
681 while elen > rlen:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
682 buf.append(self.transport.readBytes(elen - rlen))
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
683 rlen += len(buf[-1])
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
684
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
685 response = b''.join(buf)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
686 try:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
687 res = self._loads(response)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
688 return res
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
689 except ValueError as e:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
690 raise WatchmanError('watchman response decode error: %s' % e)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
691
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
692 def send(self, *args):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
693 if hasattr(self, 'bser_version'):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
694 cmd = bser.dumps(*args, version=self.bser_version,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
695 capabilities=self.bser_capabilities)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
696 else:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
697 cmd = bser.dumps(*args)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
698 self.transport.write(cmd)
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
699
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
700
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
701 class JsonCodec(Codec):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
702 """ Use json codec. This is here primarily for testing purposes """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
703 json = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
704
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
705 def __init__(self, transport):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
706 super(JsonCodec, self).__init__(transport)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
707 # optional dep on json, only if JsonCodec is used
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
708 import json
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
709 self.json = json
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
710
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
711 def receive(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
712 line = self.transport.readLine()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
713 try:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
714 # In Python 3, json.loads is a transformation from Unicode string to
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
715 # objects possibly containing Unicode strings. We typically expect
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
716 # the JSON blob to be ASCII-only with non-ASCII characters escaped,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
717 # but it's possible we might get non-ASCII bytes that are valid
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
718 # UTF-8.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
719 if compat.PYTHON3:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
720 line = line.decode('utf-8')
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
721 return self.json.loads(line)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
722 except Exception as e:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
723 print(e, line)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
724 raise
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
725
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
726 def send(self, *args):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
727 cmd = self.json.dumps(*args)
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
728 # In Python 3, json.dumps is a transformation from objects possibly
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
729 # containing Unicode strings to Unicode string. Even with (the default)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
730 # ensure_ascii=True, dumps returns a Unicode string.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
731 if compat.PYTHON3:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
732 cmd = cmd.encode('ascii')
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
733 self.transport.write(cmd + b"\n")
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
734
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
735
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
736 class client(object):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
737 """ Handles the communication with the watchman service """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
738 sockpath = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
739 transport = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
740 sendCodec = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
741 recvCodec = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
742 sendConn = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
743 recvConn = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
744 subs = {} # Keyed by subscription name
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
745 sub_by_root = {} # Keyed by root, then by subscription name
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
746 logs = [] # When log level is raised
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
747 unilateral = ['log', 'subscription']
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
748 tport = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
749 useImmutableBser = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
750
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
751 def __init__(self,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
752 sockpath=None,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
753 timeout=1.0,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
754 transport=None,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
755 sendEncoding=None,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
756 recvEncoding=None,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
757 useImmutableBser=False):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
758 self.sockpath = sockpath
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
759 self.timeout = timeout
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
760 self.useImmutableBser = useImmutableBser
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
761
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
762 if inspect.isclass(transport) and issubclass(transport, Transport):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
763 self.transport = transport
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
764 else:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
765 transport = transport or os.getenv('WATCHMAN_TRANSPORT') or 'local'
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
766 if transport == 'local' and os.name == 'nt':
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
767 self.transport = WindowsNamedPipeTransport
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
768 elif transport == 'local':
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
769 self.transport = UnixSocketTransport
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
770 elif transport == 'cli':
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
771 self.transport = CLIProcessTransport
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
772 if sendEncoding is None:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
773 sendEncoding = 'json'
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
774 if recvEncoding is None:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
775 recvEncoding = sendEncoding
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
776 else:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
777 raise WatchmanError('invalid transport %s' % transport)
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
778
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
779 sendEncoding = str(sendEncoding or os.getenv('WATCHMAN_ENCODING') or
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
780 'bser')
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
781 recvEncoding = str(recvEncoding or os.getenv('WATCHMAN_ENCODING') or
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
782 'bser')
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
783
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
784 self.recvCodec = self._parseEncoding(recvEncoding)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
785 self.sendCodec = self._parseEncoding(sendEncoding)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
786
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
787 def _parseEncoding(self, enc):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
788 if enc == 'bser':
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
789 if self.useImmutableBser:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
790 return ImmutableBserCodec
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
791 return BserCodec
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
792 elif enc == 'experimental-bser-v2':
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
793 return Bser2WithFallbackCodec
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
794 elif enc == 'json':
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
795 return JsonCodec
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
796 else:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
797 raise WatchmanError('invalid encoding %s' % enc)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
798
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
799 def _hasprop(self, result, name):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
800 if self.useImmutableBser:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
801 return hasattr(result, name)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
802 return name in result
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
803
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
804 def _resolvesockname(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
805 # if invoked via a trigger, watchman will set this env var; we
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
806 # should use it unless explicitly set otherwise
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
807 path = os.getenv('WATCHMAN_SOCK')
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
808 if path:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
809 return path
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
810
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
811 cmd = ['watchman', '--output-encoding=bser', 'get-sockname']
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
812 try:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
813 args = dict(stdout=subprocess.PIPE,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
814 stderr=subprocess.PIPE,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
815 close_fds=os.name != 'nt')
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
816
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
817 if os.name == 'nt':
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
818 # if invoked via an application with graphical user interface,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
819 # this call will cause a brief command window pop-up.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
820 # Using the flag STARTF_USESHOWWINDOW to avoid this behavior.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
821 startupinfo = subprocess.STARTUPINFO()
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
822 startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
823 args['startupinfo'] = startupinfo
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
824
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
825 p = subprocess.Popen(cmd, **args)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
826
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
827 except OSError as e:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
828 raise WatchmanError('"watchman" executable not in PATH (%s)', e)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
829
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
830 stdout, stderr = p.communicate()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
831 exitcode = p.poll()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
832
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
833 if exitcode:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
834 raise WatchmanError("watchman exited with code %d" % exitcode)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
835
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
836 result = bser.loads(stdout)
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
837 if b'error' in result:
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
838 raise WatchmanError('get-sockname error: %s' % result['error'])
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
839
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
840 return result[b'sockname']
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
841
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
842 def _connect(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
843 """ establish transport connection """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
844
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
845 if self.recvConn:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
846 return
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
847
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
848 if self.sockpath is None:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
849 self.sockpath = self._resolvesockname()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
850
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
851 self.tport = self.transport(self.sockpath, self.timeout)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
852 self.sendConn = self.sendCodec(self.tport)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
853 self.recvConn = self.recvCodec(self.tport)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
854
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
855 def __del__(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
856 self.close()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
857
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
858 def close(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
859 if self.tport:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
860 self.tport.close()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
861 self.tport = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
862 self.recvConn = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
863 self.sendConn = None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
864
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
865 def receive(self):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
866 """ receive the next PDU from the watchman service
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
867
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
868 If the client has activated subscriptions or logs then
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
869 this PDU may be a unilateral PDU sent by the service to
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
870 inform the client of a log event or subscription change.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
871
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
872 It may also simply be the response portion of a request
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
873 initiated by query.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
874
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
875 There are clients in production that subscribe and call
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
876 this in a loop to retrieve all subscription responses,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
877 so care should be taken when making changes here.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
878 """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
879
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
880 self._connect()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
881 result = self.recvConn.receive()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
882 if self._hasprop(result, 'error'):
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
883 error = result['error']
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
884 if compat.PYTHON3 and isinstance(self.recvConn, BserCodec):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
885 error = result['error'].decode('utf-8', 'surrogateescape')
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
886 raise CommandError(error)
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
887
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
888 if self._hasprop(result, 'log'):
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
889 log = result['log']
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
890 if compat.PYTHON3 and isinstance(self.recvConn, BserCodec):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
891 log = log.decode('utf-8', 'surrogateescape')
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
892 self.logs.append(log)
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
893
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
894 if self._hasprop(result, 'subscription'):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
895 sub = result['subscription']
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
896 if not (sub in self.subs):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
897 self.subs[sub] = []
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
898 self.subs[sub].append(result)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
899
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
900 # also accumulate in {root,sub} keyed store
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
901 root = os.path.normcase(result['root'])
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
902 if not root in self.sub_by_root:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
903 self.sub_by_root[root] = {}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
904 if not sub in self.sub_by_root[root]:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
905 self.sub_by_root[root][sub] = []
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
906 self.sub_by_root[root][sub].append(result)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
907
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
908 return result
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
909
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
910 def isUnilateralResponse(self, res):
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
911 if 'unilateral' in res and res['unilateral']:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
912 return True
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
913 # Fall back to checking for known unilateral responses
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
914 for k in self.unilateral:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
915 if k in res:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
916 return True
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
917 return False
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
918
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
919 def getLog(self, remove=True):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
920 """ Retrieve buffered log data
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
921
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
922 If remove is true the data will be removed from the buffer.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
923 Otherwise it will be left in the buffer
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
924 """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
925 res = self.logs
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
926 if remove:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
927 self.logs = []
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
928 return res
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
929
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
930 def getSubscription(self, name, remove=True, root=None):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
931 """ Retrieve the data associated with a named subscription
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
932
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
933 If remove is True (the default), the subscription data is removed
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
934 from the buffer. Otherwise the data is returned but left in
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
935 the buffer.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
936
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
937 Returns None if there is no data associated with `name`
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
938
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
939 If root is not None, then only return the subscription
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
940 data that matches both root and name. When used in this way,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
941 remove processing impacts both the unscoped and scoped stores
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
942 for the subscription data.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
943 """
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
944 if compat.PYTHON3 and issubclass(self.recvCodec, BserCodec):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
945 # People may pass in Unicode strings here -- but currently BSER only
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
946 # returns bytestrings. Deal with that.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
947 if isinstance(root, str):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
948 root = encoding.encode_local(root)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
949 if isinstance(name, str):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
950 name = name.encode('utf-8')
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
951
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
952 if root is not None:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
953 if not root in self.sub_by_root:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
954 return None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
955 if not name in self.sub_by_root[root]:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
956 return None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
957 sub = self.sub_by_root[root][name]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
958 if remove:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
959 del self.sub_by_root[root][name]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
960 # don't let this grow unbounded
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
961 if name in self.subs:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
962 del self.subs[name]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
963 return sub
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
964
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
965 if not (name in self.subs):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
966 return None
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
967 sub = self.subs[name]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
968 if remove:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
969 del self.subs[name]
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
970 return sub
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
971
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
972 def query(self, *args):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
973 """ Send a query to the watchman service and return the response
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
974
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
975 This call will block until the response is returned.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
976 If any unilateral responses are sent by the service in between
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
977 the request-response they will be buffered up in the client object
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
978 and NOT returned via this method.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
979 """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
980
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
981 log('calling client.query')
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
982 self._connect()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
983 try:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
984 self.sendConn.send(args)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
985
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
986 res = self.receive()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
987 while self.isUnilateralResponse(res):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
988 res = self.receive()
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
989
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
990 return res
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
991 except EnvironmentError as ee:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
992 # When we can depend on Python 3, we can use PEP 3134
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
993 # exception chaining here.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
994 raise WatchmanEnvironmentError(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
995 'I/O error communicating with watchman daemon',
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
996 ee.errno,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
997 ee.strerror,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
998 args)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
999 except WatchmanError as ex:
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1000 ex.setCommand(args)
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28432
diff changeset
1001 raise
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1002
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1003 def capabilityCheck(self, optional=None, required=None):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1004 """ Perform a server capability check """
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1005 res = self.query('version', {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1006 'optional': optional or [],
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1007 'required': required or []
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1008 })
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1009
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1010 if not self._hasprop(res, 'capabilities'):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1011 # Server doesn't support capabilities, so we need to
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1012 # synthesize the results based on the version
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1013 capabilities.synthesize(res, optional)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1014 if 'error' in res:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1015 raise CommandError(res['error'])
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1016
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1017 return res
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1018
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1019 def setTimeout(self, value):
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1020 self.recvConn.setTimeout(value)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1021 self.sendConn.setTimeout(value)