82 lines
2.1 KiB
PHP
82 lines
2.1 KiB
PHP
<?php
|
|
/**
|
|
* ext-ioctl/examples/winsize.php
|
|
*
|
|
* A simple example for using the ioctl() system call.
|
|
* Get the current windows size of this TTY.
|
|
* This script only works if you are using PHP-CLI on a TTY.
|
|
*
|
|
* @author CismonX
|
|
*/
|
|
|
|
// Constants defined in sys/ioctl.h
|
|
const TIOCGWINSZ = 0x5413;
|
|
|
|
// We need `pcntl_signal()` for this example.
|
|
if (!extension_loaded('pcntl')) {
|
|
echo 'To try this example, please install pcntl extension.', PHP_EOL;
|
|
exit;
|
|
}
|
|
|
|
// Get file descriptor of current TTY.
|
|
$handle = fopen(rtrim(`tty`), 'r+');
|
|
if ($handle === false) {
|
|
echo 'To try this example, please run PHP-CLI on a TTY.', PHP_EOL;
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Fetch current TTY window size.
|
|
*
|
|
* @param resource $handle
|
|
* @return array|false
|
|
*/
|
|
function get_window_size($handle) {
|
|
// See definition of struct winsize:
|
|
//
|
|
// struct winsize {
|
|
// unsigned short ws_row;
|
|
// unsigned short ws_col;
|
|
// unsigned short ws_xpixel; /* unused */
|
|
// unsigned short ws_ypixel; /* unused */
|
|
// };
|
|
//
|
|
// Assuming we're on a 64-bit platform, an unsigned short usually contains 16 bits.
|
|
// So we should allocate an 8-byte buffer.
|
|
$buffer = str_alloc(8);
|
|
|
|
// Fetch current window size via ioctl().
|
|
$result = ioctl($handle, TIOCGWINSZ, $buffer, $errno);
|
|
if ($result === false) {
|
|
return false;
|
|
}
|
|
|
|
// Unpack the buffer into an array of four integers.
|
|
return unpack('S4', $buffer);
|
|
}
|
|
|
|
// Get current window size.
|
|
$winsize = get_window_size($handle);
|
|
if (!$winsize) {
|
|
echo 'Failed to get window size. ', posix_strerror($errno), PHP_EOL;
|
|
exit;
|
|
}
|
|
[, $height, $width] = $winsize;
|
|
echo "Window height: $height, width: $width. Try resize window or press Ctrl+C to quit.", PHP_EOL;
|
|
|
|
// Enable asynchronous signal handling.
|
|
pcntl_async_signals(true);
|
|
|
|
// Register signal handler which gets invoked when window size changes.
|
|
pcntl_signal(SIGWINCH, function ($signo) use ($handle) {
|
|
$winsize = get_window_size($handle);
|
|
if ($winsize) {
|
|
[, $height, $width] = $winsize;
|
|
echo "SIGWINCH caught. Window height: $height, width: $width.", PHP_EOL;
|
|
}
|
|
});
|
|
|
|
while (1) {
|
|
sleep(1);
|
|
}
|