Statistics
| Branch: | Tag: | Revision:

root / lib / utils / wrapper.py @ 9a6813ac

History | View | Annotate | Download (4.8 kB)

1 7831fc5f Michael Hanselmann
#
2 7831fc5f Michael Hanselmann
#
3 7831fc5f Michael Hanselmann
4 7831fc5f Michael Hanselmann
# Copyright (C) 2006, 2007, 2010, 2011 Google Inc.
5 7831fc5f Michael Hanselmann
#
6 7831fc5f Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 7831fc5f Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 7831fc5f Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 7831fc5f Michael Hanselmann
# (at your option) any later version.
10 7831fc5f Michael Hanselmann
#
11 7831fc5f Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 7831fc5f Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 7831fc5f Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 7831fc5f Michael Hanselmann
# General Public License for more details.
15 7831fc5f Michael Hanselmann
#
16 7831fc5f Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 7831fc5f Michael Hanselmann
# along with this program; if not, write to the Free Software
18 7831fc5f Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 7831fc5f Michael Hanselmann
# 02110-1301, USA.
20 7831fc5f Michael Hanselmann
21 7831fc5f Michael Hanselmann
"""Utility functions wrapping other functions.
22 7831fc5f Michael Hanselmann

23 7831fc5f Michael Hanselmann
"""
24 7831fc5f Michael Hanselmann
25 7831fc5f Michael Hanselmann
import time
26 7831fc5f Michael Hanselmann
import socket
27 7831fc5f Michael Hanselmann
import errno
28 7831fc5f Michael Hanselmann
import tempfile
29 7831fc5f Michael Hanselmann
import fcntl
30 7831fc5f Michael Hanselmann
import os
31 7831fc5f Michael Hanselmann
import select
32 44c9b4fe Michael Hanselmann
import logging
33 7831fc5f Michael Hanselmann
34 7831fc5f Michael Hanselmann
35 7831fc5f Michael Hanselmann
def TestDelay(duration):
36 7831fc5f Michael Hanselmann
  """Sleep for a fixed amount of time.
37 7831fc5f Michael Hanselmann

38 7831fc5f Michael Hanselmann
  @type duration: float
39 7831fc5f Michael Hanselmann
  @param duration: the sleep duration
40 7831fc5f Michael Hanselmann
  @rtype: boolean
41 7831fc5f Michael Hanselmann
  @return: False for negative value, True otherwise
42 7831fc5f Michael Hanselmann

43 7831fc5f Michael Hanselmann
  """
44 7831fc5f Michael Hanselmann
  if duration < 0:
45 7831fc5f Michael Hanselmann
    return False, "Invalid sleep duration"
46 7831fc5f Michael Hanselmann
  time.sleep(duration)
47 7831fc5f Michael Hanselmann
  return True, None
48 7831fc5f Michael Hanselmann
49 7831fc5f Michael Hanselmann
50 7831fc5f Michael Hanselmann
def CloseFdNoError(fd, retries=5):
51 7831fc5f Michael Hanselmann
  """Close a file descriptor ignoring errors.
52 7831fc5f Michael Hanselmann

53 7831fc5f Michael Hanselmann
  @type fd: int
54 7831fc5f Michael Hanselmann
  @param fd: the file descriptor
55 7831fc5f Michael Hanselmann
  @type retries: int
56 7831fc5f Michael Hanselmann
  @param retries: how many retries to make, in case we get any
57 7831fc5f Michael Hanselmann
      other error than EBADF
58 7831fc5f Michael Hanselmann

59 7831fc5f Michael Hanselmann
  """
60 7831fc5f Michael Hanselmann
  try:
61 7831fc5f Michael Hanselmann
    os.close(fd)
62 7831fc5f Michael Hanselmann
  except OSError, err:
63 7831fc5f Michael Hanselmann
    if err.errno != errno.EBADF:
64 7831fc5f Michael Hanselmann
      if retries > 0:
65 7831fc5f Michael Hanselmann
        CloseFdNoError(fd, retries - 1)
66 7831fc5f Michael Hanselmann
    # else either it's closed already or we're out of retries, so we
67 7831fc5f Michael Hanselmann
    # ignore this and go on
