iconv: Bail out of the loop when an illegal sequence of bytes occurs.
[elinks/elinks-j605.git] / src / osdep / osdep.c
bloba8895539b9d51f47947e1225bc0f83a7519c29b6
1 /* Features which vary with the OS */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include <errno.h>
8 #ifdef HAVE_IO_H
9 #include <io.h> /* For win32 && set_bin(). */
10 #endif
11 #include <signal.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #ifdef HAVE_SYS_IOCTL_H
16 #include <sys/ioctl.h>
17 #endif
18 #ifdef HAVE_SYS_SIGNAL_H
19 #include <sys/signal.h>
20 #endif
21 #include <sys/types.h>
22 #ifdef HAVE_SYS_SOCKET_H
23 #include <sys/socket.h> /* Need to be after sys/types.h */
24 #endif
25 #ifdef HAVE_FCNTL_H
26 #include <fcntl.h> /* OS/2 needs this after sys/types.h */
27 #endif
29 /* We need to have it here. Stupid BSD. */
30 #ifdef HAVE_NETINET_IN_H
31 #include <netinet/in.h>
32 #endif
33 #ifdef HAVE_ARPA_INET_H
34 #include <arpa/inet.h>
35 #endif
37 /* This is for some exotic TOS mangling when handling passive FTP sockets. */
38 #ifdef HAVE_NETINET_IN_SYSTM_H
39 #include <netinet/in_systm.h>
40 #else
41 #ifdef HAVE_NETINET_IN_SYSTEM_H
42 #include <netinet/in_system.h>
43 #endif
44 #endif
45 #ifdef HAVE_NETINET_IP_H
46 #include <netinet/ip.h>
47 #endif
49 #ifdef HAVE_TERMIOS_H
50 #include <termios.h>
51 #endif
53 #ifdef HAVE_UNISTD_H
54 #include <unistd.h>
55 #endif
57 #ifdef HAVE_LOCALE_H
58 /* For the sake of SunOS, keep this away from files including
59 * intl/gettext/libintl.h because <locale.h> includes system <libintl.h> which
60 * either includes system gettext header or contains gettext function
61 * declarations. */
62 #include <locale.h>
63 #endif
65 #ifdef HAVE_X11
66 #include <X11/Xlib.h>
67 #include <X11/Xutil.h>
68 #endif
71 #include "elinks.h"
73 #include "main/select.h"
74 #include "osdep/osdep.h"
75 #include "osdep/signals.h"
76 #include "terminal/terminal.h"
77 #include "util/conv.h"
78 #include "util/memory.h"
79 #include "util/string.h"
82 /* Set a file descriptor to non-blocking mode. It returns a non-zero value
83 * on error. */
84 int
85 set_nonblocking_fd(int fd)
87 #if defined(O_NONBLOCK) || defined(O_NDELAY)
88 int flags = fcntl(fd, F_GETFL, 0);
90 if (flags < 0) return -1;
91 #if defined(O_NONBLOCK)
92 return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
93 #else
94 return fcntl(fd, F_SETFL, flags | O_NDELAY);
95 #endif
97 #elif defined(FIONBIO)
98 int flag = 1;
100 return ioctl(fd, FIONBIO, &flag);
101 #else
102 return 0;
103 #endif
106 /* Set a file descriptor to blocking mode. It returns a non-zero value on
107 * error. */
109 set_blocking_fd(int fd)
111 #if defined(O_NONBLOCK) || defined(O_NDELAY)
112 int flags = fcntl(fd, F_GETFL, 0);
114 if (flags < 0) return -1;
115 #if defined(O_NONBLOCK)
116 return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
117 #else
118 return fcntl(fd, F_SETFL, flags & ~O_NDELAY);
119 #endif
121 #elif defined(FIONBIO)
122 int flag = 0;
124 return ioctl(fd, FIONBIO, &flag);
125 #else
126 return 0;
127 #endif
130 void
131 set_ip_tos_throughput(int socket)
133 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
134 int on = IPTOS_THROUGHPUT;
136 setsockopt(socket, IPPROTO_IP, IP_TOS, (char *) &on, sizeof(on));
137 #endif
141 get_e(unsigned char *env)
143 char *v = getenv(env);
145 return (v ? atoi(v) : 0);
148 unsigned char *
149 get_cwd(void)
151 int bufsize = 128;
152 unsigned char *buf;
154 while (1) {
155 buf = mem_alloc(bufsize);
156 if (!buf) return NULL;
157 if (getcwd(buf, bufsize)) return buf;
158 mem_free(buf);
160 if (errno == EINTR) continue;
161 if (errno != ERANGE) return NULL;
162 bufsize += 128;
165 return NULL;
168 void
169 set_cwd(unsigned char *path)
171 if (path) while (chdir(path) && errno == EINTR);
174 unsigned char *
175 get_shell(void)
177 unsigned char *shell = GETSHELL;
179 if (!shell || !*shell)
180 shell = DEFAULT_SHELL;
182 return shell;
186 /* Terminal size */
188 #if !defined(CONFIG_OS_OS2) && !defined(CONFIG_OS_WIN32)
190 static void
191 sigwinch(void *s)
193 ((void (*)(void)) s)();
196 void
197 handle_terminal_resize(int fd, void (*fn)(void))
199 install_signal_handler(SIGWINCH, sigwinch, fn, 0);
202 void
203 unhandle_terminal_resize(int fd)
205 install_signal_handler(SIGWINCH, NULL, NULL, 0);
208 void
209 get_terminal_size(int fd, int *x, int *y)
211 struct winsize ws;
213 if (ioctl(1, TIOCGWINSZ, &ws) != -1) {
214 *x = ws.ws_col;
215 *y = ws.ws_row;
216 } else {
217 *x = 0;
218 *y = 0;
221 if (!*x) {
222 *x = get_e("COLUMNS");
223 if (!*x) *x = DEFAULT_TERMINAL_WIDTH;
225 if (!*y) {
226 *y = get_e("LINES");
227 if (!*y) *y = DEFAULT_TERMINAL_HEIGHT;
231 #endif
233 /* Pipe */
235 #if defined(CONFIG_OS_UNIX) || defined(CONFIG_OS_BEOS) || defined(CONFIG_OS_RISCOS)
237 void
238 set_bin(int fd)
243 c_pipe(int *fd)
245 return pipe(fd);
248 #elif defined(CONFIG_OS_OS2) || defined(CONFIG_OS_WIN32)
250 void
251 set_bin(int fd)
253 setmode(fd, O_BINARY);
257 c_pipe(int *fd)
259 int r = pipe(fd);
261 if (!r) {
262 set_bin(fd[0]);
263 set_bin(fd[1]);
266 return r;
269 #endif
271 /* Exec */
274 is_twterm(void) /* Check if it make sense to call a twterm. */
276 static int tw = -1;
278 if (tw == -1) tw = !!getenv("TWDISPLAY");
280 return tw;
284 is_gnuscreen(void)
286 static int screen = -1;
288 if (screen == -1) screen = !!getenv("STY");
290 return screen;
294 #if defined(CONFIG_OS_UNIX) || defined(CONFIG_OS_WIN32)
297 is_xterm(void)
299 static int xt = -1;
301 if (xt == -1) {
302 /* Paraphrased from debian bug 228977:
304 * It is not enough to simply check the DISPLAY env variable,
305 * as it is pretty legal to have a DISPLAY set. While these
306 * days this practice is pretty uncommon, it still makes sense
307 * sometimes, especially for people who prefer the text mode
308 * for some reason. Only relying on DISPLAY will results in bad
309 * codes being written to the terminal.
311 * Any real xterm derivative sets WINDOWID as well.
312 * Unfortunately, konsole is an exception, and it needs to be
313 * checked for separately.
315 * FIXME: The code below still fails to detect some terminals
316 * that do support a title (like the popular PuTTY ssh client).
317 * In general, proper xterm detection is a nightmarish task...
319 * -- Adam Borowski <kilobyte@mimuw.edu.pl> */
320 unsigned char *display = getenv("DISPLAY");
321 unsigned char *windowid = getenv("WINDOWID");
323 if (!windowid || !*windowid)
324 windowid = getenv("KONSOLE_DCOP_SESSION");
325 xt = (display && *display && windowid && *windowid);
328 return xt;
331 #endif
333 unsigned int resize_count = 0;
335 #ifndef CONFIG_OS_OS2
337 #if !(defined(CONFIG_OS_BEOS) && defined(HAVE_SETPGID)) && !defined(CONFIG_OS_WIN32)
340 exe(unsigned char *path)
342 return system(path);
345 #endif
347 static unsigned char *clipboard;
349 unsigned char *
350 get_clipboard_text(void)
352 /* The following support for GNU Screen's clipboard is
353 * disabled for two reasons:
355 * 1. It does not actually return the string from that
356 * clipboard, but rather causes the clipboard contents to
357 * appear in stdin. get_clipboard_text is normally called
358 * because the user pressed a Paste key in an input field,
359 * so the characters end up being inserted in that field;
360 * but if there are newlines in the clipboard, then the
361 * field may lose focus, in which case the remaining
362 * characters may trigger arbitrary actions in ELinks.
364 * 2. It pastes from both GNU Screen's clipboard and the ELinks
365 * internal clipboard. Because set_clipboard_text also sets
366 * them both, the same text would typically get pasted twice.
368 * Users can instead use the GNU Screen key bindings to run the
369 * paste command. This method still suffers from problem 1 but
370 * any user of GNU Screen should know that already. */
371 #if 0
372 /* GNU Screen's clipboard */
373 if (is_gnuscreen()) {
374 struct string str;
376 if (!init_string(&str)) return NULL;
378 add_to_string(&str, "screen -X paste .");
379 if (str.length) exe(str.source);
380 if (str.source) done_string(&str);
382 #endif
384 return stracpy(empty_string_or_(clipboard));
387 void
388 set_clipboard_text(unsigned char *data)
390 /* GNU Screen's clipboard */
391 if (is_gnuscreen()) {
392 struct string str;
394 if (!init_string(&str)) return;
396 add_to_string(&str, "screen -X register . ");
397 add_shell_quoted_to_string(&str, data, strlen(data));
399 if (str.length) exe(str.source);
400 if (str.source) done_string(&str);
403 /* Shouldn't complain about leaks. */
404 if (clipboard) free(clipboard);
405 clipboard = strdup(data);
408 /* Set xterm-like term window's title. */
409 void
410 set_window_title(unsigned char *title, int codepage)
412 struct string filtered;
414 #ifndef HAVE_SYS_CYGWIN_H
415 /* Check if we're in a xterm-like terminal. */
416 if (!is_xterm()) return;
417 #endif
419 if (!init_string(&filtered)) return;
421 /* Copy title to filtered if different from NULL */
422 if (title) {
423 unsigned char *scan = title;
424 unsigned char *end = title + strlen(title);
426 /* Remove control characters, so that they cannot
427 * interfere with the command we send to the terminal.
428 * However, do not attempt to limit the title length
429 * to terminal width, because the title is usually
430 * drawn in a different font anyway. */
431 /* Note that this is the right place where to do it, since
432 * potential alternative set_window_title() routines might
433 * want to take different precautions. */
434 for (;;) {
435 unsigned char *charbegin = scan;
436 unicode_val_T unicode
437 = cp_to_unicode(codepage, &scan, end);
438 int charlen = scan - charbegin;
440 if (unicode == UCS_NO_CHAR)
441 break;
443 /* This need not recognize all Unicode control
444 * characters. Only those that can make the
445 * terminal misparse the command. */
446 if (unicode < 0x20
447 || (unicode >= 0x7F && unicode < 0xA0))
448 continue;
450 /* If the title is getting too long, truncate
451 * it and add an ellipsis.
453 * xterm entirely rejects 1024-byte or longer
454 * titles. GNU Screen 4.00.03 misparses
455 * titles longer than 765 bytes, and is unable
456 * to display the title in hardstatus if the
457 * title and other stuff together exceed 766
458 * bytes. So set the limit quite a bit lower. */
459 if (filtered.length + charlen >= 600 - 3) {
460 add_to_string(&filtered, "...");
461 break;
464 add_bytes_to_string(&filtered, charbegin, charlen);
468 /* Send terminal escape sequence + title string */
469 printf("\033]0;%s\a", filtered.source);
471 #if 0
472 /* Miciah don't like this so it is disabled because it changes the
473 * default window name. --jonas */
474 /* Set the GNU screen window name */
475 if (is_gnuscreen())
476 printf("\033k%s\033\134", filtered.source);
477 #endif
479 fflush(stdout);
481 done_string(&filtered);
484 #ifdef HAVE_X11
485 static int x_error = 0;
487 static int
488 catch_x_error(void)
490 x_error = 1;
491 return 0;
494 /** Convert a STRING XTextProperty to a string in the specified codepage.
496 * @return the string that the caller must free with mem_free(),
497 * or NULL on error. */
498 static unsigned char *
499 xprop_to_string(Display *display, const XTextProperty *text_prop, int to_cp)
501 int from_cp;
502 char **list = NULL;
503 int count = 0;
504 struct conv_table *convert_table;
505 unsigned char *ret = NULL;
507 /* <X11/Xlib.h> defines X_HAVE_UTF8_STRING if
508 * Xutf8TextPropertyToTextList is available.
510 * The X...TextPropertyToTextList functions return a negative
511 * error code, or Success=0, or the number of unconvertible
512 * characters. Use the result even if some characters were
513 * unconvertible, because convert_string() can be lossy too,
514 * and it seems better to restore an approximation of the
515 * original title than to restore a default title that may be
516 * entirely different. */
517 #if defined(CONFIG_UTF8) && defined(X_HAVE_UTF8_STRING)
519 from_cp = get_cp_index("UTF-8");
520 if (Xutf8TextPropertyToTextList(display, text_prop, &list,
521 &count) < 0)
522 return NULL;
524 #else /* !defined(X_HAVE_UTF8_STRING) || !defined(CONFIG_UTF8) */
526 from_cp = get_cp_index("System");
527 if (XmbTextPropertyToTextList(display, text_prop, &list,
528 &count) < 0)
529 return NULL;
531 #endif /* !defined(X_HAVE_UTF8_STRING) || !defined(CONFIG_UTF8) */
533 convert_table = get_translation_table(from_cp, to_cp);
534 if (count >= 1 && convert_table)
535 ret = convert_string(convert_table, list[0], strlen(list[0]),
536 to_cp, CSM_NONE, NULL, NULL, NULL);
538 XFreeStringList(list);
539 return ret;
541 #endif /* HAVE_X11 */
543 unsigned char *
544 get_window_title(int codepage)
546 #ifdef HAVE_X11
547 /* Following code is stolen from our beloved vim. */
548 unsigned char *winid;
549 Display *display;
550 Window window, root, parent, *children;
551 XTextProperty text_prop;
552 Status status;
553 unsigned int num_children;
554 unsigned char *ret = NULL;
556 if (!is_xterm())
557 return NULL;
559 winid = getenv("WINDOWID");
560 if (!winid)
561 return NULL;
562 window = (Window) atol(winid);
563 if (!window)
564 return NULL;
566 display = XOpenDisplay(NULL);
567 if (!display)
568 return NULL;
570 /* If WINDOWID is bad, we don't want X to abort us. */
571 x_error = 0;
572 XSetErrorHandler((int (*)(Display *, XErrorEvent *)) catch_x_error);
574 status = XGetWMName(display, window, &text_prop);
575 /* status = XGetWMIconName(x11_display, x11_window, &text_prop); */
576 while (!x_error && (!status || !text_prop.value)) {
577 if (!XQueryTree(display, window, &root, &parent, &children, &num_children))
578 break;
579 if (children)
580 XFree((void *) children);
581 if (parent == root || parent == 0)
582 break;
583 window = parent;
584 status = XGetWMName(display, window, &text_prop);
587 if (!x_error && status && text_prop.value) {
588 ret = xprop_to_string(display, &text_prop, codepage);
589 XFree(text_prop.value);
592 XCloseDisplay(display);
594 return ret;
595 #else
596 /* At least reset the window title to a blank one. */
597 return stracpy("");
598 #endif
602 resize_window(int width, int height, int old_width, int old_height)
604 #ifdef HAVE_X11
605 /* Following code is stolen from our beloved vim. */
606 unsigned char *winid;
607 Display *display;
608 Window window;
609 Status status;
610 XWindowAttributes attributes;
612 if (!is_xterm())
613 return -1;
615 winid = getenv("WINDOWID");
616 if (!winid)
617 return -1;
618 window = (Window) atol(winid);
619 if (!window)
620 return -1;
622 display = XOpenDisplay(NULL);
623 if (!display)
624 return -1;
626 /* If WINDOWID is bad, we don't want X to abort us. */
627 x_error = 0;
628 XSetErrorHandler((int (*)(Display *, XErrorEvent *)) catch_x_error);
630 status = XGetWindowAttributes(display, window, &attributes);
632 while (!x_error && !status) {
633 Window root, parent, *children;
634 unsigned int num_children;
636 if (!XQueryTree(display, window, &root, &parent, &children, &num_children))
637 break;
638 if (children)
639 XFree((void *) children);
640 if (parent == root || parent == 0)
641 break;
642 window = parent;
643 status = XGetWindowAttributes(display, window, &attributes);
646 if (!x_error && status) {
647 XSizeHints *size_hints;
648 long mask;
649 int px_width = 0;
650 int px_height = 0;
652 /* With xterm 210, a window with 80x24 characters at
653 * a 6x13 font appears to have 484x316 pixels; both
654 * the width and height include four extra pixels.
655 * Computing a new size by scaling these values often
656 * results in windows that cannot display as many
657 * characters as was intended. We can do better if we
658 * can find out the actual size of character cells.
659 * If the terminal emulator has set a window size
660 * increment, assume that is the cell size. */
661 size_hints = XAllocSizeHints();
662 if (size_hints != NULL
663 && XGetWMNormalHints(display, window, size_hints, &mask)
664 && (mask & PResizeInc) != 0) {
665 px_width = attributes.width
666 + (width - old_width) * size_hints->width_inc;
667 px_height = attributes.height
668 + (height - old_height) * size_hints->height_inc;
670 if (px_width <= 0 || px_height <= 0) {
671 double ratio_width = (double) attributes.width / old_width;
672 double ratio_height = (double) attributes.height / old_height;
674 px_width = (int) ((double) width * ratio_width);
675 px_height = (int) ((double) height * ratio_height);
678 if (size_hints)
679 XFree(size_hints);
681 status = XResizeWindow(display, window, px_width, px_height);
682 while (!x_error && !status) {
683 Window root, parent, *children;
684 unsigned int num_children;
686 if (!XQueryTree(display, window, &root, &parent, &children, &num_children))
687 break;
688 if (children)
689 XFree((void *) children);
690 if (parent == root || parent == 0)
691 break;
692 window = parent;
693 status = XResizeWindow(display, window, px_width, px_height);
697 XCloseDisplay(display);
699 return 0;
700 #else
701 return -1;
702 #endif
705 #endif
708 /* Threads */
710 #if defined(HAVE_BEGINTHREAD) || defined(CONFIG_OS_BEOS)
712 struct tdata {
713 void (*fn)(void *, int);
714 int h;
715 unsigned char data[1];
718 void
719 bgt(struct tdata *t)
721 #ifdef SIGPIPE
722 signal(SIGPIPE, SIG_IGN);
723 #endif
724 t->fn(t->data, t->h);
725 write(t->h, "x", 1);
726 close(t->h);
727 free(t);
730 #else
733 start_thread(void (*fn)(void *, int), void *ptr, int l)
735 int p[2];
736 pid_t pid;
738 if (c_pipe(p) < 0) return -1;
739 if (set_nonblocking_fd(p[0]) < 0) return -1;
740 if (set_nonblocking_fd(p[1]) < 0) return -1;
742 pid = fork();
743 if (!pid) {
744 struct terminal *term;
746 /* Close input in this thread; otherwise, if it will live
747 * longer than its parent, it'll block the terminal until it'll
748 * quit as well; this way it will hopefully just die unseen and
749 * in background, causing no trouble. */
750 /* Particularly, when async dns resolving was in progress and
751 * someone quitted ELinks, it could make a delay before the
752 * terminal would be really freed and returned to shell. */
753 foreach (term, terminals)
754 if (term->fdin > 0)
755 close(term->fdin);
757 close(p[0]);
758 fn(ptr, p[1]);
759 write(p[1], "x", 1);
760 close(p[1]);
761 /* We use _exit() here instead of exit(), see
762 * http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC6 for
763 * reasons. Fixed by Sven Neumann <sven@convergence.de>. */
764 _exit(0);
766 if (pid == -1) {
767 close(p[0]);
768 close(p[1]);
769 return -1;
772 close(p[1]);
773 return p[0];
776 #endif
779 #ifndef OS2_MOUSE
780 void
781 want_draw(void)
785 void
786 done_draw(void)
789 #endif
792 #if !defined(CONFIG_OS_WIN32)
794 get_output_handle(void)
796 return 1;
800 get_ctl_handle(void)
802 static int fd = -1;
804 if (isatty(0)) return 0;
805 if (fd < 0) fd = open("/dev/tty", O_RDONLY);
806 return fd;
808 #endif
811 #if !defined(CONFIG_OS_BEOS) && !(defined(HAVE_BEGINTHREAD) && defined(HAVE_READ_KBD)) \
812 && !defined(CONFIG_OS_WIN32)
815 get_input_handle(void)
817 return get_ctl_handle();
820 #endif
822 #ifndef CONFIG_OS_WIN32
824 void
825 init_osdep(void)
827 #ifdef HAVE_LOCALE_H
828 setlocale(LC_ALL, "");
829 #endif
832 #endif
834 #if defined(CONFIG_OS_UNIX) || defined(CONFIG_OS_OS2) || defined(CONFIG_OS_RISCOS)
836 void
837 terminate_osdep(void)
841 #endif
843 #ifndef CONFIG_OS_BEOS
845 void
846 block_stdin(void)
850 void
851 unblock_stdin(void)
855 #endif
858 void
859 elinks_cfmakeraw(struct termios *t)
861 /* This elinks_cfmakeraw() intentionally leaves the following
862 * settings unchanged, even though the standard cfmakeraw()
863 * would change some of them:
865 * - c_cflag & CSIZE: number of bits per character.
866 * Bug 54 asked ELinks not to change this.
867 * - c_cflag & (PARENB | PARODD): parity bit in characters.
868 * Bug 54 asked ELinks not to change this.
869 * - c_iflag & (IXON | IXOFF | IXANY): XON/XOFF flow control.
871 * The reasoning is, if the user has set up unusual values for
872 * those settings before starting ELinks, then the terminal
873 * probably expects those values and ELinks should not mess
874 * with them. */
875 t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);
876 t->c_oflag &= ~OPOST;
877 t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
878 t->c_cc[VMIN] = 1;
879 t->c_cc[VTIME] = 0;
882 #if !defined(CONFIG_MOUSE) || (!defined(CONFIG_GPM) && !defined(CONFIG_SYSMOUSE) && !defined(OS2_MOUSE))
884 void *
885 handle_mouse(int cons, void (*fn)(void *, unsigned char *, int),
886 void *data)
888 return NULL;
891 void
892 unhandle_mouse(void *data)
896 void
897 suspend_mouse(void *data)
901 void
902 resume_mouse(void *data)
906 #endif
908 #ifndef CONFIG_OS_WIN32
909 /* Create a bitmask consisting from system-independent envirnoment modifiers.
910 * This is then complemented by system-specific modifiers in an appropriate
911 * get_system_env() routine. */
912 static int
913 get_common_env(void)
915 int env = 0;
917 if (is_xterm()) env |= ENV_XWIN;
918 if (is_twterm()) env |= ENV_TWIN;
919 if (is_gnuscreen()) env |= ENV_SCREEN;
921 /* ENV_CONSOLE is always set now and indicates that we are working w/ a
922 * displaying-capable character-adressed terminal. Sounds purely
923 * theoretically now, but it already makes some things easier and it
924 * could give us interesting opportunities later (after graphical
925 * frontends will be introduced, when working in some mysterious daemon
926 * mode or who knows what ;). --pasky */
927 env |= ENV_CONSOLE;
929 return env;
931 #endif
933 #if defined(CONFIG_OS_UNIX) || defined(CONFIG_OS_RISCOS)
935 get_system_env(void)
937 return get_common_env();
939 #endif
943 can_resize_window(int environment)
945 return !!(environment & (ENV_OS2VIO | ENV_XWIN));
948 #ifndef CONFIG_OS_OS2
950 can_open_os_shell(int environment)
952 return 1;
955 void
956 set_highpri(void)
959 #endif
962 unsigned char *
963 get_system_str(int xwin)
965 return xwin ? SYSTEM_STR "-xwin" : SYSTEM_STR;