Lines 5-10
Link Here
|
5 |
# This is a helper which ebuild processes can use |
5 |
# This is a helper which ebuild processes can use |
6 |
# to communicate with portage's main python process. |
6 |
# to communicate with portage's main python process. |
7 |
|
7 |
|
|
|
8 |
import errno |
8 |
import logging |
9 |
import logging |
9 |
import os |
10 |
import os |
10 |
import pickle |
11 |
import pickle |
Lines 44-62
import portage
Link Here
|
44 |
portage._internal_caller = True |
45 |
portage._internal_caller = True |
45 |
portage._disable_legacy_globals() |
46 |
portage._disable_legacy_globals() |
46 |
|
47 |
|
47 |
from portage.util._async.ForkProcess import ForkProcess |
|
|
48 |
from portage.util._eventloop.global_event_loop import global_event_loop |
48 |
from portage.util._eventloop.global_event_loop import global_event_loop |
|
|
49 |
from _emerge.AbstractPollTask import AbstractPollTask |
49 |
from _emerge.PipeReader import PipeReader |
50 |
from _emerge.PipeReader import PipeReader |
50 |
|
51 |
|
51 |
class FifoWriter(ForkProcess): |
52 |
RETURNCODE_WRITE_FAILED = 2 |
52 |
|
53 |
|
53 |
__slots__ = ('buf', 'fifo',) |
54 |
class FifoWriter(AbstractPollTask): |
54 |
|
55 |
|
55 |
def _run(self): |
56 |
__slots__ = ('buf', 'fifo', '_fd', '_reg_id',) |
56 |
# Atomically write the whole buffer into the fifo. |
57 |
|
57 |
with open(self.fifo, 'wb', 0) as f: |
58 |
def _start(self): |
58 |
f.write(self.buf) |
59 |
try: |
59 |
return os.EX_OK |
60 |
self._fd = os.open(self.fifo, os.O_WRONLY|os.O_NONBLOCK) |
|
|
61 |
except OSError as e: |
62 |
if e.errno == errno.ENXIO: |
63 |
# This happens if the daemon has been killed. |
64 |
self.returncode = RETURNCODE_WRITE_FAILED |
65 |
self._unregister() |
66 |
self._async_wait() |
67 |
return |
68 |
else: |
69 |
raise |
70 |
self._reg_id = self.scheduler.io_add_watch( |
71 |
self._fd, |
72 |
self.scheduler.IO_OUT | self.scheduler.IO_HUP | \ |
73 |
self._exceptional_events, self._output_handler) |
74 |
self._registered = True |
75 |
|
76 |
def _output_handler(self, fd, event): |
77 |
if event & self.scheduler.IO_OUT: |
78 |
# The whole buf should be able to fit in the fifo with |
79 |
# a single write call, so there's no valid reason for |
80 |
# os.write to raise EAGAIN here. |
81 |
buf = self.buf |
82 |
while buf: |
83 |
buf = buf[os.write(fd, buf):] |
84 |
self.returncode = os.EX_OK |
85 |
self._unregister() |
86 |
self.wait() |
87 |
return False |
88 |
else: |
89 |
self._unregister_if_appropriate(event) |
90 |
if not self._registered: |
91 |
self.returncode = RETURNCODE_WRITE_FAILED |
92 |
self.wait() |
93 |
return False |
94 |
return True |
95 |
|
96 |
def _cancel(self): |
97 |
self.returncode = self._cancelled_returncode |
98 |
self._unregister() |
99 |
|
100 |
def _unregister(self): |
101 |
self._registered = False |
102 |
if self._reg_id is not None: |
103 |
self.scheduler.source_remove(self._reg_id) |
104 |
self._reg_id = None |
105 |
if self._fd is not None: |
106 |
os.close(self._fd) |
107 |
self._fd = None |
60 |
|
108 |
|
61 |
class EbuildIpc(object): |
109 |
class EbuildIpc(object): |
62 |
|
110 |
|
63 |
- |
|
|