68 7831fc5f Michael Hanselmann
69 7831fc5f Michael Hanselmann
70 7831fc5f Michael Hanselmann
def SetCloseOnExecFlag(fd, enable):
71 7831fc5f Michael Hanselmann
  """Sets or unsets the close-on-exec flag on a file descriptor.
72 7831fc5f Michael Hanselmann

73 7831fc5f Michael Hanselmann
  @type fd: int
74 7831fc5f Michael Hanselmann
  @param fd: File descriptor
75 7831fc5f Michael Hanselmann
  @type enable: bool
76 7831fc5f Michael Hanselmann
  @param enable: Whether to set or unset it.
77 7831fc5f Michael Hanselmann

78 7831fc5f Michael Hanselmann
  """
79 7831fc5f Michael Hanselmann
  flags = fcntl.fcntl(fd, fcntl.F_GETFD)
80 7831fc5f Michael Hanselmann
81 7831fc5f Michael Hanselmann
  if enable:
82 7831fc5f Michael Hanselmann
    flags |= fcntl.FD_CLOEXEC
83 7831fc5f Michael Hanselmann
  else:
84 7831fc5f Michael Hanselmann
    flags &= ~fcntl.FD_CLOEXEC
85 7831fc5f Michael Hanselmann
86 7831fc5f Michael Hanselmann
  fcntl.fcntl(fd, fcntl.F_SETFD, flags)
87 7831fc5f Michael Hanselmann
88 7831fc5f Michael Hanselmann
89 7831fc5f Michael Hanselmann
def SetNonblockFlag(fd, enable):
90 7831fc5f Michael Hanselmann
  """Sets or unsets the O_NONBLOCK flag on on a file descriptor.
91 7831fc5f Michael Hanselmann

92 7831fc5f Michael Hanselmann
  @type fd: int
93 7831fc5f Michael Hanselmann
  @param fd: File descriptor
94 7831fc5f Michael Hanselmann
  @type enable: bool
95 7831fc5f Michael Hanselmann
  @param enable: Whether to set or unset it
96 7831fc5f Michael Hanselmann

97 7831fc5f Michael Hanselmann
  """
98 7831fc5f Michael Hanselmann
  flags = fcntl.fcntl(fd, fcntl.F_GETFL)
99 7831fc5f Michael Hanselmann
100 7831fc5f Michael Hanselmann
  if enable:
101 7831fc5f Michael Hanselmann
    flags |= os.O_NONBLOCK
102 7831fc5f Michael Hanselmann
  else:
103 7831fc5f Michael Hanselmann
    flags &= ~os.O_NONBLOCK
104 7831fc5f Michael Hanselmann
105 7831fc5f Michael Hanselmann
  fcntl.fcntl(fd, fcntl.F_SETFL, flags)
106 7831fc5f Michael Hanselmann
107 7831fc5f Michael Hanselmann
108 7831fc5f Michael Hanselmann
def RetryOnSignal(fn, *args, **kwargs):
109 7831fc5f Michael Hanselmann
  """Calls a function again if it failed due to EINTR.
110 7831fc5f Michael Hanselmann

111 7831fc5f Michael Hanselmann
  """
112 7831fc5f Michael Hanselmann
  while True:
113 7831fc5f Michael Hanselmann
    try:
114 7831fc5f Michael Hanselmann
      return fn(*args, **kwargs)
115 7831fc5f Michael Hanselmann
    except EnvironmentError, err:
116 7831fc5f Michael Hanselmann
      if err.errno != errno.EINTR:
117 7831fc5f Michael Hanselmann
        raise
118 7831fc5f Michael Hanselmann
    except (socket.error, select.error), err:
119 7831fc5f Michael Hanselmann
      # In python 2.6 and above select.error is an IOError, so it's handled
120 7831fc5f Michael Hanselmann
      # above, in 2.5 and below it's not, and it's handled here.
121 7831fc5f Michael Hanselmann
      if not (err.args and err.args[0] == errno.EINTR):
122 7831fc5f Michael Hanselmann
        raise
123 7831fc5f Michael Hanselmann
124 7831fc5f Michael Hanselmann
125 7831fc5f Michael Hanselmann
def IgnoreProcessNotFound(fn, *args, **kwargs):
126 7831fc5f Michael Hanselmann
  """Ignores ESRCH when calling a process-related function.
127 7831fc5f Michael Hanselmann

128 7831fc5f Michael Hanselmann
  ESRCH is raised when a process is not found.
129 7831fc5f Michael Hanselmann

130 7831fc5f Michael Hanselmann
  @rtype: bool
131 7831fc5f Michael Hanselmann
  @return: Whether process was found
132 7831fc5f Michael Hanselmann

133 7831fc5f Michael Hanselmann
  """
134 7831fc5f Michael Hanselmann
  try:
