libubox
C utility functions for OpenWrt.
ustream-example.c
Go to the documentation of this file.
1 #include <sys/socket.h>
2 #include <netinet/in.h>
3 
4 #include <stdio.h>
5 #include <getopt.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <unistd.h>
9 
10 #include "ustream.h"
11 #include "uloop.h"
12 #include "usock.h"
13 
14 static struct uloop_fd server;
15 static const char *port = "10000";
16 struct client *next_client = NULL;
17 
18 struct client {
19  struct sockaddr_in sin;
20 
21  struct ustream_fd s;
22  int ctr;
23 };
24 
25 static void client_read_cb(struct ustream *s, int bytes)
26 {
27  struct client *cl = container_of(s, struct client, s.stream);
28  struct ustream_buf *buf = s->r.head;
29  char *newline, *str;
30 
31  do {
32  str = ustream_get_read_buf(s, NULL);
33  if (!str)
34  break;
35 
36  newline = strchr(buf->data, '\n');
37  if (!newline)
38  break;
39 
40  *newline = 0;
41  ustream_printf(s, "%s\n", str);
42  ustream_consume(s, newline + 1 - str);
43  cl->ctr += newline + 1 - str;
44  } while(1);
45 
46  if (s->w.data_bytes > 256 && !ustream_read_blocked(s)) {
47  fprintf(stderr, "Block read, bytes: %d\n", s->w.data_bytes);
48  ustream_set_read_blocked(s, true);
49  }
50 }
51 
52 static void client_close(struct ustream *s)
53 {
54  struct client *cl = container_of(s, struct client, s.stream);
55 
56  fprintf(stderr, "Connection closed\n");
57  ustream_free(s);
58  close(cl->s.fd.fd);
59  free(cl);
60 }
61 
62 static void client_notify_write(struct ustream *s, int bytes)
63 {
64  fprintf(stderr, "Wrote %d bytes, pending: %d\n", bytes, s->w.data_bytes);
65 
66  if (s->w.data_bytes < 128 && ustream_read_blocked(s)) {
67  fprintf(stderr, "Unblock read\n");
69  }
70 }
71 
72 static void client_notify_state(struct ustream *s)
73 {
74  struct client *cl = container_of(s, struct client, s.stream);
75 
76  if (!s->eof)
77  return;
78 
79  fprintf(stderr, "eof!, pending: %d, total: %d\n", s->w.data_bytes, cl->ctr);
80  if (!s->w.data_bytes)
81  return client_close(s);
82 
83 }
84 
85 static void server_cb(struct uloop_fd *fd, unsigned int events)
86 {
87  struct client *cl;
88  unsigned int sl = sizeof(struct sockaddr_in);
89  int sfd;
90 
91  if (!next_client)
92  next_client = calloc(1, sizeof(*next_client));
93 
94  cl = next_client;
95  sfd = accept(server.fd, (struct sockaddr *) &cl->sin, &sl);
96  if (sfd < 0) {
97  fprintf(stderr, "Accept failed\n");
98  return;
99  }
100 
101  cl->s.stream.string_data = true;
105  ustream_fd_init(&cl->s, sfd);
106  next_client = NULL;
107  fprintf(stderr, "New connection\n");
108 }
109 
110 static int run_server(void)
111 {
112 
113  server.cb = server_cb;
115  if (server.fd < 0) {
116  perror("usock");
117  return 1;
118  }
119 
120  uloop_init();
122  uloop_run();
123 
124  return 0;
125 }
126 
127 static int usage(const char *name)
128 {
129  fprintf(stderr, "Usage: %s -p <port>\n", name);
130  return 1;
131 }
132 
133 int main(int argc, char **argv)
134 {
135  int ch;
136 
137  while ((ch = getopt(argc, argv, "p:")) != -1) {
138  switch(ch) {
139  case 'p':
140  port = optarg;
141  break;
142  default:
143  return usage(argv[0]);
144  }
145  }
146 
147  return run_server();
148 }
uint8_t name[]
Definition: blobmsg.h:1
#define container_of(ptr, type, member)
Definition: list.h:38
struct sockaddr_in sin
struct ustream_fd s
Definition: uloop.h:63
int fd
Definition: uloop.h:65
uloop_fd_handler cb
Definition: uloop.h:64
char * data
Definition: ustream.h:130
struct uloop_fd fd
Definition: ustream.h:124
struct ustream stream
Definition: ustream.h:123
struct ustream_buf_list r w
Definition: ustream.h:50
void(* notify_write)(struct ustream *s, int bytes)
Definition: ustream.h:68
void(* notify_read)(struct ustream *s, int bytes_new)
Definition: ustream.h:60
void(* notify_state)(struct ustream *s)
Definition: ustream.h:78
bool string_data
Definition: ustream.h:115
int fd
Definition: udebug-priv.h:27
static struct epoll_event events[ULOOP_MAX_EVENTS]
Definition: uloop-epoll.c:60
int uloop_fd_add(struct uloop_fd *sock, unsigned int flags)
Definition: uloop.c:235
int uloop_init(void)
Definition: uloop.c:150
static int uloop_run(void)
Definition: uloop.h:147
#define ULOOP_READ
Definition: uloop.h:47
int usock(int type, const char *host, const char *service)
Definition: usock.c:252
#define USOCK_NUMERIC
Definition: usock.h:28
#define USOCK_IPV4ONLY
Definition: usock.h:30
#define USOCK_SERVER
Definition: usock.h:25
#define USOCK_TCP
Definition: usock.h:22
static void client_read_cb(struct ustream *s, int bytes)
static void server_cb(struct uloop_fd *fd, unsigned int events)
int main(int argc, char **argv)
static void client_close(struct ustream *s)
struct client * next_client
static void client_notify_state(struct ustream *s)
static struct uloop_fd server
static const char * port
static void client_notify_write(struct ustream *s, int bytes)
static int run_server(void)
static int usage(const char *name)
void ustream_fd_init(struct ustream_fd *sf, int fd)
Definition: ustream-fd.c:160
void ustream_free(struct ustream *s)
Definition: ustream.c:92
int ustream_printf(struct ustream *s, const char *format,...)
Definition: ustream.c:534
void ustream_consume(struct ustream *s, int len)
Definition: ustream.c:214
char * ustream_get_read_buf(struct ustream *s, int *buflen)
Definition: ustream.c:328
void ustream_set_read_blocked(struct ustream *s, bool set)
Definition: ustream.c:204
static bool ustream_read_blocked(struct ustream *s)
Definition: ustream.h:168