mbuf: fix reset on mbuf free
[dpdk.git] / lib / librte_cmdline / cmdline.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation.
3  * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
4  * All rights reserved.
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 <errno.h>
15 #include <netinet/in.h>
16
17 #include <rte_string_fns.h>
18
19 #include "cmdline_private.h"
20
21 #ifdef RTE_EXEC_ENV_WINDOWS
22 #define write _write
23 #endif
24
25 static void
26 cmdline_valid_buffer(struct rdline *rdl, const char *buf,
27                      __rte_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
40 static int
41 cmdline_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
49 int
50 cmdline_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
67 void
68 cmdline_set_prompt(struct cmdline *cl, const char *prompt)
69 {
70         if (!cl || !prompt)
71                 return;
72         strlcpy(cl->prompt, prompt, sizeof(cl->prompt));
73 }
74
75 struct cmdline *
76 cmdline_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
106 struct rdline*
107 cmdline_get_rdline(struct cmdline *cl)
108 {
109         return &cl->rdl;
110 }
111
112 void
113 cmdline_free(struct cmdline *cl)
114 {
115         dprintf("called\n");
116
117         if (!cl)
118                 return;
119
120         if (cl->s_in > 2)
121                 close(cl->s_in);
122         if (cl->s_out != cl->s_in && cl->s_out > 2)
123                 close(cl->s_out);
124         free(cl);
125 }
126
127 void
128 cmdline_printf(const struct cmdline *cl, const char *fmt, ...)
129 {
130         va_list ap;
131
132         if (!cl || !fmt)
133                 return;
134
135         if (cl->s_out < 0)
136                 return;
137         va_start(ap, fmt);
138         cmdline_vdprintf(cl->s_out, fmt, ap);
139         va_end(ap);
140 }
141
142 int
143 cmdline_in(struct cmdline *cl, const char *buf, int size)
144 {
145         const char *history, *buffer;
146         size_t histlen, buflen;
147         int ret = 0;
148         int i, same;
149
150         if (!cl || !buf)
151                 return -1;
152
153         for (i=0; i<size; i++) {
154                 ret = rdline_char_in(&cl->rdl, buf[i]);
155
156                 if (ret == RDLINE_RES_VALIDATED) {
157                         buffer = rdline_get_buffer(&cl->rdl);
158                         history = rdline_get_history_item(&cl->rdl, 0);
159                         if (history) {
160                                 histlen = strnlen(history, RDLINE_BUF_SIZE);
161                                 same = !memcmp(buffer, history, histlen) &&
162                                         buffer[histlen] == '\n';
163                         }
164                         else
165                                 same = 0;
166                         buflen = strnlen(buffer, RDLINE_BUF_SIZE);
167                         if (buflen > 1 && !same)
168                                 rdline_add_history(&cl->rdl, buffer);
169                         rdline_newline(&cl->rdl, cl->prompt);
170                 }
171                 else if (ret == RDLINE_RES_EOF)
172                         return -1;
173                 else if (ret == RDLINE_RES_EXITED)
174                         return -1;
175         }
176         return i;
177 }
178
179 void
180 cmdline_quit(struct cmdline *cl)
181 {
182         if (!cl)
183                 return;
184         rdline_quit(&cl->rdl);
185 }
186
187 int
188 cmdline_poll(struct cmdline *cl)
189 {
190         int status;
191         ssize_t read_status;
192         char c;
193
194         if (!cl)
195                 return -EINVAL;
196         else if (cl->rdl.status == RDLINE_EXITED)
197                 return RDLINE_EXITED;
198
199         status = cmdline_poll_char(cl);
200         if (status < 0)
201                 return status;
202         else if (status > 0) {
203                 c = -1;
204                 read_status = cmdline_read_char(cl, &c);
205                 if (read_status < 0)
206                         return read_status;
207
208                 status = cmdline_in(cl, &c, 1);
209                 if (status < 0 && cl->rdl.status != RDLINE_EXITED)
210                         return status;
211         }
212
213         return cl->rdl.status;
214 }
215
216 void
217 cmdline_interact(struct cmdline *cl)
218 {
219         char c;
220
221         if (!cl)
222                 return;
223
224         c = -1;
225         while (1) {
226                 if (cmdline_read_char(cl, &c) <= 0)
227                         break;
228                 if (cmdline_in(cl, &c, 1) < 0)
229                         break;
230         }
231 }