forked from lix-project/lix
Handle SIGWINCH
This commit is contained in:
parent
ec9e0c03c3
commit
db1d45037c
|
@ -17,6 +17,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -1254,6 +1255,26 @@ void callFailure(const std::function<void(std::exception_ptr exc)> & failure, st
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Sync<std::pair<unsigned short, unsigned short>> windowSize{{0, 0}};
|
||||||
|
|
||||||
|
|
||||||
|
static void updateWindowSize()
|
||||||
|
{
|
||||||
|
struct winsize ws;
|
||||||
|
if (ioctl(1, TIOCGWINSZ, &ws) == 0) {
|
||||||
|
auto windowSize_(windowSize.lock());
|
||||||
|
windowSize_->first = ws.ws_row;
|
||||||
|
windowSize_->second = ws.ws_col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::pair<unsigned short, unsigned short> getWindowSize()
|
||||||
|
{
|
||||||
|
return *windowSize.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static Sync<std::list<std::function<void()>>> _interruptCallbacks;
|
static Sync<std::list<std::function<void()>>> _interruptCallbacks;
|
||||||
|
|
||||||
static void signalHandlerThread(sigset_t set)
|
static void signalHandlerThread(sigset_t set)
|
||||||
|
@ -1264,6 +1285,10 @@ static void signalHandlerThread(sigset_t set)
|
||||||
|
|
||||||
if (signal == SIGINT || signal == SIGTERM || signal == SIGHUP)
|
if (signal == SIGINT || signal == SIGTERM || signal == SIGHUP)
|
||||||
triggerInterrupt();
|
triggerInterrupt();
|
||||||
|
|
||||||
|
else if (signal == SIGWINCH) {
|
||||||
|
updateWindowSize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1287,6 +1312,8 @@ static sigset_t savedSignalMask;
|
||||||
|
|
||||||
void startSignalHandlerThread()
|
void startSignalHandlerThread()
|
||||||
{
|
{
|
||||||
|
updateWindowSize();
|
||||||
|
|
||||||
if (sigprocmask(SIG_BLOCK, nullptr, &savedSignalMask))
|
if (sigprocmask(SIG_BLOCK, nullptr, &savedSignalMask))
|
||||||
throw SysError("quering signal mask");
|
throw SysError("quering signal mask");
|
||||||
|
|
||||||
|
@ -1296,6 +1323,7 @@ void startSignalHandlerThread()
|
||||||
sigaddset(&set, SIGTERM);
|
sigaddset(&set, SIGTERM);
|
||||||
sigaddset(&set, SIGHUP);
|
sigaddset(&set, SIGHUP);
|
||||||
sigaddset(&set, SIGPIPE);
|
sigaddset(&set, SIGPIPE);
|
||||||
|
sigaddset(&set, SIGWINCH);
|
||||||
if (pthread_sigmask(SIG_BLOCK, &set, nullptr))
|
if (pthread_sigmask(SIG_BLOCK, &set, nullptr))
|
||||||
throw SysError("blocking signals");
|
throw SysError("blocking signals");
|
||||||
|
|
||||||
|
|
|
@ -349,6 +349,12 @@ bool hasSuffix(const string & s, const string & suffix);
|
||||||
std::string toLower(const std::string & s);
|
std::string toLower(const std::string & s);
|
||||||
|
|
||||||
|
|
||||||
|
/* Escape a string that contains octal-encoded escape codes such as
|
||||||
|
used in /etc/fstab and /proc/mounts (e.g. "foo\040bar" decodes to
|
||||||
|
"foo bar"). */
|
||||||
|
string decodeOctalEscaped(const string & s);
|
||||||
|
|
||||||
|
|
||||||
/* Exception handling in destructors: print an error message, then
|
/* Exception handling in destructors: print an error message, then
|
||||||
ignore the exception. */
|
ignore the exception. */
|
||||||
void ignoreException();
|
void ignoreException();
|
||||||
|
@ -470,4 +476,8 @@ struct MaintainCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the number of rows and columns of the terminal. */
|
||||||
|
std::pair<unsigned short, unsigned short> getWindowSize();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
static std::string getS(const std::vector<Logger::Field> & fields, size_t n)
|
static std::string getS(const std::vector<Logger::Field> & fields, size_t n)
|
||||||
|
@ -99,15 +97,10 @@ private:
|
||||||
|
|
||||||
Sync<State> state_;
|
Sync<State> state_;
|
||||||
|
|
||||||
int width = 0;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ProgressBar()
|
ProgressBar()
|
||||||
{
|
{
|
||||||
struct winsize ws;
|
|
||||||
if (ioctl(1, TIOCGWINSZ, &ws) == 0)
|
|
||||||
width = ws.ws_col;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~ProgressBar()
|
~ProgressBar()
|
||||||
|
@ -270,7 +263,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeToStderr("\r" + ansiTruncate(line, width) + "\e[K");
|
writeToStderr("\r" + ansiTruncate(line, getWindowSize().second) + "\e[K");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getStatus(State & state)
|
std::string getStatus(State & state)
|
||||||
|
|
Loading…
Reference in a new issue