aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2009-04-27 20:14:06 +1000
committerNguyễn Thái Ngọc Duy <pclouds@gmail.com>2009-04-28 14:31:59 +1000
commit1756cc5943aa545f2f18fff60d56ad0886ef6145 (patch)
tree7bbc6daad68365a33898e54ee1a1161b4cfd596a
parent0c970511cc230abd19c1a30058174cbf03222648 (diff)
downloadbusybox-w32-1756cc5943aa545f2f18fff60d56ad0886ef6145.tar.gz
busybox-w32-1756cc5943aa545f2f18fff60d56ad0886ef6145.tar.bz2
busybox-w32-1756cc5943aa545f2f18fff60d56ad0886ef6145.zip
libbb/strbuf_file: stdio emulation layer for handling with Winsock handles
not really robust, but enough to make wget works
-rw-r--r--include/strbuf_file.h69
-rw-r--r--libbb/Kbuild1
-rw-r--r--libbb/strbuf_file.c119
3 files changed, 189 insertions, 0 deletions
diff --git a/include/strbuf_file.h b/include/strbuf_file.h
new file mode 100644
index 000000000..73eff9193
--- /dev/null
+++ b/include/strbuf_file.h
@@ -0,0 +1,69 @@
1#include "strbuf.h"
2
3struct strbuf_file {
4 struct strbuf input;
5 int has_error;
6 int fd;
7};
8
9struct strbuf_file *sfdopen(int fd, const char *mode);
10int sfclose(struct strbuf_file *sf);
11int sfprintf(struct strbuf_file *sf, const char *fmt, ...);
12void sfclearerr(struct strbuf_file *sf);
13int sfread(char *buf, int size, int n, struct strbuf_file *sf);
14char *sfgets(char *buf, int size, struct strbuf_file *sf);
15int sfgetc(struct strbuf_file *sf);
16
17#ifdef REPLACE_STDIO
18
19#ifdef FILE
20#undef FILE
21#endif
22#define FILE struct strbuf_file
23
24#ifdef fdopen
25#undef fdopen
26#endif
27#define fdopen(fd,mode) sfdopen(fd,mode)
28
29#ifdef fclose
30#undef fclose
31#endif
32#define fclose(fp) sfclose(fp)
33
34#ifdef fprintf
35#undef fprintf
36#endif
37#define fprintf sfprintf
38
39#ifdef fread
40#undef fread
41#endif
42#define fread(buf,s,n,fp) sfread(buf,s,n,fp)
43
44#ifdef clearerr
45#undef clearerr
46#endif
47#define clearerr(fp) sfclearerr(fp)
48
49#ifdef ferror
50#undef ferror
51#endif
52#define ferror(fp) ((fp)->has_error)
53
54#ifdef fgets
55#undef fgets
56#endif
57#define fgets(buf,n,fp) sfgets(buf,n,fp)
58
59#ifdef getc
60#undef getc
61#endif
62#define getc(fp) sfgetc(fp)
63
64#ifdef fflush
65#undef fflush
66#endif
67#define fflush(fp) 0
68
69#endif
diff --git a/libbb/Kbuild b/libbb/Kbuild
index 4c8f542fc..dca58d6f7 100644
--- a/libbb/Kbuild
+++ b/libbb/Kbuild
@@ -136,6 +136,7 @@ lib-$(CONFIG_MINGW32) += regex.o
136lib-$(CONFIG_MINGW32) += run-command.o 136lib-$(CONFIG_MINGW32) += run-command.o
137lib-$(CONFIG_MINGW32) += setenv.o 137lib-$(CONFIG_MINGW32) += setenv.o
138lib-$(CONFIG_MINGW32) += strbuf.o 138lib-$(CONFIG_MINGW32) += strbuf.o
139lib-$(CONFIG_MINGW32) += strbuf_file.o
139lib-$(CONFIG_MINGW32) += strlcpy.o 140lib-$(CONFIG_MINGW32) += strlcpy.o
140lib-$(CONFIG_MINGW32) += trace.o 141lib-$(CONFIG_MINGW32) += trace.o
141lib-$(CONFIG_MINGW32) += usage.o 142lib-$(CONFIG_MINGW32) += usage.o
diff --git a/libbb/strbuf_file.c b/libbb/strbuf_file.c
new file mode 100644
index 000000000..fb2ba7966
--- /dev/null
+++ b/libbb/strbuf_file.c
@@ -0,0 +1,119 @@
1#include "libbb.h"
2#include "strbuf_file.h"
3
4struct strbuf_file *sfdopen(int fd, const char *mode)
5{
6 struct strbuf_file *s;
7
8 s = xmalloc(sizeof(*s));
9 strbuf_init(&s->input, 0);
10 s->has_error = 0;
11 s->fd = fd;
12 return s;
13}
14
15int sfclose(struct strbuf_file *sf)
16{
17 strbuf_release(&sf->input);
18 close(sf->fd);
19 free(sf);
20 return 0;
21}
22
23int sfprintf(struct strbuf_file *sf, const char *fmt, ...)
24{
25 int len;
26 va_list ap;
27 struct strbuf sb = STRBUF_INIT;
28
29 strbuf_grow(&sb, 64);
30 va_start(ap, fmt);
31 len = vsnprintf(sb.buf + sb.len, sb.alloc - sb.len, fmt, ap);
32 va_end(ap);
33 if (len < 0)
34 die("your vsnprintf is broken");
35 if (len > strbuf_avail(&sb)) {
36 strbuf_grow(&sb, len);
37 va_start(ap, fmt);
38 len = vsnprintf(sb.buf + sb.len, sb.alloc - sb.len, fmt, ap);
39 va_end(ap);
40 if (len > strbuf_avail(&sb)) {
41 die("this should not happen, your snprintf is broken");
42 }
43 }
44 strbuf_setlen(&sb, sb.len + len);
45 len = write(sf->fd, sb.buf, sb.len);
46 strbuf_release(&sb);
47 return len;
48}
49
50void sfclearerr(struct strbuf_file *sf)
51{
52 sf->has_error = 0;
53}
54
55int sfread(char *buf, int size, int n, struct strbuf_file *sf)
56{
57 int avail = size * n;
58 int len = avail > sf->input.len ? sf->input.len : avail;
59 char *p;
60 struct strbuf *sb = &sf->input;
61
62 if (len) {
63 memcpy(buf, sb->buf, len);
64 strbuf_setlen(sb, sb->len - len);
65 avail -= len;
66 }
67
68 p = buf + len;
69 while ((len = read(sf->fd, p, avail)) > 0) {
70 p += len;
71 avail -= len;
72 if (!avail)
73 break;
74 }
75 if (len == -1)
76 sf->has_error = 1;
77 /* just in case we have some leftover */
78 if ((p-buf) % size) {
79 len = (p-buf) % size;
80 strbuf_grow(sb, len);
81 strbuf_add(sb, p-len, len);
82 }
83 return (p-buf) / size;
84}
85
86int sfgetc(struct strbuf_file *sf)
87{
88 int ret;
89 char ch;
90 if (sf->input.len) {
91 ret = sf->input.buf[0];
92 memcpy(sf->input.buf, sf->input.buf+1, sf->input.len);
93 sf->input.len--;
94 return ret;
95 }
96 ret = read(sf->fd, &ch, 1);
97 if (ret > 0)
98 return ch;
99 if (ret == -1)
100 sf->has_error = 1;
101 return EOF;
102}
103
104char *sfgets(char *buf, int size, struct strbuf_file *sf)
105{
106 char *p = buf;
107 int ch = -1;
108 while (size > 1 && (ch = sfgetc(sf)) != EOF) {
109 *p++ = ch;
110 size--;
111 if (ch == '\n')
112 break;
113 }
114 if (p > buf && size > 0) {
115 *p++ = '\0';
116 return buf;
117 }
118 return NULL;
119}