135 7831fc5f Michael Hanselmann
    fn(*args, **kwargs)
136 7831fc5f Michael Hanselmann
  except EnvironmentError, err:
137 7831fc5f Michael Hanselmann
    # Ignore ESRCH
138 7831fc5f Michael Hanselmann
    if err.errno == errno.ESRCH:
139 7831fc5f Michael Hanselmann
      return False
140 7831fc5f Michael Hanselmann
    raise
141 7831fc5f Michael Hanselmann
142 7831fc5f Michael Hanselmann
  return True
143 7831fc5f Michael Hanselmann
144 7831fc5f Michael Hanselmann
145 7831fc5f Michael Hanselmann
def IgnoreSignals(fn, *args, **kwargs):
146 7831fc5f Michael Hanselmann
  """Tries to call a function ignoring failures due to EINTR.
147 7831fc5f Michael Hanselmann

148 7831fc5f Michael Hanselmann
  """
149 7831fc5f Michael Hanselmann
  try:
150 7831fc5f Michael Hanselmann
    return fn(*args, **kwargs)
151 7831fc5f Michael Hanselmann
  except EnvironmentError, err:
152 7831fc5f Michael Hanselmann
    if err.errno == errno.EINTR:
153 7831fc5f Michael Hanselmann
      return None
154 7831fc5f Michael Hanselmann
    else:
155 7831fc5f Michael Hanselmann
      raise
156 7831fc5f Michael Hanselmann
  except (select.error, socket.error), err:
157 7831fc5f Michael Hanselmann
    # In python 2.6 and above select.error is an IOError, so it's handled
158 7831fc5f Michael Hanselmann
    # above, in 2.5 and below it's not, and it's handled here.
159 7831fc5f Michael Hanselmann
    if err.args and err.args[0] == errno.EINTR:
160 7831fc5f Michael Hanselmann
      return None
161 7831fc5f Michael Hanselmann
    else:
162 7831fc5f Michael Hanselmann
      raise
163 7831fc5f Michael Hanselmann
164 7831fc5f Michael Hanselmann
165 7831fc5f Michael Hanselmann
def GetClosedTempfile(*args, **kwargs):
166 7831fc5f Michael Hanselmann
  """Creates a temporary file and returns its path.
167 7831fc5f Michael Hanselmann

168 7831fc5f Michael Hanselmann
  """
169 7831fc5f Michael Hanselmann
  (fd, path) = tempfile.mkstemp(*args, **kwargs)
170 7831fc5f Michael Hanselmann
  CloseFdNoError(fd)
171 7831fc5f Michael Hanselmann
  return path
172 44c9b4fe Michael Hanselmann
173 44c9b4fe Michael Hanselmann
174 44c9b4fe Michael Hanselmann
def ResetTempfileModule():
175 44c9b4fe Michael Hanselmann
  """Resets the random name generator of the tempfile module.
176 44c9b4fe Michael Hanselmann

177 44c9b4fe Michael Hanselmann
  This function should be called after C{os.fork} in the child process to
178 44c9b4fe Michael Hanselmann
  ensure it creates a newly seeded random generator. Otherwise it would
179 44c9b4fe Michael Hanselmann
  generate the same random parts as the parent process. If several processes
180 44c9b4fe Michael Hanselmann
  race for the creation of a temporary file, this could lead to one not getting
181 44c9b4fe Michael Hanselmann
  a temporary name.
182 44c9b4fe Michael Hanselmann

183 44c9b4fe Michael Hanselmann
  """
184 44c9b4fe Michael Hanselmann
  # pylint: disable-msg=W0212
185 44c9b4fe Michael Hanselmann
  if hasattr(tempfile, "_once_lock") and hasattr(tempfile, "_name_sequence"):
186 44c9b4fe Michael Hanselmann
    tempfile._once_lock.acquire()
187 44c9b4fe Michael Hanselmann
    try:
188 44c9b4fe Michael Hanselmann
      # Reset random name generator
189 44c9b4fe Michael Hanselmann
      tempfile._name_sequence = None
190 44c9b4fe Michael Hanselmann
    finally:
191 44c9b4fe Michael Hanselmann
      tempfile._once_lock.release()
192 44c9b4fe Michael Hanselmann
  else:
193 44c9b4fe Michael Hanselmann
    logging.critical("The tempfile module misses at least one of the"
194 44c9b4fe Michael Hanselmann
                     " '_once_lock' and '_name_sequence' attributes")