Date:2011-04-10 20:25:43 (12 years 11 months ago)
Author:Werner Almesberger
Commit:3b0ee3c00a9b096b334119a6170b6eedaada0c97
Message:tools/: added network (TCP) I/O helper functions

- include/netio.h, lib/netio.c: network I/O helper functions
- lib/Makefile (OBJS): added netio.o
Files: tools/include/netio.h (1 diff)
tools/lib/Makefile (1 diff)
tools/lib/netio.c (1 diff)

Change Details

tools/include/netio.h
1/*
2 * include/netio.h - Helper functions for socket I/O
3 *
4 * Written 2011 by Werner Almesberger
5 * Copyright 2011 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#ifndef NETIO_H
15#define NETIO_H
16
17#include <stdint.h>
18#include <sys/types.h>
19
20
21struct netio;
22
23extern int netio_verbose;
24
25int netio_getc(struct netio *dsc, uint8_t *res);
26ssize_t netio_read_until(struct netio *dsc, const char *end, void *buf,
27    size_t len, char *last);
28ssize_t netio_read(struct netio *dsc, void *buf, size_t len);
29int netio_write(struct netio *dsc, const void *data, size_t len);
30int netio_printf(struct netio *dsc, const char *fmt, ...);
31struct netio *netio_open(int s);
32void netio_close(struct netio *dsc);
33
34#endif /* !NETIO_H */
tools/lib/Makefile
1919OBJS_ben_jlime = atben.o
2020OBJS_ben_openwrt = atben.o
2121
22OBJS = atrf.o misctxrx.o cwtest.o $(OBJS_$(TARGET))
22OBJS = atrf.o misctxrx.o cwtest.o netio.o $(OBJS_$(TARGET))
2323
2424.PHONY: all clean spotless
2525
tools/lib/netio.c
1/*
2 * lib/netio.c - Helper functions for socket I/O
3 *
4 * Written 2011 by Werner Almesberger
5 * Copyright 2011 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stdarg.h>
15#include <stdint.h>
16#include <stdlib.h>
17#include <stdio.h>
18#include <unistd.h>
19#include <string.h>
20#include <sys/types.h>
21
22#include "netio.h"
23
24
25#define BUFFER 1024
26
27
28struct netio {
29    int s;
30    uint8_t *pos;
31    int size;
32    uint8_t buf[BUFFER];
33};
34
35
36int netio_verbose = 0;
37
38
39static void display(uint8_t c)
40{
41    fputc((c >= ' ' && c <= '~') || c == '\n' ? c : '?', stderr);
42}
43
44
45int netio_getc(struct netio *dsc, uint8_t *res)
46{
47    ssize_t got;
48
49    while (!dsc->size) {
50        got = read(dsc->s, dsc->buf, BUFFER);
51        if (got < 0) {
52            perror("read");
53            return -1;
54        }
55        if (!got)
56            return 0;
57        dsc->pos = dsc->buf;
58        dsc->size = got;
59    }
60    dsc->size--;
61    *res = *dsc->pos++;
62    if (netio_verbose)
63        display(*res);
64    return 1;
65}
66
67
68ssize_t netio_read_until(struct netio *dsc, const char *end, void *buf,
69    size_t len, char *last)
70{
71    size_t left;
72    const char *term;
73
74    for (left = len; left; left--)
75        switch (netio_getc(dsc, buf)) {
76        case 1:
77            buf++;
78            term = strchr(end, ((char *) buf)[-1]);
79            if (!term)
80                break;
81            if (!*term) {
82                fprintf(stderr, "received NUL in text\n");
83                return -1;
84            }
85            if (last)
86                *last = ((char *) buf)[-1];
87            return len-left; /* we don't count the terminator */
88        case 0:
89            if (last)
90                *last = 0;
91            return len-left;
92        case -1:
93            return -1;
94        }
95    fprintf(stderr, "buffer overrun\n");
96    return -1;
97}
98
99
100ssize_t netio_read(struct netio *dsc, void *buf, size_t len)
101{
102    size_t left;
103
104    for (left = len; left; left--)
105        switch (netio_getc(dsc, buf)) {
106        case 1:
107            buf++;
108            break;
109        case 0:
110            return len-left;
111        case -1:
112            return -1;
113        }
114    return len;
115}
116
117
118int netio_write(struct netio *dsc, const void *data, size_t len)
119{
120    const uint8_t *p;
121    ssize_t left, wrote;
122
123    if (netio_verbose)
124        for (p = data; p != data+len; p++)
125            display(*p);
126    for (left = len; left; left -= wrote) {
127        wrote = write(dsc->s, data, len);
128        if (wrote < 0) {
129            perror("write");
130            return -1;
131        }
132        data += wrote;
133    }
134    return len;
135}
136
137
138int netio_printf(struct netio *dsc, const char *fmt, ...)
139{
140    va_list ap;
141    int n, res;
142    char *buf;
143
144    va_start(ap, fmt);
145    n = vsnprintf(NULL, 0, fmt, ap);
146    va_end(ap);
147
148    buf = malloc(n+1);
149    if (!buf) {
150        perror("malloc");
151        return -1;
152        }
153
154    va_start(ap, fmt);
155    vsprintf(buf, fmt, ap);
156    va_end(ap);
157
158    res = netio_write(dsc, buf, n);
159
160    free(buf);
161
162    return res;
163}
164
165
166struct netio *netio_open(int s)
167{
168    struct netio *dsc;
169
170    dsc = malloc(sizeof(*dsc));
171    if (!dsc) {
172        perror("malloc");
173        return NULL;
174    }
175    dsc->s = s;
176    dsc->size = 0;
177    return dsc;
178}
179
180
181void netio_close(struct netio *dsc)
182{
183    if (close(dsc->s) < 0)
184        perror("close");
185    free(dsc);
186}

Archive Download the corresponding diff file



interactive