FreeNOS
Cat.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009 Niek Linnenbank
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <sys/stat.h>
25 #include "Cat.h"
26 
27 Cat::Cat(int argc, char **argv)
28  : POSIXApplication(argc, argv)
29 {
30  parser().setDescription("Concatenate files to standard output");
31  parser().registerPositional("FILE", "file(s) to concatenate", 0);
32 }
33 
35 {
36 }
37 
39 {
40  return arguments().getPositionals().count() > 0 ? Success : ShowUsage;
41 }
42 
44 {
45  Result result = Success, ret = Success;
46  const Vector<Argument *> & positionals = arguments().getPositionals();
47 
48  // Cat all given files. */
49  for (Size i = 0; i < positionals.count(); i++)
50  {
51  // Perform cat. */
52  result = cat(*(positionals[i]->getValue()));
53 
54  // Update exit code if needed
55  if (result != Success)
56  {
57  ret = result;
58  }
59  }
60  // Done
61  return ret;
62 }
63 
64 Cat::Result Cat::cat(const char *file) const
65 {
66  char buf[1024];
67  int fd, e;
68  struct stat st;
69  const char *name = *(parser().name());
70 
71  DEBUG("file = " << file);
72 
73  // Stat the file
74  if (stat(file, &st) != 0)
75  {
76  printf("%s: failed to stat '%s': %s\r\n",
77  name, file, strerror(errno));
78  return NotFound;
79  }
80 
81  // Must be a regular file or device
82  if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode))
83  {
84  printf("%s: not a file: '%s'\r\n", name, file);
85  return InvalidArgument;
86  }
87 
88  // Clear buffer
89  memset(buf, 0, sizeof(buf));
90 
91  // Attempt to open the file first
92  if ((fd = open(file, O_RDONLY)) < 0)
93  {
94  printf("%s: failed to open '%s': %s\r\n",
95  name, file, strerror(errno));
96  return IOError;
97  }
98 
99  // Read contents
100  while (1)
101  {
102  e = read(fd, buf, sizeof(buf) - 1);
103  switch (e)
104  {
105  // Error occurred
106  case -1:
107  printf("%s: failed to read '%s': %s\r\n",
108  name, file, strerror(errno));
109  close(fd);
110  return IOError;
111 
112  // End of file
113  case 0:
114  close(fd);
115  return Success;
116 
117  // Output data
118  default:
119  buf[e] = 0;
120  printf("%s", buf);
121  break;
122  }
123  }
124  return InvalidArgument;
125 }
Cat::Cat
Cat(int argc, char **argv)
Constructor.
Definition: Cat.cpp:27
Cat::initialize
virtual Result initialize()
Initialize the application.
Definition: Cat.cpp:38
stat
The <sys/stat.h> header shall define the stat structure.
Definition: stat.h:176
fcntl.h
Cat::~Cat
virtual ~Cat()
Destructor.
Definition: Cat.cpp:34
errno
C int errno
The lvalue errno is used by many functions to return error values.
string.h
Cat::exec
virtual Result exec()
Execute the application.
Definition: Cat.cpp:43
Application::NotFound
@ NotFound
Definition: Application.h:56
POSIXApplication
POSIX-compatible application.
Definition: POSIXApplication.h:35
Application::Success
@ Success
Definition: Application.h:55
Application::arguments
const ArgumentContainer & arguments() const
Get program arguments.
Definition: Application.cpp:112
open
int open(const char *path, int oflag,...)
Open file relative to directory file descriptor.
Definition: open.cpp:26
Application::ShowUsage
@ ShowUsage
Definition: Application.h:59
ArgumentParser::setDescription
void setDescription(const String &desc)
Set program description.
Definition: ArgumentParser.cpp:95
read
ssize_t read(int fildes, void *buf, size_t nbyte)
Read from a file.
Definition: read.cpp:22
Application::IOError
@ IOError
Definition: Application.h:57
DEBUG
#define DEBUG(msg)
Output a debug message to standard output.
Definition: Log.h:89
S_ISCHR
#define S_ISCHR(m)
Test for a character special file.
Definition: stat.h:152
printf
int printf(const char *format,...)
Output a formatted string to standard output.
Definition: printf.cpp:22
close
int close(int fildes)
Close a file descriptor.
Definition: close.cpp:22
Application::InvalidArgument
@ InvalidArgument
Definition: Application.h:58
Vector::count
virtual Size count() const
Returns the number of items inside the Vector.
Definition: Vector.h:204
stdio.h
strerror
char * strerror(int errnum)
The strerror function maps the number in errnum to a message string.
Definition: strerror.cpp:20
S_ISREG
#define S_ISREG(m)
Test for a regular file.
Definition: stat.h:161
Size
unsigned int Size
Any sane size indicator cannot go negative.
Definition: Types.h:128
stat::st_mode
mode_t st_mode
Mode of file.
Definition: stat.h:203
Application::Result
Result
Result codes.
Definition: Application.h:53
ArgumentParser::name
const String & name() const
Retrieve program name.
Definition: ArgumentParser.cpp:85
stat
int stat(const char *path, struct stat *buf)
Get file status.
Definition: stat.cpp:25
ArgumentParser::registerPositional
Result registerPositional(const char *name, const char *description, Size count=1)
Register a positional argument.
Definition: ArgumentParser.cpp:119
stat.h
unistd.h
Application::parser
ArgumentParser & parser()
Get program arguments parser.
Definition: Application.cpp:102
memset
void * memset(void *dest, int ch, size_t count)
Fill memory with a constant byte.
Definition: memset.cpp:20
Cat::cat
Result cat(const char *file) const
Concatenate a file.
Definition: Cat.cpp:64
stdlib.h
Vector< Argument * >
Cat.h
O_RDONLY
#define O_RDONLY
Open for reading only.
Definition: fcntl.h:81
errno.h
ArgumentContainer::getPositionals
const Vector< Argument * > & getPositionals() const
Get positional arguments.
Definition: ArgumentContainer.cpp:39