1 1.102 rillig /* $NetBSD: el.c,v 1.102 2025/01/03 00:40:08 rillig Exp $ */ 2 1.2 lukem 3 1.1 cgd /*- 4 1.1 cgd * Copyright (c) 1992, 1993 5 1.1 cgd * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * This code is derived from software contributed to Berkeley by 8 1.1 cgd * Christos Zoulas of Cornell University. 9 1.1 cgd * 10 1.1 cgd * Redistribution and use in source and binary forms, with or without 11 1.1 cgd * modification, are permitted provided that the following conditions 12 1.1 cgd * are met: 13 1.1 cgd * 1. Redistributions of source code must retain the above copyright 14 1.1 cgd * notice, this list of conditions and the following disclaimer. 15 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 cgd * notice, this list of conditions and the following disclaimer in the 17 1.1 cgd * documentation and/or other materials provided with the distribution. 18 1.32 agc * 3. Neither the name of the University nor the names of its contributors 19 1.1 cgd * may be used to endorse or promote products derived from this software 20 1.1 cgd * without specific prior written permission. 21 1.1 cgd * 22 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 1.1 cgd * SUCH DAMAGE. 33 1.1 cgd */ 34 1.1 cgd 35 1.29 christos #include "config.h" 36 1.1 cgd #if !defined(lint) && !defined(SCCSID) 37 1.2 lukem #if 0 38 1.1 cgd static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94"; 39 1.2 lukem #else 40 1.102 rillig __RCSID("$NetBSD: el.c,v 1.102 2025/01/03 00:40:08 rillig Exp $"); 41 1.2 lukem #endif 42 1.1 cgd #endif /* not lint && not SCCSID */ 43 1.1 cgd 44 1.1 cgd /* 45 1.1 cgd * el.c: EditLine interface functions 46 1.1 cgd */ 47 1.1 cgd #include <sys/types.h> 48 1.1 cgd #include <sys/param.h> 49 1.82 christos #include <ctype.h> 50 1.84 christos #include <langinfo.h> 51 1.84 christos #include <locale.h> 52 1.82 christos #include <stdarg.h> 53 1.82 christos #include <stdlib.h> 54 1.1 cgd #include <string.h> 55 1.75 christos 56 1.1 cgd #include "el.h" 57 1.81 christos #include "parse.h" 58 1.89 christos #include "read.h" 59 1.1 cgd 60 1.1 cgd /* el_init(): 61 1.1 cgd * Initialize editline and set default parameters. 62 1.1 cgd */ 63 1.88 christos EditLine * 64 1.19 lukem el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) 65 1.1 cgd { 66 1.72 christos return el_init_fd(prog, fin, fout, ferr, fileno(fin), fileno(fout), 67 1.72 christos fileno(ferr)); 68 1.72 christos } 69 1.72 christos 70 1.95 christos libedit_private EditLine * 71 1.95 christos el_init_internal(const char *prog, FILE *fin, FILE *fout, FILE *ferr, 72 1.95 christos int fdin, int fdout, int fderr, int flags) 73 1.72 christos { 74 1.99 christos EditLine *el = el_calloc(1, sizeof(*el)); 75 1.1 cgd 76 1.19 lukem if (el == NULL) 77 1.68 christos return NULL; 78 1.1 cgd 79 1.44 christos el->el_infile = fin; 80 1.19 lukem el->el_outfile = fout; 81 1.19 lukem el->el_errfile = ferr; 82 1.44 christos 83 1.72 christos el->el_infd = fdin; 84 1.72 christos el->el_outfd = fdout; 85 1.72 christos el->el_errfd = fderr; 86 1.44 christos 87 1.86 christos el->el_prog = wcsdup(ct_decode_string(prog, &el->el_scratch)); 88 1.56 christos if (el->el_prog == NULL) { 89 1.36 christos el_free(el); 90 1.36 christos return NULL; 91 1.36 christos } 92 1.19 lukem 93 1.19 lukem /* 94 1.19 lukem * Initialize all the modules. Order is important!!! 95 1.19 lukem */ 96 1.95 christos el->el_flags = flags; 97 1.19 lukem 98 1.64 christos if (terminal_init(el) == -1) { 99 1.36 christos el_free(el->el_prog); 100 1.25 christos el_free(el); 101 1.25 christos return NULL; 102 1.25 christos } 103 1.66 christos (void) keymacro_init(el); 104 1.19 lukem (void) map_init(el); 105 1.19 lukem if (tty_init(el) == -1) 106 1.19 lukem el->el_flags |= NO_TTY; 107 1.19 lukem (void) ch_init(el); 108 1.19 lukem (void) search_init(el); 109 1.19 lukem (void) hist_init(el); 110 1.19 lukem (void) prompt_init(el); 111 1.19 lukem (void) sig_init(el); 112 1.94 christos (void) literal_init(el); 113 1.89 christos if (read_init(el) == -1) { 114 1.89 christos el_end(el); 115 1.89 christos return NULL; 116 1.89 christos } 117 1.68 christos return el; 118 1.19 lukem } 119 1.1 cgd 120 1.95 christos EditLine * 121 1.95 christos el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr, 122 1.95 christos int fdin, int fdout, int fderr) 123 1.95 christos { 124 1.95 christos return el_init_internal(prog, fin, fout, ferr, fdin, fdout, fderr, 0); 125 1.95 christos } 126 1.1 cgd 127 1.1 cgd /* el_end(): 128 1.1 cgd * Clean up. 129 1.1 cgd */ 130 1.88 christos void 131 1.19 lukem el_end(EditLine *el) 132 1.1 cgd { 133 1.1 cgd 134 1.19 lukem if (el == NULL) 135 1.19 lukem return; 136 1.1 cgd 137 1.19 lukem el_reset(el); 138 1.19 lukem 139 1.64 christos terminal_end(el); 140 1.66 christos keymacro_end(el); 141 1.19 lukem map_end(el); 142 1.74 christos if (!(el->el_flags & NO_TTY)) 143 1.96 christos tty_end(el, TCSAFLUSH); 144 1.19 lukem ch_end(el); 145 1.101 christos read_end(el); 146 1.19 lukem search_end(el); 147 1.19 lukem hist_end(el); 148 1.19 lukem prompt_end(el); 149 1.19 lukem sig_end(el); 150 1.94 christos literal_end(el); 151 1.19 lukem 152 1.67 christos el_free(el->el_prog); 153 1.90 christos el_free(el->el_visual.cbuff); 154 1.90 christos el_free(el->el_visual.wbuff); 155 1.67 christos el_free(el->el_scratch.cbuff); 156 1.67 christos el_free(el->el_scratch.wbuff); 157 1.67 christos el_free(el->el_lgcyconv.cbuff); 158 1.67 christos el_free(el->el_lgcyconv.wbuff); 159 1.67 christos el_free(el); 160 1.19 lukem } 161 1.1 cgd 162 1.1 cgd 163 1.1 cgd /* el_reset(): 164 1.1 cgd * Reset the tty and the parser 165 1.1 cgd */ 166 1.88 christos void 167 1.19 lukem el_reset(EditLine *el) 168 1.1 cgd { 169 1.19 lukem 170 1.19 lukem tty_cookedmode(el); 171 1.92 christos ch_reset(el); /* XXX: Do we want that? */ 172 1.1 cgd } 173 1.1 cgd 174 1.1 cgd 175 1.1 cgd /* el_set(): 176 1.1 cgd * set the editline parameters 177 1.1 cgd */ 178 1.88 christos int 179 1.86 christos el_wset(EditLine *el, int op, ...) 180 1.1 cgd { 181 1.44 christos va_list ap; 182 1.27 christos int rv = 0; 183 1.1 cgd 184 1.19 lukem if (el == NULL) 185 1.68 christos return -1; 186 1.44 christos va_start(ap, op); 187 1.22 wiz 188 1.19 lukem switch (op) { 189 1.19 lukem case EL_PROMPT: 190 1.51 christos case EL_RPROMPT: { 191 1.51 christos el_pfunc_t p = va_arg(ap, el_pfunc_t); 192 1.52 christos 193 1.56 christos rv = prompt_set(el, p, 0, op, 1); 194 1.52 christos break; 195 1.52 christos } 196 1.52 christos 197 1.60 christos case EL_RESIZE: { 198 1.60 christos el_zfunc_t p = va_arg(ap, el_zfunc_t); 199 1.60 christos void *arg = va_arg(ap, void *); 200 1.60 christos rv = ch_resizefun(el, p, arg); 201 1.60 christos break; 202 1.60 christos } 203 1.60 christos 204 1.73 christos case EL_ALIAS_TEXT: { 205 1.73 christos el_afunc_t p = va_arg(ap, el_afunc_t); 206 1.73 christos void *arg = va_arg(ap, void *); 207 1.73 christos rv = ch_aliasfun(el, p, arg); 208 1.73 christos break; 209 1.73 christos } 210 1.73 christos 211 1.52 christos case EL_PROMPT_ESC: 212 1.52 christos case EL_RPROMPT_ESC: { 213 1.52 christos el_pfunc_t p = va_arg(ap, el_pfunc_t); 214 1.56 christos int c = va_arg(ap, int); 215 1.51 christos 216 1.87 christos rv = prompt_set(el, p, (wchar_t)c, op, 1); 217 1.50 christos break; 218 1.51 christos } 219 1.13 simonb 220 1.19 lukem case EL_TERMINAL: 221 1.64 christos rv = terminal_set(el, va_arg(ap, char *)); 222 1.19 lukem break; 223 1.1 cgd 224 1.19 lukem case EL_EDITOR: 225 1.87 christos rv = map_set_editor(el, va_arg(ap, wchar_t *)); 226 1.1 cgd break; 227 1.1 cgd 228 1.19 lukem case EL_SIGNAL: 229 1.44 christos if (va_arg(ap, int)) 230 1.19 lukem el->el_flags |= HANDLE_SIGNALS; 231 1.19 lukem else 232 1.19 lukem el->el_flags &= ~HANDLE_SIGNALS; 233 1.1 cgd break; 234 1.1 cgd 235 1.19 lukem case EL_BIND: 236 1.19 lukem case EL_TELLTC: 237 1.19 lukem case EL_SETTC: 238 1.19 lukem case EL_ECHOTC: 239 1.19 lukem case EL_SETTY: 240 1.19 lukem { 241 1.87 christos const wchar_t *argv[20]; 242 1.19 lukem int i; 243 1.19 lukem 244 1.70 christos for (i = 1; i < (int)__arraycount(argv); i++) 245 1.87 christos if ((argv[i] = va_arg(ap, wchar_t *)) == NULL) 246 1.19 lukem break; 247 1.19 lukem 248 1.19 lukem switch (op) { 249 1.19 lukem case EL_BIND: 250 1.86 christos argv[0] = L"bind"; 251 1.19 lukem rv = map_bind(el, i, argv); 252 1.19 lukem break; 253 1.19 lukem 254 1.19 lukem case EL_TELLTC: 255 1.86 christos argv[0] = L"telltc"; 256 1.64 christos rv = terminal_telltc(el, i, argv); 257 1.19 lukem break; 258 1.19 lukem 259 1.19 lukem case EL_SETTC: 260 1.86 christos argv[0] = L"settc"; 261 1.64 christos rv = terminal_settc(el, i, argv); 262 1.19 lukem break; 263 1.19 lukem 264 1.19 lukem case EL_ECHOTC: 265 1.86 christos argv[0] = L"echotc"; 266 1.64 christos rv = terminal_echotc(el, i, argv); 267 1.19 lukem break; 268 1.19 lukem 269 1.19 lukem case EL_SETTY: 270 1.86 christos argv[0] = L"setty"; 271 1.19 lukem rv = tty_stty(el, i, argv); 272 1.19 lukem break; 273 1.19 lukem 274 1.19 lukem default: 275 1.19 lukem rv = -1; 276 1.20 christos EL_ABORT((el->el_errfile, "Bad op %d\n", op)); 277 1.19 lukem } 278 1.1 cgd break; 279 1.19 lukem } 280 1.19 lukem 281 1.19 lukem case EL_ADDFN: 282 1.19 lukem { 283 1.87 christos wchar_t *name = va_arg(ap, wchar_t *); 284 1.87 christos wchar_t *help = va_arg(ap, wchar_t *); 285 1.44 christos el_func_t func = va_arg(ap, el_func_t); 286 1.1 cgd 287 1.19 lukem rv = map_addfunc(el, name, help, func); 288 1.1 cgd break; 289 1.19 lukem } 290 1.19 lukem 291 1.19 lukem case EL_HIST: 292 1.19 lukem { 293 1.44 christos hist_fun_t func = va_arg(ap, hist_fun_t); 294 1.67 christos void *ptr = va_arg(ap, void *); 295 1.1 cgd 296 1.19 lukem rv = hist_set(el, func, ptr); 297 1.97 christos if (MB_CUR_MAX == 1) 298 1.59 christos el->el_flags &= ~NARROW_HISTORY; 299 1.1 cgd break; 300 1.19 lukem } 301 1.1 cgd 302 1.100 christos case EL_SAFEREAD: 303 1.100 christos if (va_arg(ap, int)) 304 1.100 christos el->el_flags |= FIXIO; 305 1.100 christos else 306 1.100 christos el->el_flags &= ~FIXIO; 307 1.100 christos rv = 0; 308 1.100 christos break; 309 1.100 christos 310 1.19 lukem case EL_EDITMODE: 311 1.44 christos if (va_arg(ap, int)) 312 1.19 lukem el->el_flags &= ~EDIT_DISABLED; 313 1.19 lukem else 314 1.19 lukem el->el_flags |= EDIT_DISABLED; 315 1.19 lukem rv = 0; 316 1.1 cgd break; 317 1.13 simonb 318 1.23 christos case EL_GETCFN: 319 1.23 christos { 320 1.44 christos el_rfunc_t rc = va_arg(ap, el_rfunc_t); 321 1.89 christos rv = el_read_setfn(el->el_read, rc); 322 1.23 christos break; 323 1.23 christos } 324 1.23 christos 325 1.24 christos case EL_CLIENTDATA: 326 1.44 christos el->el_data = va_arg(ap, void *); 327 1.24 christos break; 328 1.24 christos 329 1.34 christos case EL_UNBUFFERED: 330 1.44 christos rv = va_arg(ap, int); 331 1.34 christos if (rv && !(el->el_flags & UNBUFFERED)) { 332 1.34 christos el->el_flags |= UNBUFFERED; 333 1.34 christos read_prepare(el); 334 1.34 christos } else if (!rv && (el->el_flags & UNBUFFERED)) { 335 1.34 christos el->el_flags &= ~UNBUFFERED; 336 1.34 christos read_finish(el); 337 1.34 christos } 338 1.35 christos rv = 0; 339 1.35 christos break; 340 1.35 christos 341 1.35 christos case EL_PREP_TERM: 342 1.44 christos rv = va_arg(ap, int); 343 1.35 christos if (rv) 344 1.38 christos (void) tty_rawmode(el); 345 1.35 christos else 346 1.38 christos (void) tty_cookedmode(el); 347 1.34 christos rv = 0; 348 1.34 christos break; 349 1.34 christos 350 1.44 christos case EL_SETFP: 351 1.44 christos { 352 1.44 christos FILE *fp; 353 1.44 christos int what; 354 1.44 christos 355 1.44 christos what = va_arg(ap, int); 356 1.44 christos fp = va_arg(ap, FILE *); 357 1.44 christos 358 1.44 christos rv = 0; 359 1.44 christos switch (what) { 360 1.44 christos case 0: 361 1.44 christos el->el_infile = fp; 362 1.44 christos el->el_infd = fileno(fp); 363 1.44 christos break; 364 1.44 christos case 1: 365 1.44 christos el->el_outfile = fp; 366 1.61 christos el->el_outfd = fileno(fp); 367 1.44 christos break; 368 1.44 christos case 2: 369 1.44 christos el->el_errfile = fp; 370 1.61 christos el->el_errfd = fileno(fp); 371 1.44 christos break; 372 1.44 christos default: 373 1.44 christos rv = -1; 374 1.44 christos break; 375 1.44 christos } 376 1.44 christos break; 377 1.44 christos } 378 1.44 christos 379 1.45 christos case EL_REFRESH: 380 1.45 christos re_clear_display(el); 381 1.45 christos re_refresh(el); 382 1.64 christos terminal__flush(el); 383 1.45 christos break; 384 1.45 christos 385 1.19 lukem default: 386 1.19 lukem rv = -1; 387 1.27 christos break; 388 1.1 cgd } 389 1.1 cgd 390 1.44 christos va_end(ap); 391 1.68 christos return rv; 392 1.19 lukem } 393 1.1 cgd 394 1.1 cgd 395 1.10 lukem /* el_get(): 396 1.10 lukem * retrieve the editline parameters 397 1.10 lukem */ 398 1.88 christos int 399 1.86 christos el_wget(EditLine *el, int op, ...) 400 1.10 lukem { 401 1.42 christos va_list ap; 402 1.19 lukem int rv; 403 1.10 lukem 404 1.42 christos if (el == NULL) 405 1.42 christos return -1; 406 1.42 christos 407 1.42 christos va_start(ap, op); 408 1.42 christos 409 1.19 lukem switch (op) { 410 1.19 lukem case EL_PROMPT: 411 1.51 christos case EL_RPROMPT: { 412 1.51 christos el_pfunc_t *p = va_arg(ap, el_pfunc_t *); 413 1.56 christos rv = prompt_get(el, p, 0, op); 414 1.56 christos break; 415 1.56 christos } 416 1.56 christos case EL_PROMPT_ESC: 417 1.56 christos case EL_RPROMPT_ESC: { 418 1.56 christos el_pfunc_t *p = va_arg(ap, el_pfunc_t *); 419 1.87 christos wchar_t *c = va_arg(ap, wchar_t *); 420 1.51 christos 421 1.51 christos rv = prompt_get(el, p, c, op); 422 1.19 lukem break; 423 1.51 christos } 424 1.10 lukem 425 1.19 lukem case EL_EDITOR: 426 1.87 christos rv = map_get_editor(el, va_arg(ap, const wchar_t **)); 427 1.10 lukem break; 428 1.10 lukem 429 1.19 lukem case EL_SIGNAL: 430 1.42 christos *va_arg(ap, int *) = (el->el_flags & HANDLE_SIGNALS); 431 1.19 lukem rv = 0; 432 1.10 lukem break; 433 1.10 lukem 434 1.19 lukem case EL_EDITMODE: 435 1.42 christos *va_arg(ap, int *) = !(el->el_flags & EDIT_DISABLED); 436 1.19 lukem rv = 0; 437 1.10 lukem break; 438 1.10 lukem 439 1.100 christos case EL_SAFEREAD: 440 1.100 christos *va_arg(ap, int *) = (el->el_flags & FIXIO); 441 1.100 christos rv = 0; 442 1.100 christos break; 443 1.100 christos 444 1.19 lukem case EL_TERMINAL: 445 1.64 christos terminal_get(el, va_arg(ap, const char **)); 446 1.33 christos rv = 0; 447 1.10 lukem break; 448 1.10 lukem 449 1.42 christos case EL_GETTC: 450 1.19 lukem { 451 1.42 christos static char name[] = "gettc"; 452 1.98 christos char *argv[3]; 453 1.69 christos argv[0] = name; 454 1.98 christos argv[1] = va_arg(ap, char *); 455 1.98 christos argv[2] = va_arg(ap, void *); 456 1.98 christos rv = terminal_gettc(el, 3, argv); 457 1.10 lukem break; 458 1.10 lukem } 459 1.13 simonb 460 1.23 christos case EL_GETCFN: 461 1.89 christos *va_arg(ap, el_rfunc_t *) = el_read_getfn(el->el_read); 462 1.24 christos rv = 0; 463 1.24 christos break; 464 1.24 christos 465 1.24 christos case EL_CLIENTDATA: 466 1.42 christos *va_arg(ap, void **) = el->el_data; 467 1.34 christos rv = 0; 468 1.34 christos break; 469 1.34 christos 470 1.34 christos case EL_UNBUFFERED: 471 1.71 christos *va_arg(ap, int *) = (el->el_flags & UNBUFFERED) != 0; 472 1.23 christos rv = 0; 473 1.23 christos break; 474 1.19 lukem 475 1.44 christos case EL_GETFP: 476 1.44 christos { 477 1.44 christos int what; 478 1.44 christos FILE **fpp; 479 1.44 christos 480 1.44 christos what = va_arg(ap, int); 481 1.44 christos fpp = va_arg(ap, FILE **); 482 1.44 christos rv = 0; 483 1.44 christos switch (what) { 484 1.44 christos case 0: 485 1.44 christos *fpp = el->el_infile; 486 1.44 christos break; 487 1.44 christos case 1: 488 1.44 christos *fpp = el->el_outfile; 489 1.44 christos break; 490 1.44 christos case 2: 491 1.44 christos *fpp = el->el_errfile; 492 1.44 christos break; 493 1.44 christos default: 494 1.44 christos rv = -1; 495 1.44 christos break; 496 1.44 christos } 497 1.44 christos break; 498 1.44 christos } 499 1.19 lukem default: 500 1.19 lukem rv = -1; 501 1.44 christos break; 502 1.19 lukem } 503 1.42 christos va_end(ap); 504 1.10 lukem 505 1.68 christos return rv; 506 1.19 lukem } 507 1.10 lukem 508 1.10 lukem 509 1.1 cgd /* el_line(): 510 1.1 cgd * Return editing info 511 1.1 cgd */ 512 1.88 christos const LineInfoW * 513 1.86 christos el_wline(EditLine *el) 514 1.1 cgd { 515 1.19 lukem 516 1.86 christos return (const LineInfoW *)(void *)&el->el_line; 517 1.1 cgd } 518 1.1 cgd 519 1.1 cgd 520 1.1 cgd /* el_source(): 521 1.1 cgd * Source a file 522 1.1 cgd */ 523 1.88 christos int 524 1.19 lukem el_source(EditLine *el, const char *fname) 525 1.1 cgd { 526 1.19 lukem FILE *fp; 527 1.19 lukem size_t len; 528 1.77 christos ssize_t slen; 529 1.27 christos char *ptr; 530 1.64 christos char *path = NULL; 531 1.87 christos const wchar_t *dptr; 532 1.64 christos int error = 0; 533 1.19 lukem 534 1.19 lukem fp = NULL; 535 1.19 lukem if (fname == NULL) { 536 1.29 christos #ifdef HAVE_ISSETUGID 537 1.19 lukem if (issetugid()) 538 1.68 christos return -1; 539 1.93 kre 540 1.93 kre if ((fname = getenv("EDITRC")) == NULL) { 541 1.93 kre static const char elpath[] = "/.editrc"; 542 1.93 kre size_t plen = sizeof(elpath); 543 1.93 kre 544 1.93 kre if ((ptr = getenv("HOME")) == NULL) 545 1.93 kre return -1; 546 1.93 kre plen += strlen(ptr); 547 1.99 christos if ((path = el_calloc(plen, sizeof(*path))) == NULL) 548 1.93 kre return -1; 549 1.93 kre (void)snprintf(path, plen, "%s%s", ptr, 550 1.93 kre elpath + (*ptr == '\0')); 551 1.93 kre fname = path; 552 1.93 kre } 553 1.27 christos #else 554 1.27 christos /* 555 1.27 christos * If issetugid() is missing, always return an error, in order 556 1.27 christos * to keep from inadvertently opening up the user to a security 557 1.27 christos * hole. 558 1.27 christos */ 559 1.68 christos return -1; 560 1.27 christos #endif 561 1.19 lukem } 562 1.93 kre if (fname[0] == '\0') 563 1.93 kre return -1; 564 1.93 kre 565 1.19 lukem if (fp == NULL) 566 1.19 lukem fp = fopen(fname, "r"); 567 1.64 christos if (fp == NULL) { 568 1.64 christos el_free(path); 569 1.68 christos return -1; 570 1.64 christos } 571 1.19 lukem 572 1.77 christos ptr = NULL; 573 1.77 christos len = 0; 574 1.77 christos while ((slen = getline(&ptr, &len, fp)) != -1) { 575 1.63 christos if (*ptr == '\n') 576 1.63 christos continue; /* Empty line. */ 577 1.77 christos if (slen > 0 && ptr[--slen] == '\n') 578 1.77 christos ptr[slen] = '\0'; 579 1.77 christos 580 1.56 christos dptr = ct_decode_string(ptr, &el->el_scratch); 581 1.56 christos if (!dptr) 582 1.56 christos continue; 583 1.55 christos /* loop until first non-space char or EOL */ 584 1.85 christos while (*dptr != '\0' && iswspace(*dptr)) 585 1.56 christos dptr++; 586 1.56 christos if (*dptr == '#') 587 1.55 christos continue; /* ignore, this is a comment line */ 588 1.64 christos if ((error = parse_line(el, dptr)) == -1) 589 1.64 christos break; 590 1.1 cgd } 591 1.76 christos free(ptr); 592 1.1 cgd 593 1.64 christos el_free(path); 594 1.19 lukem (void) fclose(fp); 595 1.68 christos return error; 596 1.1 cgd } 597 1.1 cgd 598 1.1 cgd 599 1.1 cgd /* el_resize(): 600 1.1 cgd * Called from program when terminal is resized 601 1.1 cgd */ 602 1.88 christos void 603 1.19 lukem el_resize(EditLine *el) 604 1.1 cgd { 605 1.19 lukem int lins, cols; 606 1.19 lukem sigset_t oset, nset; 607 1.19 lukem 608 1.19 lukem (void) sigemptyset(&nset); 609 1.19 lukem (void) sigaddset(&nset, SIGWINCH); 610 1.19 lukem (void) sigprocmask(SIG_BLOCK, &nset, &oset); 611 1.19 lukem 612 1.19 lukem /* get the correct window size */ 613 1.64 christos if (terminal_get_size(el, &lins, &cols)) 614 1.64 christos terminal_change_size(el, lins, cols); 615 1.1 cgd 616 1.19 lukem (void) sigprocmask(SIG_SETMASK, &oset, NULL); 617 1.9 christos } 618 1.14 lukem 619 1.9 christos 620 1.9 christos /* el_beep(): 621 1.9 christos * Called from the program to beep 622 1.9 christos */ 623 1.88 christos void 624 1.19 lukem el_beep(EditLine *el) 625 1.9 christos { 626 1.19 lukem 627 1.64 christos terminal_beep(el); 628 1.1 cgd } 629 1.10 lukem 630 1.10 lukem 631 1.10 lukem /* el_editmode() 632 1.10 lukem * Set the state of EDIT_DISABLED from the `edit' command. 633 1.10 lukem */ 634 1.91 christos libedit_private int 635 1.10 lukem /*ARGSUSED*/ 636 1.87 christos el_editmode(EditLine *el, int argc, const wchar_t **argv) 637 1.10 lukem { 638 1.87 christos const wchar_t *how; 639 1.10 lukem 640 1.19 lukem if (argv == NULL || argc != 2 || argv[1] == NULL) 641 1.68 christos return -1; 642 1.10 lukem 643 1.19 lukem how = argv[1]; 644 1.86 christos if (wcscmp(how, L"on") == 0) { 645 1.19 lukem el->el_flags &= ~EDIT_DISABLED; 646 1.39 christos tty_rawmode(el); 647 1.86 christos } else if (wcscmp(how, L"off") == 0) { 648 1.39 christos tty_cookedmode(el); 649 1.19 lukem el->el_flags |= EDIT_DISABLED; 650 1.39 christos } 651 1.19 lukem else { 652 1.85 christos (void) fprintf(el->el_errfile, "edit: Bad value `%ls'.\n", 653 1.56 christos how); 654 1.68 christos return -1; 655 1.19 lukem } 656 1.68 christos return 0; 657 1.19 lukem } 658