Root/tools/lib/netio.c

Source at commit 49e7c83796bc04941e9dbcec69bc0751563ff4d4 created 2 years 8 months ago.
By Werner Almesberger, atusb/: use ""VDD" symbol from kicad-libs
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}
187

Archive Download this file



interactive