Asterisk - The Open Source Telephony Project GIT-master-4f2b068
Loading...
Searching...
No Matches
editline_compat.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2026, Sean Bright
5 *
6 * Sean Bright <sean@seanbright.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18#include "asterisk.h"
19
20#include <histedit.h>
21
22#include "editline_compat.h"
23
24/*
25 * The `read_char` function below is a modified (see inline comments)
26 * version of the `read_char` function in libedit's src/read.c file which,
27 * as of 2026-01-02, can be found here:
28 *
29 # https://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libedit/read.c?rev=HEAD
30 *
31 * The copyright and license information is reproduced here:
32 */
33
34/*-
35 * Copyright (c) 1992, 1993
36 * The Regents of the University of California. All rights reserved.
37 *
38 * This code is derived from software contributed to Berkeley by
39 * Christos Zoulas of Cornell University.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. Neither the name of the University nor the names of its contributors
50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission.
52 *
53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE.
64 */
65
66
67/* read_char():
68 * Read a character from the tty.
69 */
70static int
71read_char(EditLine *el, wchar_t *cp)
72{
73 ssize_t num_read;
74#ifdef EDITLINE_ORIG
75 /* Removed for Asterisk. FIXIO is set when the EL_SAFEREAD
76 flag is set on the EditLine handle, which we do not do
77 so `tried` will always be 1 */
78 int tried = (el->el_flags & FIXIO) == 0;
79#endif
80 char cbuf[MB_LEN_MAX];
81 size_t cbp = 0;
82#ifdef EDITLINE_ORIG
83 /* Removed for Asterisk. This is only needed for FIXIO,
84 as above. */
85 int save_errno = errno;
86#endif
87
88 again:
89#ifdef EDITLINE_ORIG
90 /* Removed for Asterisk. libedit only sets up signal handlers
91 for SIGCONT and SIGWINCH if the EL_SIGNAL flag is set on
92 the EditLine handle, which we do not do.
93
94 Additionally, we don't have access to the internals of `el`
95 to get the file descriptor to read from, but we know that
96 we will always be reading from stdin, so hardcode it */
97 el->el_signal->sig_no = 0;
98 while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) {
99 int e = errno;
100 switch (el->el_signal->sig_no) {
101 case SIGCONT:
102 el_wset(el, EL_REFRESH);
103 /*FALLTHROUGH*/
104 case SIGWINCH:
105 sig_set(el);
106 goto again;
107 default:
108 break;
109 }
110 if (!tried && read__fixio(el->el_infd, e) == 0) {
111 errno = save_errno;
112 tried = 1;
113 } else {
114 errno = e;
115 *cp = L'\0';
116 return -1;
117 }
118 }
119#else
120 while ((num_read = read(STDIN_FILENO, cbuf + cbp, (size_t)1)) == -1) {
121 *cp = L'\0';
122 return -1;
123 }
124#endif
125
126 /* Test for EOF */
127 if (num_read == 0) {
128 *cp = L'\0';
129 return 0;
130 }
131
132 for (;;) {
133 mbstate_t mbs;
134
135 ++cbp;
136 /* This only works because UTF8 is stateless. */
137 memset(&mbs, 0, sizeof(mbs));
138 switch (mbrtowc(cp, cbuf, cbp, &mbs)) {
139 case (size_t)-1:
140 if (cbp > 1) {
141 /*
142 * Invalid sequence, discard all bytes
143 * except the last one.
144 */
145 cbuf[0] = cbuf[cbp - 1];
146 cbp = 0;
147 break;
148 } else {
149 /* Invalid byte, discard it. */
150 cbp = 0;
151 goto again;
152 }
153 case (size_t)-2:
154 if (cbp >= MB_LEN_MAX) {
155 errno = EILSEQ;
156 *cp = L'\0';
157 return -1;
158 }
159 /* Incomplete sequence, read another byte. */
160 goto again;
161 default:
162 /* Valid character, process it. */
163 return 1;
164 }
165 }
166}
167
168int editline_read_char(EditLine *el, wchar_t *cp)
169{
170 return read_char(el, cp);
171}
static EditLine * el
Definition asterisk.c:348
Asterisk main include file. File version handling, generic pbx functions.
int editline_read_char(EditLine *el, wchar_t *cp)
static int read_char(EditLine *el, wchar_t *cp)
int errno