📄 os_dep.c
字号:
/*if (!(t = malloc(sizeof(struct tdata) + l))) return -1; t->fn = fn; t->h = p[1]; memcpy(t->data, ptr, l);*/ foreach(ts, thread_stacks) { if (ts->pid == -1 || kill(ts->pid, 0)) { if (ts->l >= l) goto ts_ok; else { struct thread_stack *tts = ts; ts = ts->prev; del_from_list(tts); free(tts->stack); free(tts); } } } if (!(ts = malloc(sizeof(struct thread_stack) + l))) goto fail; if (!(ts->stack = malloc(0x10000))) { free(ts); goto fail; } ts->l = l; add_to_list(thread_stacks, ts); ts_ok: ts->fn = fn; ts->h = p[1]; memcpy(ts->data, ptr, l); if ((ts->pid = __clone((int (*)(void *))bglt, (char *)ts->stack + 0x8000, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD, ts)) == -1) { fail: close(p[0]); close(p[1]); return -1; } return p[0];}#elif defined(HAVE_PTHREADS)#include <pthread.h>int start_thread(void (*fn)(void *, int), void *ptr, int l){ pthread_t thread; struct tdata *t; int p[2]; if (c_pipe(p) < 0) return -1; fcntl(p[0], F_SETFL, O_NONBLOCK); fcntl(p[1], F_SETFL, O_NONBLOCK); if (!(t = malloc(sizeof(struct tdata) + l))) return -1; t->fn = fn; t->h = p[1]; memcpy(t->data, ptr, l); if (pthread_create(&thread, NULL, (void *(*)(void *))bgpt, t)) { close(p[0]); close(p[1]); mem_free(t); return -1; } return p[0];}#elif defined(HAVE_ATHEOS_THREADS_H) && defined(HAVE_SPAWN_THREAD) && defined(HAVE_RESUME_THREAD)#include <atheos/threads.h>int start_thread(void (*fn)(void *, int), void *ptr, int l){ int p[2]; thread_id f; struct tdata *t; if (c_pipe(p) < 0) return -1; fcntl(p[0], F_SETFL, O_NONBLOCK); fcntl(p[1], F_SETFL, O_NONBLOCK); if (!(t = malloc(sizeof(struct tdata) + l))) return -1; t->fn = fn; t->h = p[1]; memcpy(t->data, ptr, l); if ((f = spawn_thread("links_lookup", abgt, 0, 0, t)) == -1) { close(p[0]); close(p[1]); mem_free(t); return -1; } resume_thread(f); return p[0];}#else /* HAVE_BEGINTHREAD */int start_thread(void (*fn)(void *, int), void *ptr, int l){ int p[2]; pid_t f; if (c_pipe(p) < 0) return -1; fcntl(p[0], F_SETFL, O_NONBLOCK); fcntl(p[1], F_SETFL, O_NONBLOCK); if (!(f = fork())) { close_fork_tty(); close(p[0]); fn(ptr, p[1]); write(p[1], "x", 1); close(p[1]); _exit(0); } if (f == -1) { close(p[0]); close(p[1]); return -1; } close(p[1]); return p[0];}#endif#ifndef USING_OS2_MOUSEvoid want_draw(void) {}void done_draw(void) {}#endifint get_output_handle(void) { return 1; }#if defined(OS2)int get_ctl_handle(void) { return get_input_handle(); }#elseint get_ctl_handle(void) { return 0; }#endif#if defined(BEOS)#elif defined(HAVE_BEGINTHREAD) && defined(HAVE_READ_KBD)int get_input_handle(void){ int fd[2]; if (ti != -1) return ti; if (is_xterm()) return 0; if (c_pipe(fd) < 0) return 0; ti = fd[0]; tp = fd[1]; _beginthread(input_thread, NULL, 0x10000, (void *)tp);/*#if defined(HAVE_MOUOPEN) && !defined(USE_GPM) _beginthread(mouse_thread, NULL, 0x10000, (void *)tp);#endif*/ return fd[0];}#elseint get_input_handle(void){ return 0;}#endif /* defined(HAVE_BEGINTHREAD) && defined(HAVE_READ_KBD) */void os_cfmakeraw(struct termios *t){#ifdef HAVE_CFMAKERAW cfmakeraw(t);#ifdef VMIN t->c_cc[VMIN] = 1;#endif#else t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); t->c_oflag &= ~OPOST; t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); t->c_cflag &= ~(CSIZE|PARENB); t->c_cflag |= CS8; t->c_cc[VMIN] = 1; t->c_cc[VTIME] = 0;#endif}#ifdef USE_GPMstruct gpm_mouse_spec { int h; void (*fn)(void *, unsigned char *, int); void *data;};static void gpm_mouse_in(struct gpm_mouse_spec *gms){ Gpm_Event gev; struct event ev; if (Gpm_GetEvent(&gev) <= 0) { set_handlers(gms->h, NULL, NULL, NULL, NULL); return; } ev.ev = EV_MOUSE; ev.x = gev.x - 1; ev.y = gev.y - 1; if (ev.x < 0) ev.x = 0; if (ev.y < 0) ev.y = 0; if (gev.buttons & GPM_B_LEFT) ev.b = B_LEFT; else if (gev.buttons & GPM_B_MIDDLE) ev.b = B_MIDDLE; else if (gev.buttons & GPM_B_RIGHT) ev.b = B_RIGHT; else return; if (gev.type & GPM_DOWN) ev.b |= B_DOWN; else if (gev.type & GPM_UP) ev.b |= B_UP; else if (gev.type & GPM_DRAG) ev.b |= B_DRAG; else return; gms->fn(gms->data, (char *)&ev, sizeof(struct event));}/* GPM installs its own signal handlers and we don't want them */sigset_t gpm_sigset;char gpm_sigset_valid;#ifdef SIGWINCHstruct sigaction gpm_winch;char gpm_winch_valid;#endif#ifdef SIGTSTPstruct sigaction gpm_tstp;char gpm_tstp_valid;#endifstatic void save_gpm_signals(void){ sigset_t sig; sigemptyset(&sig);#ifdef SIGWINCH sigaddset(&sig, SIGWINCH);#endif#ifdef SIGTSTP sigaddset(&sig, SIGTSTP);#endif gpm_sigset_valid = !sigprocmask(SIG_BLOCK, &sig, &gpm_sigset);#ifdef SIGWINCH gpm_winch_valid = !sigaction(SIGWINCH, NULL, &gpm_winch);#endif#ifdef SIGTSTP gpm_tstp_valid = !sigaction(SIGTSTP, NULL, &gpm_tstp);#endif}static void restore_gpm_signals(void){#ifdef SIGWINCH if (gpm_winch_valid) sigaction(SIGWINCH, &gpm_winch, NULL);#endif#ifdef SIGTSTP if (gpm_tstp_valid) sigaction(SIGTSTP, &gpm_tstp, NULL);#endif if (gpm_sigset_valid) sigprocmask(SIG_SETMASK, &gpm_sigset, NULL);}void *handle_mouse(int cons, void (*fn)(void *, unsigned char *, int), void *data){ int h; Gpm_Connect conn; struct gpm_mouse_spec *gms; conn.eventMask = ~GPM_MOVE; conn.defaultMask = GPM_MOVE; conn.minMod = 0; conn.maxMod = 0; save_gpm_signals(); h = Gpm_Open(&conn, cons); restore_gpm_signals(); if (h < 0) return NULL; gms = mem_alloc(sizeof(struct gpm_mouse_spec)); gms->h = h; gms->fn = fn; gms->data = data; set_handlers(h, (void (*)(void *))gpm_mouse_in, NULL, NULL, gms); return gms;}void unhandle_mouse(void *h){ struct gpm_mouse_spec *gms = h; set_handlers(gms->h, NULL, NULL, NULL, NULL); save_gpm_signals(); Gpm_Close(); restore_gpm_signals(); mem_free(gms);}#elif !defined(USING_OS2_MOUSE)void *handle_mouse(int cons, void (*fn)(void *, unsigned char *, int), void *data) { return NULL; }void unhandle_mouse(void *data) { }#endif /* #ifdef USE_GPM */#if defined(OS2)int get_system_env(void){ if (is_xterm()) return 0; return ENV_OS2VIO; /* !!! FIXME: telnet */}#elif defined(BEOS)int get_system_env(void){ unsigned char *term = getenv("TERM"); if (!term || (upcase(term[0]) == 'B' && upcase(term[1]) == 'E')) return ENV_BE; return 0;}#elif defined(WIN32)int get_system_env(void){ if (is_xterm()) return 0; return ENV_WIN32;}#elseint get_system_env(void){ return 0;}#endifvoid exec_new_links(struct terminal *term, unsigned char *xterm, unsigned char *exe, unsigned char *param){ unsigned char *str; str = mem_alloc(strlen(xterm) + 1 + strlen(exe) + 1 + strlen(param) + 1); if (*xterm) sprintf(str, "%s %s %s", xterm, exe, param); else sprintf(str, "%s %s", exe, param); exec_on_terminal(term, str, "", 2); mem_free(str);}void open_in_new_twterm(struct terminal *term, unsigned char *exe, unsigned char *param){ unsigned char *twterm; if (!(twterm = getenv("LINKS_TWTERM"))) twterm = "twterm -e"; exec_new_links(term, twterm, exe, param);}void open_in_new_xterm(struct terminal *term, unsigned char *exe, unsigned char *param){ unsigned char *xterm; if (!(xterm = getenv("LINKS_XTERM"))) xterm = "xterm -e"; exec_new_links(term, xterm, exe, param);}void open_in_new_screen(struct terminal *term, unsigned char *exe, unsigned char *param){ exec_new_links(term, "screen", exe, param);}#ifdef OS2void open_in_new_vio(struct terminal *term, unsigned char *exe, unsigned char *param){ unsigned char *x = stracpy("\""); add_to_strn(&x, exe); add_to_strn(&x, "\""); exec_new_links(term, "start \"Links\" /c /f /win", x, param); mem_free(x);}void open_in_new_fullscreen(struct terminal *term, unsigned char *exe, unsigned char *param){ unsigned char *x = stracpy("\""); add_to_strn(&x, exe); add_to_strn(&x, "\""); exec_new_links(term, "start \"Links\" /c /f /fs", x, param); mem_free(x);}#endif#ifdef WIN32void open_in_new_win32(struct terminal *term, unsigned char *exe, unsigned char *param){ exec_new_links(term, "", exe, param);}#endif#ifdef BEOSvoid open_in_new_be(struct terminal *term, unsigned char *exe, unsigned char *param){ exec_new_links(term, "Terminal", exe, param);}#endif#ifdef Gvoid open_in_new_g(struct terminal *term, unsigned char *exe, unsigned char *param){ void *info; unsigned char *target=NULL; int len; int base = 0; unsigned char *url = ""; if (!cmpbeg(param, "-target ")) { unsigned char *p; target=param+strlen("-target "); for (p=target;*p!=' '&&*p;p++); *p=0; param=p+1; } if (!cmpbeg(param, "-base-session ")) { base = atoi(param + strlen("-base-session ")); } else { url = param; } if ((info = create_session_info(base, url, target, &len))) attach_g_terminal(info, len);}#endifstruct { int env; void (*fn)(struct terminal *term, unsigned char *, unsigned char *); unsigned char *text; unsigned char *hk;} oinw[] = { {ENV_XWIN, open_in_new_xterm, TEXT_(T_XTERM), TEXT_(T_HK_XTERM)}, {ENV_TWIN, open_in_new_twterm, TEXT_(T_TWTERM), TEXT_(T_HK_TWTERM)}, {ENV_SCREEN, open_in_new_screen, TEXT_(T_SCREEN), TEXT_(T_HK_SCREEN)},#ifdef OS2 {ENV_OS2VIO, open_in_new_vio, TEXT_(T_WINDOW), TEXT_(T_HK_WINDOW)}, {ENV_OS2VIO, open_in_new_fullscreen, TEXT_(T_FULL_SCREEN), TEXT_(T_HK_FULL_SCREEN)},#endif#ifdef WIN32 {ENV_WIN32, open_in_new_win32, TEXT_(T_WINDOW), TEXT_(T_HK_WINDOW)},#endif#ifdef BEOS {ENV_BE, open_in_new_be, TEXT_(T_BEOS_TERMINAL), TEXT_(T_HK_BEOS_TERMINAL)},#endif#ifdef G {ENV_G, open_in_new_g, TEXT_(T_WINDOW), TEXT_(T_HK_WINDOW)},#endif {0, NULL, NULL, NULL}};struct open_in_new *get_open_in_new(int environment){ int i; struct open_in_new *oin = DUMMY; int noin = 0; if (anonymous) return NULL; if (environment & ENV_G) environment = ENV_G; for (i = 0; oinw[i].env; i++) if ((environment & oinw[i].env) == oinw[i].env) { if ((unsigned)noin > MAXINT / sizeof(struct open_in_new) - 2) overalloc(); oin = mem_realloc(oin, (noin + 2) * sizeof(struct open_in_new)); oin[noin].text = oinw[i].text; oin[noin].hk = oinw[i].hk; oin[noin].fn = oinw[i].fn; noin++; oin[noin].text = NULL; oin[noin].hk = NULL; oin[noin].fn = NULL; } if (oin == DUMMY) return NULL; return oin;}int can_resize_window(int environment){ if (environment & (ENV_OS2VIO | ENV_WIN32)) return 1; return 0;}int can_open_os_shell(int environment){#ifdef OS2 if (environment & ENV_XWIN) return 0;#endif return 1;}#ifndef OS2void set_highpri(void){}#elsevoid set_highpri(void){ DosSetPriority(PRTYS_PROCESS, PRTYC_FOREGROUNDSERVER, 0, 0);}#endif#ifndef HAVE_SNPRINTF#define B_SZ 65536char snprtintf_buffer[B_SZ];int my_snprintf(char *str, int n, char *f, ...){ int i; va_list l; if (!n) return -1; va_start(l, f); vsprintf(snprtintf_buffer, f, l); va_end(l); i = strlen(snprtintf_buffer); if (i >= B_SZ) { error("String size too large!"); va_end(l); fatal_tty_exit(); exit(RET_FATAL); } if (i >= n) { memcpy(str, snprtintf_buffer, n); str[n - 1] = 0; va_end(l); return -1; } strcpy(str, snprtintf_buffer); va_end(l); return i;}#endif#ifndef HAVE_MEMMOVE#define MEMMOVEtypedef long word; /* "word" used for optimal copy speed */#define wsize sizeof(word)#define wmask (wsize - 1)/* * Copy a block of memory, handling overlap. * This is the routine that actually implements * (the portable versions of) bcopy, memcpy, and memmove. */void *memmove(dst0, src0, length) void *dst0; const void *src0; size_t length;{ char *dst = dst0; const char *src = src0; size_t t; unsigned long u; if (length == 0 || dst == src) /* nothing to do */ goto done; /* * Macros: loop-t-times; and loop-t-times, t>0 */#define TLOOP(s) if (t) TLOOP1(s)#define TLOOP1(s) do { s; } while (--t) if ((unsigned long)dst < (unsigned long)src) { /* * Copy forward. */ u = (unsigned long)src; /* only need low bits */ if ((u | (unsigned long)dst) & wmask) { /* * Try to align operands. This cannot be done * unless the low bits match. */ if ((u ^ (unsigned long)dst) & wmask || length < wsize) t = length; else t = wsize - (size_t)(u & wmask); length -= t; TLOOP1(*dst++ = *src++); } /* * Copy whole words, then mop up any trailing bytes. */ t = length / wsize; TLOOP(*(word *)(void *)dst = *(const word *)(const void *)src; src += wsize; dst += wsize); t = length & wmask; TLOOP(*dst++ = *src++); } else { /* * Copy backwards. Otherwise essentially the same. * Alignment works as before, except that it takes * (t&wmask) bytes to align, not wsize-(t&wmask). */ src += length; dst += length; u = (unsigned long)src; if ((u | (unsigned long)dst) & wmask) { if ((u ^ (unsigned long)dst) & wmask || length <= wsize) t = length; else t = (size_t)(u & wmask); length -= t; TLOOP1(*--dst = *--src); } t = length / wsize; TLOOP(src -= wsize; dst -= wsize; *(word *)(void *)dst = *(const word *)(const void *)src); t = length & wmask; TLOOP(*--dst = *--src); }done:#if defined(MEMCOPY) || defined(MEMMOVE) return (dst0);#else return;#endif}#endif#ifndef HAVE_RAISEintraise(s) int s; {#ifdef HAVE_GETPID return(kill(getpid(), s));#else return 0;#endif};#endif#ifndef HAVE_STRTOUL/****yes bad fix***/unsigned long strtoul(const char *nptr, char **endptr, int base) { return (unsigned long)strtol(nptr,endptr,base); };#endif#ifndef HAVE_STRERRORchar **sys_errlist;char *strerror(int errnum) { return sys_errlist[errnum];};#endif#ifndef HAVE_GETTIMEOFDAYint gettimeofday(struct timeval *tv, struct timezone *tz){ if (tv) tv->tv_sec = time(NULL), tv->tv_usec = 0; if (tz) tz->tz_minuteswest = tz->tz_dsttime = 0; return 0;}#endif#ifndef HAVE_STRCSPNsize_t strcspn(const char *s, const char *reject){ size_t r; for (r = 0; *s; r++, s++) { const char *rj; for (rj = reject; *rj; rj++) if (*s == *rj) goto brk; } brk: return r;}#endif#ifndef HAVE_STRSTRchar *strstr(const char *haystack, const char *needle){ size_t hs = strlen(haystack); size_t ns = strlen(needle); while (hs >= ns) { if (!memcmp(haystack, needle, ns)) return haystack; haystack++, hs--; } return NULL;}#endif#ifndef HAVE_TEMPNAMchar *tempnam(const char *dir, const char *pfx){ static int counter = 0; unsigned char *d, *s, *a; int l; if (!(d = getenv("TMPDIR"))) { if (dir) d = (unsigned char *)dir; else if (!(d = getenv("TMP")) && !(d = getenv("TEMP"))) {#ifdef P_tmpdir d = P_tmpdir;#else d = "/tmp";#endif } } l = 0; s = init_str(); add_to_str(&s, &l, d); if (s[0] && s[strlen(s) - 1] != '/') add_chr_to_str(&s, &l, '/'); add_to_str(&s, &l, (unsigned char *)pfx); add_num_to_str(&s, &l, counter++); a = strdup(s); mem_free(s); return a;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -