Skip to content

Commit ec9c4ec

Browse files
committed
adding support for reading from stdin.
1 parent 566920e commit ec9c4ec

File tree

2 files changed

+83
-20
lines changed

2 files changed

+83
-20
lines changed

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
all:
22
gcc -Wall -Wextra -pedantic -o hdump hdump.c
33

4+
debug:
5+
gcc -Wall -Wextra -pedantic -DDEBUG -o hdump hdump.c
6+
47
install:
58
install -m 0755 hdump /usr/local/bin/hdump
69

hdump.c

+80-20
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,60 @@
2121
#define _FILE_OFFSET_BITS 64
2222

2323
#include <unistd.h>
24+
#include <sys/select.h>
2425

2526
#endif /*__unix__ */
2627

2728
#include <stdio.h>
28-
#include <ctype.h>
29-
#include <string.h>
3029
#include <stdlib.h>
30+
#include <stdbool.h>
31+
#include <string.h>
32+
33+
#include <ctype.h>
3134
#include <getopt.h>
3235

3336
#define VERSION "2.4"
3437
#define BANNER puts("hdump "VERSION" by Fernando Merces - mentebinaria.com.br")
3538
#define USAGE fatal("Usage:\n\thdump [-c columns] [-s skip] [-n length] file")
3639

40+
3741
void fatal(const char *msg)
3842
{
3943
fprintf(stderr, "%s\n", msg);
4044
exit(EXIT_FAILURE);
4145
}
4246

47+
#ifdef __unix__
48+
/**
49+
* **@Nota:
50+
* Testa se há algo no buffer de entrada.
51+
*/
52+
bool
53+
available_input (void)
54+
{
55+
56+
FILE * in;
57+
bool available;
58+
struct timeval tv;
59+
fd_set fds;
60+
tv.tv_sec = 0;
61+
tv.tv_usec = 0;
62+
63+
if (!(in = fopen ("/dev/stdin", "rb")))
64+
fatal ("checking standart input");
65+
66+
67+
FD_ZERO (&fds);
68+
FD_SET (fileno (in), &fds);
69+
select ((fileno (in) + 1), &fds, NULL, NULL, &tv);
70+
available = FD_ISSET (fileno (in), &fds);
71+
72+
fclose (in);
73+
74+
return available;
75+
}
76+
77+
#endif /* __unix__ */
4378

4479
/* This function handles all the output space characters number calculation */
4580
int get_spaces(int bread, int cols)
@@ -59,17 +94,39 @@ int get_spaces(int bread, int cols)
5994

6095
int main(int argc, char *argv[])
6196
{
62-
FILE *file;
97+
FILE *file = NULL;
6398
unsigned char *buff, *ascii;
6499
register unsigned int i;
65100
size_t cols;
66101
unsigned long int bread, skip, length, address;
67102
int c;
103+
bool in = false;
68104

69105
bread = skip = length = address = cols = 0;
70106

107+
/**
108+
* **@Nota:
109+
* Caso seja windows, apenas imprime USAGE
110+
* caso contrário, testa se tem algo no buffer
111+
* de entrada, se tiver, assume que deve ler de lah
112+
* ja que nenhum arquivo ou opção foi provida
113+
* pelo usuário.
114+
*/
71115
if (argc < 2)
116+
#ifndef __unix__
72117
USAGE;
118+
#else
119+
{
120+
if (!(file = fopen ("/dev/stdin", "rb")))
121+
fatal ("checking standart input");
122+
if (!(in = available_input ()))
123+
USAGE;
124+
125+
if (!(file = fopen ("/dev/stdin", "rb")))
126+
fatal ("opening standart input");
127+
128+
}
129+
#endif /* __unix__ */
73130

74131
while ((c = getopt (argc, argv, "c:s:n:vh")) != -1)
75132
{
@@ -89,33 +146,35 @@ int main(int argc, char *argv[])
89146
USAGE;
90147
}
91148
}
92-
149+
93150
if (!cols)
94151
cols = 16;
95152

96-
if (!(file = fopen(argv[argc-1], "rb")))
97-
fatal("file not found or not readable");
98153

99-
#ifdef __unix__
100154

101-
/*
102-
* Caso o arquivo de entrada seja na verdade uma
103-
* pseudo-tty como /dev/stdin.
155+
/**
156+
* **@Nota:
157+
* caso seja windows, apenas tenta abrir o arquivo.
158+
* Caso contrário, testa se há algo disponivel no buffer de entrada
159+
* se sim, assume que deve ler de lá, evitando confundir as argumentos
160+
* passados.
104161
*/
105-
if (isatty (fileno (file))) {
106-
for ( ;skip > 0; skip --) {
107-
if (fgetc (file) == EOF)
108-
fatal ("skipping too much");
109-
}
162+
if (!file) {
163+
#ifndef __unix__
164+
if (!(file = fopen (argv[argc-1], "rb")))
165+
#else
166+
if (!(file = fopen ((available_input () ? "/dev/stdin" : argv[argc-1]), "rb")))
167+
#endif /* __unix__ */
168+
fatal("file not found or not readable");
110169
}
170+
111171

112-
#else
113172

114173
/* anda #skip posicoes para frente (-s) */
115-
if (fseek(file, skip, SEEK_SET))
116-
fatal("unable to seek through file");
117-
118-
#endif /* __unix__ */
174+
for ( ;skip > 0; skip --) {
175+
if (fgetc (file) == EOF)
176+
fatal ("skipping too much");
177+
}
119178

120179
buff = (unsigned char *) calloc (1, sizeof(unsigned char) * cols);
121180
ascii = (unsigned char *) calloc (1, (sizeof(unsigned char) * cols) + 1);
@@ -126,6 +185,7 @@ int main(int argc, char *argv[])
126185
do
127186
{
128187
bread = (int) fread(buff, sizeof(char), cols, file);
188+
129189
for (i=0; i<bread; i++)
130190
{
131191
/* imprime o offset */

0 commit comments

Comments
 (0)