]> git.proxmox.com Git - ceph.git/blame - ceph/src/seastar/dpdk/lib/librte_cmdline/cmdline.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / seastar / dpdk / lib / librte_cmdline / cmdline.c
CommitLineData
9f95a23c
TL
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation.
7c673cae
FG
3 * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
4 * All rights reserved.
7c673cae
FG
5 */
6
7#include <stdio.h>
8#include <string.h>
9#include <unistd.h>
10#include <stdlib.h>
11#include <stdarg.h>
12#include <inttypes.h>
13#include <fcntl.h>
14#include <poll.h>
15#include <errno.h>
16#include <termios.h>
17#include <netinet/in.h>
18
19#include <rte_string_fns.h>
20
21#include "cmdline_parse.h"
22#include "cmdline_rdline.h"
23#include "cmdline.h"
24
25static void
26cmdline_valid_buffer(struct rdline *rdl, const char *buf,
27 __attribute__((unused)) unsigned int size)
28{
29 struct cmdline *cl = rdl->opaque;
30 int ret;
31 ret = cmdline_parse(cl, buf);
32 if (ret == CMDLINE_PARSE_AMBIGUOUS)
33 cmdline_printf(cl, "Ambiguous command\n");
34 else if (ret == CMDLINE_PARSE_NOMATCH)
35 cmdline_printf(cl, "Command not found\n");
36 else if (ret == CMDLINE_PARSE_BAD_ARGS)
37 cmdline_printf(cl, "Bad arguments\n");
38}
39
40static int
41cmdline_complete_buffer(struct rdline *rdl, const char *buf,
42 char *dstbuf, unsigned int dstsize,
43 int *state)
44{
45 struct cmdline *cl = rdl->opaque;
46 return cmdline_complete(cl, buf, state, dstbuf, dstsize);
47}
48
49int
50cmdline_write_char(struct rdline *rdl, char c)
51{
52 int ret = -1;
53 struct cmdline *cl;
54
55 if (!rdl)
56 return -1;
57
58 cl = rdl->opaque;
59
60 if (cl->s_out >= 0)
61 ret = write(cl->s_out, &c, 1);
62
63 return ret;
64}
65
66
67void
68cmdline_set_prompt(struct cmdline *cl, const char *prompt)
69{
70 if (!cl || !prompt)
71 return;
9f95a23c 72 strlcpy(cl->prompt, prompt, sizeof(cl->prompt));
7c673cae
FG
73}
74
75struct cmdline *
76cmdline_new(cmdline_parse_ctx_t *ctx, const char *prompt, int s_in, int s_out)
77{
78 struct cmdline *cl;
79 int ret;
80
81 if (!ctx || !prompt)
82 return NULL;
83
84 cl = malloc(sizeof(struct cmdline));
85 if (cl == NULL)
86 return NULL;
87 memset(cl, 0, sizeof(struct cmdline));
88 cl->s_in = s_in;
89 cl->s_out = s_out;
90 cl->ctx = ctx;
91
92 ret = rdline_init(&cl->rdl, cmdline_write_char, cmdline_valid_buffer,
93 cmdline_complete_buffer);
94 if (ret != 0) {
95 free(cl);
96 return NULL;
97 }
98
99 cl->rdl.opaque = cl;
100 cmdline_set_prompt(cl, prompt);
101 rdline_newline(&cl->rdl, cl->prompt);
102
103 return cl;
104}
105
106void
107cmdline_free(struct cmdline *cl)
108{
109 dprintf("called\n");
110
111 if (!cl)
112 return;
113
114 if (cl->s_in > 2)
115 close(cl->s_in);
116 if (cl->s_out != cl->s_in && cl->s_out > 2)
117 close(cl->s_out);
118 free(cl);
119}
120
121void
122cmdline_printf(const struct cmdline *cl, const char *fmt, ...)
123{
124 va_list ap;
125
126 if (!cl || !fmt)
127 return;
128
7c673cae
FG
129 if (cl->s_out < 0)
130 return;
131 va_start(ap, fmt);
132 vdprintf(cl->s_out, fmt, ap);
133 va_end(ap);
7c673cae
FG
134}
135
136int
137cmdline_in(struct cmdline *cl, const char *buf, int size)
138{
139 const char *history, *buffer;
140 size_t histlen, buflen;
141 int ret = 0;
142 int i, same;
143
144 if (!cl || !buf)
145 return -1;
146
147 for (i=0; i<size; i++) {
148 ret = rdline_char_in(&cl->rdl, buf[i]);
149
150 if (ret == RDLINE_RES_VALIDATED) {
151 buffer = rdline_get_buffer(&cl->rdl);
152 history = rdline_get_history_item(&cl->rdl, 0);
153 if (history) {
154 histlen = strnlen(history, RDLINE_BUF_SIZE);
155 same = !memcmp(buffer, history, histlen) &&
156 buffer[histlen] == '\n';
157 }
158 else
159 same = 0;
160 buflen = strnlen(buffer, RDLINE_BUF_SIZE);
161 if (buflen > 1 && !same)
162 rdline_add_history(&cl->rdl, buffer);
163 rdline_newline(&cl->rdl, cl->prompt);
164 }
165 else if (ret == RDLINE_RES_EOF)
166 return -1;
167 else if (ret == RDLINE_RES_EXITED)
168 return -1;
169 }
170 return i;
171}
172
173void
174cmdline_quit(struct cmdline *cl)
175{
176 if (!cl)
177 return;
178 rdline_quit(&cl->rdl);
179}
180
181int
182cmdline_poll(struct cmdline *cl)
183{
184 struct pollfd pfd;
185 int status;
186 ssize_t read_status;
187 char c;
188
189 if (!cl)
190 return -EINVAL;
191 else if (cl->rdl.status == RDLINE_EXITED)
192 return RDLINE_EXITED;
193
194 pfd.fd = cl->s_in;
195 pfd.events = POLLIN;
196 pfd.revents = 0;
197
198 status = poll(&pfd, 1, 0);
199 if (status < 0)
200 return status;
201 else if (status > 0) {
202 c = -1;
203 read_status = read(cl->s_in, &c, 1);
204 if (read_status < 0)
205 return read_status;
206
207 status = cmdline_in(cl, &c, 1);
208 if (status < 0 && cl->rdl.status != RDLINE_EXITED)
209 return status;
210 }
211
212 return cl->rdl.status;
213}
214
215void
216cmdline_interact(struct cmdline *cl)
217{
218 char c;
219
220 if (!cl)
221 return;
222
223 c = -1;
224 while (1) {
225 if (read(cl->s_in, &c, 1) <= 0)
226 break;
227 if (cmdline_in(cl, &c, 1) < 0)
228 break;
229 }
230}