blob: c6211419b892ba7f6e843bbd6aca8a81e0f6cf11 [file] [log] [blame]
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -07001#
2# Copyright (C) 2008 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
Sarah Owenscecd1d82012-11-01 22:59:27 -070016from __future__ import print_function
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070017import os
18import select
19import sys
20
21active = False
22
23def RunPager(globalConfig):
24 global active
25
Shawn O. Pearce8f82a4f2009-04-01 07:24:22 -070026 if not os.isatty(0) or not os.isatty(1):
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070027 return
28 pager = _SelectPager(globalConfig)
29 if pager == '' or pager == 'cat':
30 return
31
32 # This process turns into the pager; a child it forks will
33 # do the real processing and output back to the pager. This
34 # is necessary to keep the pager in control of the tty.
35 #
36 try:
37 r, w = os.pipe()
38 pid = os.fork()
39 if not pid:
40 os.dup2(w, 1)
41 os.dup2(w, 2)
42 os.close(r)
43 os.close(w)
44 active = True
45 return
46
47 os.dup2(r, 0)
48 os.close(r)
49 os.close(w)
50
51 _BecomePager(pager)
52 except Exception:
Sarah Owenscecd1d82012-11-01 22:59:27 -070053 print("fatal: cannot start pager '%s'" % pager, file=sys.stderr)
David Pursehouse01f443d2012-10-03 19:11:28 +090054 sys.exit(255)
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070055
56def _SelectPager(globalConfig):
57 try:
58 return os.environ['GIT_PAGER']
59 except KeyError:
60 pass
61
62 pager = globalConfig.GetString('core.pager')
63 if pager:
64 return pager
65
66 try:
67 return os.environ['PAGER']
68 except KeyError:
69 pass
70
71 return 'less'
72
73def _BecomePager(pager):
74 # Delaying execution of the pager until we have output
75 # ready works around a long-standing bug in popularly
76 # available versions of 'less', a better 'more'.
77 #
David Pursehouse8a68ff92012-09-24 12:15:13 +090078 _a, _b, _c = select.select([0], [], [0])
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070079
80 os.environ['LESS'] = 'FRSX'
81
82 try:
83 os.execvp(pager, [pager])
David Pursehouse8a68ff92012-09-24 12:15:13 +090084 except OSError:
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070085 os.execv('/bin/sh', ['sh', '-c', pager])