Handle SIGWINCH
This commit is contained in:
		
							parent
							
								
									ec9e0c03c3
								
							
						
					
					
						commit
						db1d45037c
					
				
					 3 changed files with 39 additions and 8 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue