📄 osdep.c
字号:
/* Features which vary with the OS *//* $Id: osdep.c,v 1.154.4.10 2005/04/05 21:08:42 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <errno.h>#ifdef HAVE_IO_H#include <io.h> /* For win32 && set_bin(). */#endif#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef HAVE_SYS_IOCTL_H#include <sys/ioctl.h>#endif#ifdef HAVE_SYS_SIGNAL_H#include <sys/signal.h>#endif#include <sys/types.h>#ifdef HAVE_SYS_SOCKET_H#include <sys/socket.h> /* Need to be after sys/types.h */#endif#ifdef HAVE_FCNTL_H#include <fcntl.h> /* OS/2 needs this after sys/types.h */#endif/* We need to have it here. Stupid BSD. */#ifdef HAVE_NETINET_IN_H#include <netinet/in.h>#endif#ifdef HAVE_ARPA_INET_H#include <arpa/inet.h>#endif/* This is for some exotic TOS mangling when handling passive FTP sockets. */#ifdef HAVE_NETINET_IN_SYSTM_H#include <netinet/in_systm.h>#else#ifdef HAVE_NETINET_IN_SYSTEM_H#include <netinet/in_system.h>#endif#endif#ifdef HAVE_NETINET_IP_H#include <netinet/ip.h>#endif#ifdef HAVE_TERMIOS_H#include <termios.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_LOCALE_H/* For the sake of SunOS, keep this away from files including * intl/gettext/libintl.h because <locale.h> includes system <libintl.h> which * either includes system gettext header or contains gettext function * declarations. */#include <locale.h>#endif#ifdef HAVE_X11#include <X11/Xlib.h>#include <X11/Xutil.h>#endif#include "elinks.h"#include "lowlevel/select.h"#include "lowlevel/signals.h"#include "osdep/osdep.h"#include "sched/session.h"#include "terminal/terminal.h"#include "util/conv.h"#include "util/memory.h"#include "util/string.h"/* Set a file descriptor to non-blocking mode. It returns a non-zero value * on error. */intset_nonblocking_fd(int fd){#if defined(O_NONBLOCK) || defined(O_NDELAY) int flags = fcntl(fd, F_GETFL, 0); if (flags < 0) return -1;#if defined(O_NONBLOCK) return fcntl(fd, F_SETFL, flags | O_NONBLOCK);#else return fcntl(fd, F_SETFL, flags | O_NDELAY);#endif#elif defined(FIONBIO) int flag = 1; return ioctl(fd, FIONBIO, &flag);#else return 0;#endif}/* Set a file descriptor to blocking mode. It returns a non-zero value on * error. */intset_blocking_fd(int fd){#if defined(O_NONBLOCK) || defined(O_NDELAY) int flags = fcntl(fd, F_GETFL, 0); if (flags < 0) return -1;#if defined(O_NONBLOCK) return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);#else return fcntl(fd, F_SETFL, flags & ~O_NDELAY);#endif#elif defined(FIONBIO) int flag = 0; return ioctl(fd, FIONBIO, &flag);#else return 0;#endif}voidset_ip_tos_throughput(int socket){#if defined(IP_TOS) && defined(IPTOS_THROUGHPUT) int on = IPTOS_THROUGHPUT; setsockopt(socket, IPPROTO_IP, IP_TOS, (char *) &on, sizeof(on));#endif}intget_e(unsigned char *env){ char *v = getenv(env); return (v ? atoi(v) : 0);}unsigned char *get_cwd(void){ int bufsize = 128; unsigned char *buf; while (1) { buf = mem_alloc(bufsize); if (!buf) return NULL; if (getcwd(buf, bufsize)) return buf; mem_free(buf); if (errno == EINTR) continue; if (errno != ERANGE) return NULL; bufsize += 128; } return NULL;}voidset_cwd(unsigned char *path){ if (path) while (chdir(path) && errno == EINTR);}unsigned char *get_shell(void){ unsigned char *shell = GETSHELL; if (!shell || !*shell) shell = DEFAULT_SHELL; return shell;}/* Terminal size */#if !defined(CONFIG_OS2) && !defined(CONFIG_WIN32)static voidsigwinch(void *s){ ((void (*)(void)) s)();}voidhandle_terminal_resize(int fd, void (*fn)(void)){ install_signal_handler(SIGWINCH, sigwinch, fn, 0);}voidunhandle_terminal_resize(int fd){ install_signal_handler(SIGWINCH, NULL, NULL, 0);}voidget_terminal_size(int fd, int *x, int *y){ struct winsize ws; if (ioctl(1, TIOCGWINSZ, &ws) != -1) { *x = ws.ws_col; *y = ws.ws_row; } else { *x = 0; *y = 0; } if (!*x) { *x = get_e("COLUMNS"); if (!*x) *x = DEFAULT_TERMINAL_WIDTH; } if (!*y) { *y = get_e("LINES"); if (!*y) *y = DEFAULT_TERMINAL_HEIGHT; }}#endif/* Pipe */#if defined(CONFIG_UNIX) || defined(CONFIG_BEOS) || defined(CONFIG_RISCOS)voidset_bin(int fd){}intc_pipe(int *fd){ return pipe(fd);}#elif defined(CONFIG_OS2) || defined(CONFIG_WIN32)voidset_bin(int fd){ setmode(fd, O_BINARY);}intc_pipe(int *fd){ int r = pipe(fd); if (!r) { set_bin(fd[0]); set_bin(fd[1]); } return r;}#endif/* Exec */intis_twterm(void) /* Check if it make sense to call a twterm. */{ static int tw = -1; if (tw == -1) tw = !!getenv("TWDISPLAY"); return tw;}intis_gnuscreen(void){ static int screen = -1; if (screen == -1) screen = !!getenv("STY"); return screen;}#if defined(CONFIG_UNIX) || defined(CONFIG_WIN32)intis_xterm(void){ static int xt = -1; if (xt == -1) { /* Paraphrased from debian bug 228977: * * It is not enough to simply check the DISPLAY env variable, * as it is pretty legal to have a DISPLAY set. While these * days this practice is pretty uncommon, it still makes sense * sometimes, especially for people who prefer the text mode * for some reason. Only relying on DISPLAY will results in bad * codes being written to the terminal. * * Any real xterm derivative sets WINDOWID as well. * Unfortunately, konsole is an exception, and it needs to be * checked for separately. * * FIXME: The code below still fails to detect some terminals * that do support a title (like the popular PuTTY ssh client). * In general, proper xterm detection is a nightmarish task... * * -- Adam Borowski <kilobyte@mimuw.edu.pl> */ unsigned char *display = getenv("DISPLAY"); unsigned char *windowid = getenv("WINDOWID"); if (!windowid || !*windowid) windowid = getenv("KONSOLE_DCOP_SESSION"); xt = (display && *display && windowid && *windowid); } return xt;}#endifunsigned int resize_count = 0;#ifndef CONFIG_OS2#if !(defined(CONFIG_BEOS) && defined(HAVE_SETPGID)) && !defined(CONFIG_WIN32)intexe(unsigned char *path){ return system(path);}#endifunsigned char *get_clipboard_text(void) /* !!! FIXME */{ unsigned char *ret = mem_alloc(1); if (ret) ret[0] = 0; return ret;}voidset_clipboard_text(unsigned char *data){ /* GNU Screen's clipboard */ if (is_gnuscreen()) { struct string str; if (!init_string(&str)) return; add_to_string(&str, "screen -X register . "); add_shell_quoted_to_string(&str, data, strlen(data)); if (str.length) exe(str.source); if (str.source) done_string(&str); } /* TODO: internal clipboard */}/* Set xterm-like term window's title. */voidset_window_title(unsigned char *title){ unsigned char *s; int xsize, ysize; int j = 0; /* Check if we're in a xterm-like terminal. */ if (!is_xterm() && !is_gnuscreen()) return; /* Retrieve terminal dimensions. */ get_terminal_size(0, &xsize, &ysize); /* Check if terminal width is reasonnable. */ if (xsize < 1 || xsize > 1024) return; /* Allocate space for title + 3 ending points + null char. */ s = (unsigned char *) mem_alloc((xsize + 3 + 1) * sizeof(unsigned char)); if (!s) return; /* Copy title to s if different from NULL */ if (title) { int i; /* We limit title length to terminal width and ignore control * chars if any. Note that in most cases window decoration * reduces printable width, so it's just a precaution. */ /* Note that this is the right place where to do it, since * potential alternative set_window_title() routines might * want to take different precautions. */ for (i = 0; title[i] && i < xsize; i++) { /* 0x80 .. 0x9f are ISO-8859-* control characters. * In some other encodings they could be used for * legitimate characters, though (ie. in Kamenicky). * We should therefore maybe check for these only * if the terminal is running in an ISO- encoding. */ if (iscntrl(title[i]) || (title[i] & 0x7f) < 0x20 || title[i] == 0x7f) continue; s[j++] = title[i]; } /* If title is truncated, add "..." */ if (i == xsize) { s[j++] = '.'; s[j++] = '.'; s[j++] = '.';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -