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
27Cat::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
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
64Cat::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}
Result
Result codes.
Definition Application.h:54
const ArgumentContainer & arguments() const
Get program arguments.
ArgumentParser & parser()
Get program arguments parser.
const Vector< Argument * > & getPositionals() const
Get positional arguments.
void setDescription(const String &desc)
Set program description.
Result registerPositional(const char *name, const char *description, Size count=1)
Register a positional argument.
const String & name() const
Retrieve program name.
virtual Result initialize()
Initialize the application.
Definition Cat.cpp:38
virtual Result exec()
Execute the application.
Definition Cat.cpp:43
Result cat(const char *file) const
Concatenate a file.
Definition Cat.cpp:64
virtual ~Cat()
Destructor.
Definition Cat.cpp:34
Cat(int argc, char **argv)
Constructor.
Definition Cat.cpp:27
POSIX-compatible application.
Vectors are dynamically resizeable Arrays.
Definition Vector.h:42
virtual Size count() const
Returns the number of items inside the Vector.
Definition Vector.h:204
C int open(const char *path, int oflag,...)
Open file relative to directory file descriptor.
Definition open.cpp:26
C char * strerror(int errnum)
The strerror function maps the number in errnum to a message string.
Definition strerror.cpp:20
C int close(int fildes)
Close a file descriptor.
Definition close.cpp:22
C int errno
The lvalue errno is used by many functions to return error values.
C void * memset(void *dest, int ch, size_t count)
Fill memory with a constant byte.
Definition memset.cpp:20
#define S_ISCHR(m)
Test for a character special file.
Definition stat.h:152
#define O_RDONLY
Open for reading only.
Definition fcntl.h:81
C int printf(const char *format,...)
Output a formatted string to standard output.
Definition printf.cpp:22
C ssize_t read(int fildes, void *buf, size_t nbyte)
Read from a file.
Definition read.cpp:22
#define S_ISREG(m)
Test for a regular file.
Definition stat.h:161
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128
#define DEBUG(msg)
Output a debug message to standard output.
Definition Log.h:89
The <sys/stat.h> header shall define the stat structure.
Definition stat.h:177
mode_t st_mode
Mode of file.
Definition stat.h:203