linux cat命令改变功能显示当前文件行号
linux的cat命令使用-n显示多个文件行号时,行号是累加的,不是到了新文件就重新计数。这样满足不了我的需求。如果到了新文件能够重新计数,就能使用-nf(在上一篇-f显示文件名功能的基础上)加| grep xxx,既能直接显示xxx所在文件名,又能直接显示xxx所在文件的行号。
对比效果
cat1是上一次编译的增加了-f功能但是没有重置行号的可执行文件。
bibo@sunny:~/work/coreutils/coreutils$ ../../cat/cat1 ./src/*.c -nf | grep full_write
./src/cat.c: 1777 if (full_write (STDOUT_FILENO, buf, n_read) != n_read)
./src/cat.c: 1792 if (full_write (STDOUT_FILENO, outbuf, n_write) != n_write)
./src/cat.c: 1856 if (full_write (STDOUT_FILENO, wp, outsize) != outsize)
./src/cat.c: 2408 if (full_write (STDOUT_FILENO, "\r", 1) != 1)
./src/copy.c: 6643 if (full_write (dest_fd, pbuf, psize) != psize)
./src/copy.c: 6739 if ((full_write (fd, zeros, n)) != n)
./src/factor.c: 27708 if (full_write (STDOUT_FILENO, lbuf.buf, size) != size)
./src/split.c: 66931 if (full_write (output_desc, bp, bytes) == bytes)
./src/split.c: 67258 if (full_write (STDOUT_FILENO, bp, to_write) != to_write)
./src/split.c: 67348 if (full_write (STDOUT_FILENO, buf, n_read) != n_read
./src/split.c: 67515 if (full_write (STDOUT_FILENO, bp, to_write) != to_write)
./src/split.c: 67533 if (full_write (files[i_file].ofd, bp, to_write) != to_write
./src/yes.c: 85966 while (full_write (STDOUT_FILENO, buf, bufused) == bufused)
bibo@sunny:~/work/coreutils/coreutils$ ./src/cat ./src/*.c -nf | grep full_write
./src/cat.c: 195 if (full_write (STDOUT_FILENO, buf, n_read) != n_read)
./src/cat.c: 210 if (full_write (STDOUT_FILENO, outbuf, n_write) != n_write)
./src/cat.c: 274 if (full_write (STDOUT_FILENO, wp, outsize) != outsize)
./src/cat.c: 826 if (full_write (STDOUT_FILENO, "\r", 1) != 1)
./src/copy.c: 427 if (full_write (dest_fd, pbuf, psize) != psize)
./src/copy.c: 523 if ((full_write (fd, zeros, n)) != n)
./src/factor.c: 2365 if (full_write (STDOUT_FILENO, lbuf.buf, size) != size)
./src/split.c: 632 if (full_write (output_desc, bp, bytes) == bytes)
./src/split.c: 959 if (full_write (STDOUT_FILENO, bp, to_write) != to_write)
./src/split.c: 1049 if (full_write (STDOUT_FILENO, buf, n_read) != n_read
./src/split.c: 1216 if (full_write (STDOUT_FILENO, bp, to_write) != to_write)
./src/split.c: 1234 if (full_write (files[i_file].ofd, bp, to_write) != to_write
./src/yes.c: 125 while (full_write (STDOUT_FILENO, buf, bufused) == bufused)
做出改动的源文件
./src/cat.c
使用sed将源文件中的windows的回车符'\r'去掉,如果有回车符'\r'会提交失败,这是在windows和linux来回传输文件并编辑文件导致的。
sed -i 's/\r//' ./src/cat.c
使用git add将./src/cat.c添加到暂存区
git add ./src/cat.c
使用git commit提交这次代码更新,-m表示备注信息,备注信息必须要遵守原项目规定的格式,否则会提交失败。
git commit -m "cat: reset row number when open a new file"
使用git log查看提交日志,可以看到之前别人的提交备注信息都是简短的关键词加冒号,再加简单的说明。
bibo@sunny:~/work/coreutils/coreutils$ git log
commit 64efc26d39266b72af029e8acf537f1f28a92c0a (HEAD -> master)
Author: BIBO <120705103@qq.com>
Date: Fri Dec 29 11:22:31 2023 +0800cat: reset row number when open a new filecommit 98d463ef5d44b9dfe6757942251164b56795b06f (origin/master, origin/HEAD)
Author: Christian Göttsche <cgzones@googlemail.com>
Date: Tue Dec 19 15:55:28 2023 +0100copy,install: avoid unnecessary security context translationsDo not perform SELinux context translation for operations not involvinguser input or output. Context translation converts MCS/MLS labels intohuman readable form, which is useful for user facing applications likels(1) or the --context=CTX argument of cp(1).* src/copy.c (set_process_security_ctx): Use raw selinux variants.* src/install.c (need_copy): Likewise.(setdefaultfilecon): Likewise.* src/selinux.c (computecon): Likewise.(defaultcon): Likewise.* tests/cp/no-ctx.sh: Add raw variants to preload lib.* NEWS: Mention the improvement.commit 343b8d7ba705c4e2a537bdc06ac6aa043e5f9e31
Author: Pádraig Brady <P@draigBrady.com>
Date: Tue Dec 19 17:18:46 2023 +0000build: update gnulib to latest* gnulib: Primarily to get raw selinux wrappers
使用git diff加提交id查看提交前后的差异,新的提交id放在后面看起来会更舒服,显示的差异是增量。
bibo@sunny:~/work/coreutils/coreutils$ git diff 98d463ef5d44b9dfe6757942251164b56795b06f 64efc26d39266b72af029e8acf537f1f28a92c0a
diff --git a/src/cat.c b/src/cat.c
index e019faa8a..178c61c02 100644
--- a/src/cat.c
+++ b/src/cat.c
@@ -110,6 +110,7 @@ Concatenate FILE(s) to standard output.\n\-t equivalent to -vT\n\-T, --show-tabs display TAB characters as ^I\n\-u (ignored)\n\
+ -f, --show-filename display filename at begin of each line\n\-v, --show-nonprinting use ^ and M- notation, except for LFD and TAB\n\"), stdout);fputs (HELP_OPTION_DESCRIPTION, stdout);
@@ -126,6 +127,22 @@ Examples:\n\exit (status);}+/* Reset line number */
+static void
+reset_line_num (void)
+{
+ line_num_print = line_buf + LINE_COUNTER_BUF_LEN - 8;
+ line_num_start = line_buf + LINE_COUNTER_BUF_LEN - 3;
+ line_num_end = line_buf + LINE_COUNTER_BUF_LEN - 3;
+ for (int i = 0; i < 17; i++)
+ {
+ line_buf[i] = ' ';
+ }
+ line_buf[17] = '0';
+ line_buf[18] = '\t';
+ line_buf[19] = '\0';
+}
+/* Compute the next line number. */static void
@@ -211,7 +228,7 @@ write_pending (char *outbuf, char **bpout)static boolcat (char *inbuf, idx_t insize, char *outbuf, idx_t outsize,bool show_nonprinting, bool show_tabs, bool number, bool number_nonblank,
- bool show_ends, bool squeeze_blank)
+ bool show_ends, bool squeeze_blank, bool show_filename){/* Last character read from the input buffer. */unsigned char ch;
@@ -395,6 +412,13 @@ cat (char *inbuf, idx_t insize, char *outbuf, idx_t outsize,pending_cr = false;}+ /* Are we at the beginning of a line, and filename are requested? */
+ if (newlines >= 0 && show_filename)
+ {
+ bpout = stpcpy (bpout, infile);
+ *bpout++ = ':';
+ }
+/* Are we at the beginning of a line, and line numbers are requested? */if (newlines >= 0 && number)
@@ -547,6 +571,7 @@ main (int argc, char **argv)bool show_ends = false;bool show_nonprinting = false;bool show_tabs = false;
+ bool show_filename = false;int file_open_mode = O_RDONLY;static struct option const long_options[] =
@@ -558,6 +583,7 @@ main (int argc, char **argv){"show-ends", no_argument, nullptr, 'E'},{"show-tabs", no_argument, nullptr, 'T'},{"show-all", no_argument, nullptr, 'A'},
+ {"show-filename", no_argument, nullptr, 'f'},{GETOPT_HELP_OPTION_DECL},{GETOPT_VERSION_OPTION_DECL},{nullptr, 0, nullptr, 0}
@@ -578,7 +604,7 @@ main (int argc, char **argv)/* Parse command line options. */int c;
- while ((c = getopt_long (argc, argv, "benstuvAET", long_options, nullptr))
+ while ((c = getopt_long (argc, argv, "befnstuvAET", long_options, nullptr))!= -1){switch (c)
@@ -628,6 +654,10 @@ main (int argc, char **argv)show_tabs = true;break;+ case 'f':
+ show_filename = true;
+ break;
+case_GETOPT_HELP_CHAR;case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -667,6 +697,8 @@ main (int argc, char **argv)do{
+ reset_line_num();
+if (argind < argc)infile = argv[argind];@@ -722,7 +754,7 @@ main (int argc, char **argv)works, 'simple_cat' otherwise. */if (! (number || show_ends || show_nonprinting
- || show_tabs || squeeze_blank))
+ || show_tabs || squeeze_blank || show_filename)){int copy_cat_status =out_isreg && S_ISREG (stat_buf.st_mode) ? copy_cat () : 0;
@@ -773,7 +805,7 @@ main (int argc, char **argv)ok &= cat (inbuf, insize, outbuf, outsize, show_nonprinting,show_tabs, number, number_nonblank, show_ends,
- squeeze_blank);
+ squeeze_blank, show_filename);alignfree (outbuf);}
修改后的./src/cat.c文件
/* cat -- concatenate files and print on the standard output.Copyright (C) 1988-2023 Free Software Foundation, Inc.This program is free software: you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation, either version 3 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program. If not, see <https://www.gnu.org/licenses/>. *//* Differences from the Unix cat:* Always unbuffered, -u is ignored.* Usually much faster than other versions of cat, the differenceis especially apparent when using the -v option.By tege@sics.se, Torbjörn Granlund, advised by rms, Richard Stallman. */#include <config.h>#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>#if HAVE_STROPTS_H
# include <stropts.h>
#endif
#include <sys/ioctl.h>#include "system.h"
#include "alignalloc.h"
#include "ioblksize.h"
#include "fadvise.h"
#include "full-write.h"
#include "safe-read.h"
#include "xbinary-io.h"/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "cat"#define AUTHORS \proper_name_lite ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \proper_name ("Richard M. Stallman")/* Name of input file. May be "-". */
static char const *infile;/* Descriptor on which input file is open. */
static int input_desc;/* Buffer for line numbers.An 11 digit counter may overflow within an hour on a P2/466,an 18 digit counter needs about 1000y */
#define LINE_COUNTER_BUF_LEN 20
static char line_buf[LINE_COUNTER_BUF_LEN] ={' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0','\t', '\0'};/* Position in 'line_buf' where printing starts. This will not changeunless the number of lines is larger than 999999. */
static char *line_num_print = line_buf + LINE_COUNTER_BUF_LEN - 8;/* Position of the first digit in 'line_buf'. */
static char *line_num_start = line_buf + LINE_COUNTER_BUF_LEN - 3;/* Position of the last digit in 'line_buf'. */
static char *line_num_end = line_buf + LINE_COUNTER_BUF_LEN - 3;/* Preserves the 'cat' function's local 'newlines' between invocations. */
static int newlines2 = 0;/* Whether there is a pending CR to process. */
static bool pending_cr = false;void
usage (int status)
{if (status != EXIT_SUCCESS)emit_try_help ();else{printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
"),program_name);fputs (_("\
Concatenate FILE(s) to standard output.\n\
"), stdout);emit_stdin_note ();fputs (_("\
\n\-A, --show-all equivalent to -vET\n\-b, --number-nonblank number nonempty output lines, overrides -n\n\-e equivalent to -vE\n\-E, --show-ends display $ at end of each line\n\-n, --number number all output lines\n\-s, --squeeze-blank suppress repeated empty output lines\n\
"), stdout);fputs (_("\-t equivalent to -vT\n\-T, --show-tabs display TAB characters as ^I\n\-u (ignored)\n\-f, --show-filename display filename at begin of each line\n\-v, --show-nonprinting use ^ and M- notation, except for LFD and TAB\n\
"), stdout);fputs (HELP_OPTION_DESCRIPTION, stdout);fputs (VERSION_OPTION_DESCRIPTION, stdout);printf (_("\
\n\
Examples:\n\%s f - g Output f's contents, then standard input, then g's contents.\n\%s Copy standard input to standard output.\n\
"),program_name, program_name);emit_ancillary_info (PROGRAM_NAME);}exit (status);
}/* Reset line number */
static void
reset_line_num (void)
{line_num_print = line_buf + LINE_COUNTER_BUF_LEN - 8;line_num_start = line_buf + LINE_COUNTER_BUF_LEN - 3;line_num_end = line_buf + LINE_COUNTER_BUF_LEN - 3;for (int i = 0; i < 17; i++){line_buf[i] = ' ';}line_buf[17] = '0';line_buf[18] = '\t';line_buf[19] = '\0';
}/* Compute the next line number. */static void
next_line_num (void)
{char *endp = line_num_end;do{if ((*endp)++ < '9')return;*endp-- = '0';}while (endp >= line_num_start);if (line_num_start > line_buf)*--line_num_start = '1';else*line_buf = '>';if (line_num_start < line_num_print)line_num_print--;
}/* Plain cat. Copy the file behind 'input_desc' to STDOUT_FILENO.BUF (of size BUFSIZE) is the I/O buffer, used by reads and writes.Return true if successful. */static bool
simple_cat (char *buf, idx_t bufsize)
{/* Loop until the end of the file. */while (true){/* Read a block of input. */size_t n_read = safe_read (input_desc, buf, bufsize);if (n_read == SAFE_READ_ERROR){error (0, errno, "%s", quotef (infile));return false;}/* End of this file? */if (n_read == 0)return true;/* Write this block out. */if (full_write (STDOUT_FILENO, buf, n_read) != n_read)write_error ();}
}/* Write any pending output to STDOUT_FILENO.Pending is defined to be the *BPOUT - OUTBUF bytes starting at OUTBUF.Then set *BPOUT to OUTPUT if it's not already that value. */static inline void
write_pending (char *outbuf, char **bpout)
{idx_t n_write = *bpout - outbuf;if (0 < n_write){if (full_write (STDOUT_FILENO, outbuf, n_write) != n_write)write_error ();*bpout = outbuf;}
}/* Copy the file behind 'input_desc' to STDOUT_FILENO.Use INBUF and read INSIZE with each call,and OUTBUF and write OUTSIZE with each call.(The buffers are a bit larger than the I/O sizes.)The remaining boolean args say what 'cat' options to use.Return true if successful.Called if any option more than -u was specified.A newline character is always put at the end of the buffer, to makean explicit test for buffer end unnecessary. */static bool
cat (char *inbuf, idx_t insize, char *outbuf, idx_t outsize,bool show_nonprinting, bool show_tabs, bool number, bool number_nonblank,bool show_ends, bool squeeze_blank, bool show_filename)
{/* Last character read from the input buffer. */unsigned char ch;/* Determines how many consecutive newlines there have been in theinput. 0 newlines makes NEWLINES -1, 1 newline makes NEWLINES 1,etc. Initially 0 to indicate that we are at the beginning of anew line. The "state" of the procedure is determined byNEWLINES. */int newlines = newlines2;#ifdef FIONREAD/* If nonzero, use the FIONREAD ioctl, as an optimization.(On Ultrix, it is not supported on NFS file systems.) */bool use_fionread = true;
#endif/* The inbuf pointers are initialized so that BPIN > EOB, and thereby inputis read immediately. *//* Pointer to the first non-valid byte in the input buffer, i.e., thecurrent end of the buffer. */char *eob = inbuf;/* Pointer to the next character in the input buffer. */char *bpin = eob + 1;/* Pointer to the position where the next character shall be written. */char *bpout = outbuf;while (true){do{/* Write if there are at least OUTSIZE bytes in OUTBUF. */if (outbuf + outsize <= bpout){char *wp = outbuf;idx_t remaining_bytes;do{if (full_write (STDOUT_FILENO, wp, outsize) != outsize)write_error ();wp += outsize;remaining_bytes = bpout - wp;}while (outsize <= remaining_bytes);/* Move the remaining bytes to the beginning of thebuffer. */memmove (outbuf, wp, remaining_bytes);bpout = outbuf + remaining_bytes;}/* Is INBUF empty? */if (bpin > eob){bool input_pending = false;
#ifdef FIONREADint n_to_read = 0;/* Is there any input to read immediately?If not, we are about to wait,so write all buffered output before waiting. */if (use_fionread&& ioctl (input_desc, FIONREAD, &n_to_read) < 0){/* Ultrix returns EOPNOTSUPP on NFS;HP-UX returns ENOTTY on pipes.SunOS returns EINVAL andMore/BSD returns ENODEV on special fileslike /dev/null.Irix-5 returns ENOSYS on pipes. */if (errno == EOPNOTSUPP || errno == ENOTTY|| errno == EINVAL || errno == ENODEV|| errno == ENOSYS)use_fionread = false;else{error (0, errno, _("cannot do ioctl on %s"),quoteaf (infile));newlines2 = newlines;return false;}}if (n_to_read != 0)input_pending = true;
#endifif (!input_pending)write_pending (outbuf, &bpout);/* Read more input into INBUF. */size_t n_read = safe_read (input_desc, inbuf, insize);if (n_read == SAFE_READ_ERROR){error (0, errno, "%s", quotef (infile));write_pending (outbuf, &bpout);newlines2 = newlines;return false;}if (n_read == 0){write_pending (outbuf, &bpout);newlines2 = newlines;return true;}/* Update the pointers and insert a sentinel at the bufferend. */bpin = inbuf;eob = bpin + n_read;*eob = '\n';}else{/* It was a real (not a sentinel) newline. *//* Was the last line empty?(i.e., have two or more consecutive newlines been read?) */if (++newlines > 0){if (newlines >= 2){/* Limit this to 2 here. Otherwise, with lots ofconsecutive newlines, the counter could wraparound at INT_MAX. */newlines = 2;/* Are multiple adjacent empty lines to be substitutedby single ditto (-s), and this was the second emptyline? */if (squeeze_blank){ch = *bpin++;continue;}}/* Are line numbers to be written at empty lines (-n)? */if (number && !number_nonblank){next_line_num ();bpout = stpcpy (bpout, line_num_print);}}/* Output a currency symbol if requested (-e). */if (show_ends){if (pending_cr){*bpout++ = '^';*bpout++ = 'M';pending_cr = false;}*bpout++ = '$';}/* Output the newline. */*bpout++ = '\n';}ch = *bpin++;}while (ch == '\n');/* Here CH cannot contain a newline character. */if (pending_cr){*bpout++ = '\r';pending_cr = false;}/* Are we at the beginning of a line, and filename are requested? */if (newlines >= 0 && show_filename){bpout = stpcpy (bpout, infile);*bpout++ = ':';}/* Are we at the beginning of a line, and line numbers are requested? */if (newlines >= 0 && number){next_line_num ();bpout = stpcpy (bpout, line_num_print);}/* The loops below continue until a newline character is found,which means that the buffer is empty or that a proper newlinehas been found. *//* If quoting, i.e., at least one of -v, -e, or -t specified,scan for chars that need conversion. */if (show_nonprinting){while (true){if (ch >= 32){if (ch < 127)*bpout++ = ch;else if (ch == 127){*bpout++ = '^';*bpout++ = '?';}else{*bpout++ = 'M';*bpout++ = '-';if (ch >= 128 + 32){if (ch < 128 + 127)*bpout++ = ch - 128;else{*bpout++ = '^';*bpout++ = '?';}}else{*bpout++ = '^';*bpout++ = ch - 128 + 64;}}}else if (ch == '\t' && !show_tabs)*bpout++ = '\t';else if (ch == '\n'){newlines = -1;break;}else{*bpout++ = '^';*bpout++ = ch + 64;}ch = *bpin++;}}else{/* Not quoting, neither of -v, -e, or -t specified. */while (true){if (ch == '\t' && show_tabs){*bpout++ = '^';*bpout++ = ch + 64;}else if (ch != '\n'){if (ch == '\r' && *bpin == '\n' && show_ends){if (bpin == eob)pending_cr = true;else{*bpout++ = '^';*bpout++ = 'M';}}else*bpout++ = ch;}else{newlines = -1;break;}ch = *bpin++;}}}
}/* Copy data from input to output using copy_file_range if possible.Return 1 if successful, 0 if ordinary read+write should be tried,-1 if a serious problem has been diagnosed. */static int
copy_cat (void)
{/* Copy at most COPY_MAX bytes at a time; this is min(SSIZE_MAX, SIZE_MAX) truncated to a value that issurely aligned well. */ssize_t copy_max = MIN (SSIZE_MAX, SIZE_MAX) >> 30 << 30;/* copy_file_range does not support some cases, and itincorrectly returns 0 when reading from the proc filesystem on the Linux kernel through at least 5.6.19 (2020),so fall back on read+write if the copy_file_range isunsupported or the input file seems empty. */for (bool some_copied = false; ; some_copied = true)switch (copy_file_range (input_desc, nullptr, STDOUT_FILENO, nullptr,copy_max, 0)){case 0:return some_copied;case -1:if (errno == ENOSYS || is_ENOTSUP (errno) || errno == EINVAL|| errno == EBADF || errno == EXDEV || errno == ETXTBSY|| errno == EPERM)return 0;error (0, errno, "%s", quotef (infile));return -1;}
}int
main (int argc, char **argv)
{/* Nonzero if we have ever read standard input. */bool have_read_stdin = false;struct stat stat_buf;/* Variables that are set according to the specified options. */bool number = false;bool number_nonblank = false;bool squeeze_blank = false;bool show_ends = false;bool show_nonprinting = false;bool show_tabs = false;bool show_filename = false;int file_open_mode = O_RDONLY;static struct option const long_options[] ={{"number-nonblank", no_argument, nullptr, 'b'},{"number", no_argument, nullptr, 'n'},{"squeeze-blank", no_argument, nullptr, 's'},{"show-nonprinting", no_argument, nullptr, 'v'},{"show-ends", no_argument, nullptr, 'E'},{"show-tabs", no_argument, nullptr, 'T'},{"show-all", no_argument, nullptr, 'A'},{"show-filename", no_argument, nullptr, 'f'},{GETOPT_HELP_OPTION_DECL},{GETOPT_VERSION_OPTION_DECL},{nullptr, 0, nullptr, 0}};initialize_main (&argc, &argv);set_program_name (argv[0]);setlocale (LC_ALL, "");bindtextdomain (PACKAGE, LOCALEDIR);textdomain (PACKAGE);/* Arrange to close stdout if we exit via thecase_GETOPT_HELP_CHAR or case_GETOPT_VERSION_CHAR code.Normally STDOUT_FILENO is used rather than stdout, soclose_stdout does nothing. */atexit (close_stdout);/* Parse command line options. */int c;while ((c = getopt_long (argc, argv, "befnstuvAET", long_options, nullptr))!= -1){switch (c){case 'b':number = true;number_nonblank = true;break;case 'e':show_ends = true;show_nonprinting = true;break;case 'n':number = true;break;case 's':squeeze_blank = true;break;case 't':show_tabs = true;show_nonprinting = true;break;case 'u':/* We provide the -u feature unconditionally. */break;case 'v':show_nonprinting = true;break;case 'A':show_nonprinting = true;show_ends = true;show_tabs = true;break;case 'E':show_ends = true;break;case 'T':show_tabs = true;break;case 'f':show_filename = true;break;case_GETOPT_HELP_CHAR;case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);default:usage (EXIT_FAILURE);}}/* Get device, i-node number, and optimal blocksize of output. */if (fstat (STDOUT_FILENO, &stat_buf) < 0)error (EXIT_FAILURE, errno, _("standard output"));/* Optimal size of i/o operations of output. */idx_t outsize = io_blksize (&stat_buf);/* Device and I-node number of the output. */dev_t out_dev = stat_buf.st_dev;ino_t out_ino = stat_buf.st_ino;/* True if the output is a regular file. */bool out_isreg = S_ISREG (stat_buf.st_mode) != 0;if (! (number || show_ends || squeeze_blank)){file_open_mode |= O_BINARY;xset_binary_mode (STDOUT_FILENO, O_BINARY);}/* Main loop. */infile = "-";int argind = optind;bool ok = true;idx_t page_size = getpagesize ();do{reset_line_num();if (argind < argc)infile = argv[argind];bool reading_stdin = STREQ (infile, "-");if (reading_stdin){have_read_stdin = true;input_desc = STDIN_FILENO;if (file_open_mode & O_BINARY)xset_binary_mode (STDIN_FILENO, O_BINARY);}else{input_desc = open (infile, file_open_mode);if (input_desc < 0){error (0, errno, "%s", quotef (infile));ok = false;continue;}}if (fstat (input_desc, &stat_buf) < 0){error (0, errno, "%s", quotef (infile));ok = false;goto contin;}/* Optimal size of i/o operations of input. */idx_t insize = io_blksize (&stat_buf);fdadvise (input_desc, 0, 0, FADVISE_SEQUENTIAL);/* Don't copy a nonempty regular file to itself, as that wouldmerely exhaust the output device. It's better to catch thiserror earlier rather than later. */if (out_isreg&& stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino&& lseek (input_desc, 0, SEEK_CUR) < stat_buf.st_size){error (0, 0, _("%s: input file is output file"), quotef (infile));ok = false;goto contin;}/* Pointer to the input buffer. */char *inbuf;/* Select which version of 'cat' to use. If any format-orientedoptions were given use 'cat'; if not, use 'copy_cat' if itworks, 'simple_cat' otherwise. */if (! (number || show_ends || show_nonprinting|| show_tabs || squeeze_blank || show_filename)){int copy_cat_status =out_isreg && S_ISREG (stat_buf.st_mode) ? copy_cat () : 0;if (copy_cat_status != 0){inbuf = nullptr;ok &= 0 < copy_cat_status;}else{insize = MAX (insize, outsize);inbuf = xalignalloc (page_size, insize);ok &= simple_cat (inbuf, insize);}}else{/* Allocate, with an extra byte for a newline sentinel. */inbuf = xalignalloc (page_size, insize + 1);/* Why are(OUTSIZE - 1 + INSIZE * 4 + LINE_COUNTER_BUF_LEN)bytes allocated for the output buffer?A test whether output needs to be written is done when the inputbuffer empties or when a newline appears in the input. Afteroutput is written, at most (OUTSIZE - 1) bytes will remain in thebuffer. Now INSIZE bytes of input is read. Each input charactermay grow by a factor of 4 (by the prepending of M-^). If allcharacters do, and no newlines appear in this block of input, wewill have at most (OUTSIZE - 1 + INSIZE * 4) bytes in the buffer.If the last character in the preceding block of input was anewline, a line number may be written (according to the givenoptions) as the first thing in the output buffer. (Done after thenew input is read, but before processing of the input begins.)A line number requires seldom more than LINE_COUNTER_BUF_LENpositions.Align the output buffer to a page size boundary, for efficiencyon some paging implementations. */idx_t bufsize;if (ckd_mul (&bufsize, insize, 4)|| ckd_add (&bufsize, bufsize, outsize)|| ckd_add (&bufsize, bufsize, LINE_COUNTER_BUF_LEN - 1))xalloc_die ();char *outbuf = xalignalloc (page_size, bufsize);ok &= cat (inbuf, insize, outbuf, outsize, show_nonprinting,show_tabs, number, number_nonblank, show_ends,squeeze_blank, show_filename);alignfree (outbuf);}alignfree (inbuf);contin:if (!reading_stdin && close (input_desc) < 0){error (0, errno, "%s", quotef (infile));ok = false;}}while (++argind < argc);if (pending_cr){if (full_write (STDOUT_FILENO, "\r", 1) != 1)write_error ();}if (have_read_stdin && close (STDIN_FILENO) < 0)error (EXIT_FAILURE, errno, _("closing standard input"));return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
相关文章:
linux cat命令改变功能显示当前文件行号
linux的cat命令使用-n显示多个文件行号时,行号是累加的,不是到了新文件就重新计数。这样满足不了我的需求。如果到了新文件能够重新计数,就能使用-nf(在上一篇-f显示文件名功能的基础上)加| grep xxx,既能直…...
Django-REST-Framework 如何快速生成Swagger, ReDoc格式的 REST API 文档
1、API 接口文档的几种规范格式 前后端分离项目中,使用规范、便捷的API接口文档工具,可以有效提高团队工作效率。 标准化的API文档的益处: 允许开发人员以交互式的方式查看、测试API接口,以方便使用将所有可暴露的API接口进行分…...
SpringBoot当中的Singleton和Prototype详解
在Spring Boot中,Singleton和Prototype是两种Bean的作用域。这两种作用域决定了Spring容器如何创建和管理Bean的实例。 Singleton(单例): 当一个Bean被配置为Singleton作用域时,Spring容器在启动时只会创建该Bean的一个…...
LeetCode第1题 - 两数之和
题目 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 示例 给定 nums [2, 7, 11, 15], …...
(14)Linux 地址空间的理解
前言:本章核心主题为 "进程地址空间"。 一、Linux 进程地址空间 程序地址空间是内存吗?不是!程序地址空间不是内存! 其实,我们称之为程序地址空间都不准确,应该叫 进程地址空间,这…...
Java中的设计模式
设计模式是软件开发中常见问题的可重用解决方案。在Java中,设计模式有助于提高代码的可维护性、可读性和可扩展性。以下是一篇关于Java中设计模式的文章,以帮助您更好地理解这些模式。 一、设计模式简介 设计模式是经过验证的解决方案,用于…...
Hadoop(2):常见的MapReduce[在Ubuntu中运行!]
1 以词频统计为例子介绍 mapreduce怎么写出来的 弄清楚MapReduce的各个过程: 将文件输入后,返回的<k1,v1>代表的含义是:k1表示偏移量,即v1的第一个字母在文件中的索引(从0开始数的);v1表…...
Unity | 快速修复Animation missing错误
目录 一、背景 二、效果 三、解决办法 一、背景 最近在做2D 骨骼动画相关的Demo,我自己使用Unity引擎进行骨骼绑定并创建了anim后,一切正常,anim也能播放。但是昨天我修改Obj及子物体的名称(由中文改为英文,如&…...
ssm基于web的志愿者管理系统的设计与实现+vue论文
摘 要 使用旧方法对志愿者管理系统的信息进行系统化管理已经不再让人们信赖了,把现在的网络信息技术运用在志愿者管理系统的管理上面可以解决许多信息管理上面的难题,比如处理数据时间很长,数据存在错误不能及时纠正等问题。这次开发的志愿者…...
C++运算符重载(插入and提取)
介绍 本文主要介绍 插入(>>) and 提取(<<)的运算符重载 1.插入(>>) 提取(<<)只能是友元函数 2.插入关键词istream 例子:istream& operator>>(istream& in, sumber&Left) 3.提取关键词ostream 例子:ostream&a…...
C#高级 08Json操作
1.概念 Json是存储和交换文本信息的语法。类似于XML。Json比XML更小、更快、更易解析。Json与XML一样是一种数据格式。Json是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。Json采取完全独立于语言的文本格式, 但是也使用了类似于C语言的习惯。这些特性使…...
封装uniapp签字板
新开发的业务涉及到签字功能,由于是动态的表单,无法确定它会出现在哪里,不得已封装模块。 其中涉及到一个难点就是this的指向性问题, 第二个是微信小程序写法, 我这个写法里用了u-view的写法,可以自己修改组…...
Mybatis行为配置之Ⅳ—日志
专栏精选 引入Mybatis Mybatis的快速入门 Mybatis的增删改查扩展功能说明 mapper映射的参数和结果 Mybatis复杂类型的结果映射 Mybatis基于注解的结果映射 Mybatis枚举类型处理和类型处理器 再谈动态SQL Mybatis配置入门 Mybatis行为配置之Ⅰ—缓存 Mybatis行为配置…...
Java设计模式-外观模式
目录 一、影院管理项目 二、外观模式 (一)基本介绍 (二)原理类图 (三)解决影院管理 (四)注意事项和细节 (五)外观模式在MyBatis框架应用的源码分析 一…...
js+css实现颜色选择器
<!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>颜色选择器</title><style>.color-box {width: 50px;height: 50px;border: 1px solid #000;cursor: pointer;}</style> </head> <body><…...
Go语言中的包管理工具之Go Modules的使用
GoLang 中常用的包管理的方式 常用的有三种 Go PathGo VendorGo Modules 关于 Go Modules 1 ) 概述 Go的包管理,经过社区和官方的共同努力下,最终在百家争鸣后Go官方在 2018.8 推出了go 1.11版本中的Go Modules,并且很快成为一统江湖的包…...
【c/c++】指针例图基础详解
文章目录 指针变量内存指针详解例1例2练习&答案解析 指针变量内存 int main(){// 各类型变量占字节数printf("char: %d\n",sizeof(char)); // 1printf("short: %d\n",sizeof(short)); // 2printf("int: %d\n",sizeof(int)); // 4pri…...
TCP/IP的网络层(即IP层)之IP地址和网络掩码,在视频监控系统中的配置和应用
在给客户讲解我们的AS-V1000视频监控平台的时候,有的客户经常会配置错误IP地址的掩码和网关,导致出现一些网路问题。而在视频监控系统中,IP地址和子网掩码是用于标识网络中设备的重要标识符。IP地址被用来唯一地标识一个网络设备,…...
代码随想录刷题 | Day1
今日学习目标 一、基础 数组 array类 模板类vector 数组是存放在连续内存空间上的相同类型数据的集合。 数组可以方便的通过下标索引的方式获取到下标下对应的数据。 需要两点注意的是 数组下标都是从0开始的。 数组内存空间的地址是连续的 而且大家如果使用C的话&…...
查看IOS游戏FPS
摘要 本篇技术博客将介绍如何使用克魔助手工具来查看iOS游戏的帧率(FPS)。通过克魔助手,开发者可以轻松监测游戏性能,以提升用户体验和游戏质量。 引言 在iOS游戏开发过程中,了解游戏的帧率对于优化游戏性能至关重要…...
PyTorch 2.5 入门必备:开箱即用镜像快速上手指南
PyTorch 2.5 入门必备:开箱即用镜像快速上手指南 1. 为什么选择PyTorch 2.5镜像? 深度学习环境配置一直是新手入门的第一道门槛。传统的手动安装方式需要处理CUDA驱动、cuDNN、Python包依赖等一系列复杂问题,往往耗费数小时甚至数天时间。P…...
如何高效解析城通网盘链接:这款开源工具让下载速度提升10倍
如何高效解析城通网盘链接:这款开源工具让下载速度提升10倍 【免费下载链接】ctfileGet 获取城通网盘一次性直连地址 项目地址: https://gitcode.com/gh_mirrors/ct/ctfileGet ctfileGet作为一款专注于城通网盘链接解析的开源工具,通过纯前端技术…...
别再只写Prompt了!用Cursor Skills给你的AI助手装上‘前端设计说明书’
别再只写Prompt了!用Cursor Skills给你的AI助手装上‘前端设计说明书’ 作为一名长期与AI代码生成工具打交道的前端开发者,我深刻理解那种面对千篇一律的"AI感"设计时的无奈。每次都要花费大量时间编写冗长的Prompt,结果生成的代码…...
UE6.5 C++27调试私密工作流(EPIC内部培训文档节选):从PDB/DSYM生成到Live Reload调试延迟压至11ms
第一章:UE6.5 C27调试工作流演进与核心挑战Unreal Engine 6.5 首次原生支持 C27 标准子集(以 Clang 18 / MSVC 19.39 为后端),其调试工作流已从传统符号断点驱动,转向基于语义感知的实时表达式求值与协程上下文追踪。这…...
攻克高并发场景:基于快马平台生成黑马点评秒杀与缓存实战代码
今天想和大家分享一个实战项目经验——如何用InsCode(快马)平台快速搭建高并发场景下的黑马点评系统核心模块。这个项目最吸引我的地方在于,它完美复现了电商系统中那些让人头疼的高并发场景,比如秒杀、缓存一致性等问题。 秒杀功能的核心逻辑 优惠券秒…...
Tsuru平台终极选型指南:如何选择最适合你的PaaS解决方案
Tsuru平台终极选型指南:如何选择最适合你的PaaS解决方案 【免费下载链接】tsuru Open source and extensible Platform as a Service (PaaS). 项目地址: https://gitcode.com/gh_mirrors/ts/tsuru 在当今快速发展的云原生时代,选择合适的PaaS平台…...
Django React Redux Base:终极全栈开发模板完全指南
Django React Redux Base:终极全栈开发模板完全指南 【免费下载链接】django-react-redux-base Seedstars Labs Base Django React Redux Project 项目地址: https://gitcode.com/gh_mirrors/dj/django-react-redux-base 想要快速构建现代化Web应用却苦于复杂…...
uosc:革命性MPV播放器UI,基于接近度智能显示界面元素
uosc:革命性MPV播放器UI,基于接近度智能显示界面元素 【免费下载链接】uosc Feature-rich minimalist proximity-based UI for MPV player. 项目地址: https://gitcode.com/gh_mirrors/uo/uosc uosc是一款为MPV播放器打造的功能丰富且极简的基于接…...
vokoscreenNG完全指南:开源屏幕录制工具的全方位应用手册
vokoscreenNG完全指南:开源屏幕录制工具的全方位应用手册 【免费下载链接】vokoscreenNG vokoscreenNG is a powerful screencast creator in many languages to record the screen, an area or a window (Linux only). Recording of audio from multiple sources i…...
VRM Addon for Blender全流程指南:从安装到高级角色创作
VRM Addon for Blender全流程指南:从安装到高级角色创作 【免费下载链接】VRM-Addon-for-Blender VRM Importer, Exporter and Utilities for Blender 2.93 to 5.0 项目地址: https://gitcode.com/gh_mirrors/vr/VRM-Addon-for-Blender VRM Addon for Blende…...
