1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 11:57:35 +00:00

ls: Don't layout or colorize output if stdout is not a TTY

This commit is contained in:
Andreas Kling 2019-08-20 21:05:05 +02:00
parent d4b7b92492
commit 029786e6b5

View file

@ -23,8 +23,20 @@ static bool flag_show_dotfiles = false;
static bool flag_show_inode = false; static bool flag_show_inode = false;
static bool flag_print_numeric = false; static bool flag_print_numeric = false;
static int terminal_rows = 0;
static int terminal_columns = 0;
static bool output_is_terminal = false;
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
struct winsize ws;
int rc = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
if (rc == 0) {
terminal_rows = ws.ws_row;
terminal_columns = ws.ws_col;
output_is_terminal = true;
}
static const char* valid_option_characters = "laiGn"; static const char* valid_option_characters = "laiGn";
int opt; int opt;
while ((opt = getopt(argc, argv, valid_option_characters)) != -1) { while ((opt = getopt(argc, argv, valid_option_characters)) != -1) {
@ -71,18 +83,10 @@ int main(int argc, char** argv)
return status; return status;
} }
void get_geometry(int& rows, int& columns)
{
struct winsize ws;
ioctl(0, TIOCGWINSZ, &ws);
rows = ws.ws_row;
columns = ws.ws_col;
}
int print_name(struct stat& st, const char* name, const char* path_for_link_resolution = nullptr) int print_name(struct stat& st, const char* name, const char* path_for_link_resolution = nullptr)
{ {
int nprinted = strlen(name); int nprinted = strlen(name);
if (!flag_colorize) { if (!flag_colorize || !output_is_terminal) {
printf("%s", name); printf("%s", name);
} else { } else {
const char* begin_color = ""; const char* begin_color = "";
@ -236,10 +240,6 @@ bool print_filesystem_object_short(const char* path, const char* name, int* npri
int do_file_system_object_short(const char* path) int do_file_system_object_short(const char* path)
{ {
int rows;
int columns;
get_geometry(rows, columns);
CDirIterator di(path, !flag_show_dotfiles ? CDirIterator::SkipDots : CDirIterator::Flags::NoFlags); CDirIterator di(path, !flag_show_dotfiles ? CDirIterator::SkipDots : CDirIterator::Flags::NoFlags);
if (di.has_error()) { if (di.has_error()) {
if (di.error() == ENOTDIR) { if (di.error() == ENOTDIR) {
@ -273,18 +273,18 @@ int do_file_system_object_short(const char* path)
if (!print_filesystem_object_short(pathbuf, name.characters(), &nprinted)) if (!print_filesystem_object_short(pathbuf, name.characters(), &nprinted))
return 2; return 2;
int offset = 0; int offset = 0;
if (columns > longest_name) if (terminal_columns > longest_name)
offset = columns % longest_name / (columns / longest_name); offset = terminal_columns % longest_name / (terminal_columns / longest_name);
/* The offset must be at least 2 because:
* - With each file an aditional char is printed e.g. '@','*'. // The offset must be at least 2 because:
* - Each filename must be separated by a space. // - With each file an aditional char is printed e.g. '@','*'.
*/ // - Each filename must be separated by a space.
int column_width = longest_name + (offset > 0 ? offset : 2); int column_width = longest_name + (offset > 0 ? offset : 2);
printed_on_row += column_width; printed_on_row += column_width;
for (int j = nprinted; i != (names.size() - 1) && j < column_width; ++j) for (int j = nprinted; i != (names.size() - 1) && j < column_width; ++j)
printf(" "); printf(" ");
if ((printed_on_row + column_width) >= columns) { if ((printed_on_row + column_width) >= terminal_columns) {
printf("\n"); printf("\n");
printed_on_row = 0; printed_on_row = 0;
} }