1
0
mirror of https://github.com/openSUSE/osc.git synced 2024-09-19 16:56:17 +02:00
github.com_openSUSE_osc/osc-wrapper.py
Marcus Huewe 5d6a1cef4d Make stderr line buffered if it does not refer to a tty
If osc is invoked, for instance, via "osc -d rbl ... > log.txt 2>&1",
writes to stderr and stdout do not necessarily appear in program order
in the log.txt file. More precisely, it is possible that the buildlog
comes first and the http debug output is at the end of the
file.
During osc/python3 startup (with the redirection from above), the
following is done:
- make stdout line buffered (due to the code in osc-wrapper.py)
- make stderr buffered (but not line buffered) because stderr does
  not refer to a tty (python3 startup)

Consequently, if osc has code like

print("foo")
print("bar", file=sys.stderr)
print("baz")

it is possible that the contents of the log.txt is

foo
baz
bar

because stderr is buffered (but not line buffered). In order to fix
this, make stderr line buffered, too.
2021-03-24 14:13:38 +01:00

47 lines
1.7 KiB
Python
Executable File

#!/usr/bin/env python
# this wrapper exists so it can be put into /usr/bin, but still allows the
# python module to be called within the source directory during development
import locale
import sys
import os
from osc import commandline, babysitter
try:
# this is a hack to make osc work as expected with utf-8 characters,
# no matter how site.py is set...
reload(sys)
loc = locale.getpreferredencoding()
if not loc:
loc = sys.getpreferredencoding()
sys.setdefaultencoding(loc)
del sys.setdefaultencoding
except NameError:
#reload, neither setdefaultencoding are in python3
pass
# avoid buffering output on pipes (bnc#930137)
# Note: the following only applies to python2
# Basically, a "print('foo')" call is translated to a corresponding
# fwrite call that writes to the stdout stream (cf. string_print
# (Objects/stringobject.c) and builtin_print (Python/bltinmodule.c));
# If no pipe is used, stdout is a tty/refers to a terminal =>
# the stream is line buffered (see _IO_file_doallocate (libio/filedoalloc.c)).
# If a pipe is used, stdout does not refer to a terminal anymore =>
# the stream is fully buffered by default (see _IO_file_doallocate).
# The following fdopen call makes stdout line buffered again (at least on
# systems that support setvbuf - if setvbuf is not supported, the stream
# remains fully buffered (see PyFile_SetBufSize (Objects/fileobject.c))).
if not os.isatty(sys.stdout.fileno()):
sys.stdout = os.fdopen(sys.stdout.fileno(), sys.stdout.mode, 1)
if not os.isatty(sys.stderr.fileno()):
sys.stderr = os.fdopen(sys.stderr.fileno(), sys.stderr.mode, 1)
osccli = commandline.Osc()
r = babysitter.run(osccli)
sys.exit(r)