MCPcopy Create free account
hub / github.com/coreutils/coreutils / wc

Function wc

src/wc.c:371–693  ·  view source on GitHub ↗

Count words. FILE_X is the name of the file (or null for standard input) that is open on descriptor FD. *FSTATUS is its status. Return true if successful. */

Source from the content-addressed store, hash-verified

369 input) that is open on descriptor FD. *FSTATUS is its status.
370 Return true if successful. */
371static bool
372wc (int fd, char const *file_x, struct fstatus *fstatus)
373{
374 int err = 0;
375 char buf[IO_BUFSIZE + 1];
376 intmax_t lines, words, chars, bytes, linelength;
377 bool count_bytes, count_chars, count_complicated;
378 char const *file = file_x ? file_x : _("standard input");
379
380 lines = words = chars = bytes = linelength = 0;
381
382 /* If in the current locale, chars are equivalent to bytes, we prefer
383 counting bytes, because that's easier. */
384 if (MB_CUR_MAX > 1)
385 {
386 count_bytes = print_bytes;
387 count_chars = print_chars;
388 }
389 else
390 {
391 count_bytes = print_bytes || print_chars;
392 count_chars = false;
393 }
394 count_complicated = print_words || print_linelength;
395
396 /* Advise the kernel of our access pattern only if we will read(). */
397 if (!count_bytes || count_chars || print_lines || count_complicated)
398 fdadvise (fd, 0, 0, FADVISE_SEQUENTIAL);
399
400 /* When counting only bytes, save some line- and word-counting
401 overhead. If FD is a 'regular' Unix file, using lseek is enough
402 to get its 'size' in bytes. Otherwise, read blocks of IO_BUFSIZE
403 bytes at a time until EOF. Note that the 'size' (number of bytes)
404 that wc reports is smaller than stats.st_size when the file is not
405 positioned at its beginning. That's why the lseek calls below are
406 necessary. For example the command
407 '(dd ibs=99k skip=1 count=0; ./wc -c) < /etc/group'
408 should make wc report '0' bytes. */
409
410 if (count_bytes && !count_chars && !print_lines && !count_complicated)
411 {
412 bool skip_read = false;
413
414 if (0 < fstatus->failed)
415 fstatus->failed = fstat (fd, &fstatus->st);
416
417 /* For sized files, seek to one st_blksize before EOF rather than to EOF.
418 This works better for files in proc-like file systems where
419 the size is only approximate. */
420 if (! fstatus->failed && usable_st_size (&fstatus->st)
421 && 0 <= fstatus->st.st_size)
422 {
423 off_t end_pos = fstatus->st.st_size;
424 off_t current_pos = lseek (fd, 0, SEEK_CUR);
425 if (current_pos < 0)
426 ;
427 else if (end_pos % page_size)
428 {

Callers 1

wc_fileFunction · 0.85

Calls 5

fdadviseFunction · 0.85
usable_st_sizeFunction · 0.85
maybe_c32isnbspaceFunction · 0.85
write_countsFunction · 0.85
wc_linesFunction · 0.70

Tested by

no test coverage detected