os_dep.c

来自「this is the file used to browse web」· C语言 代码 · 共 1,957 行 · 第 1/3 页

C
1,957
字号
	if (mouse_mutex_init) _fmutex_release(&mouse_mutex);#endif}#endif /* if HAVE_MOUOPEN */#elif defined(HAVE_CLONE)/* This is maybe buggy... */#include <sched.h>struct thread_stack {	struct thread_stack *next;	struct thread_stack *prev;	int pid;	void *stack;	void (*fn)(void *, int);	int h;	int l;	unsigned char data[1];};void bglt(struct thread_stack *ts){	ts->fn(ts->data, ts->h);	write(ts->h, "x", 1);	close(ts->h);}struct list_head thread_stacks = { &thread_stacks, &thread_stacks };int start_thread(void (*fn)(void *, int), void *ptr, int l){	struct thread_stack *ts;	int p[2];	int f;	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);*/	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];}#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 done_draw() {}#endifint get_output_handle() { return 1; }#if defined(OS2)int get_ctl_handle() { return get_input_handle(); }#elseint get_ctl_handle() { return 0; }#endif#if defined(BEOS)#elif defined(HAVE_BEGINTHREAD) && defined(HAVE_READ_KBD)int get_input_handle(){	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(){	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;	/* cfmakeraw is broken on AIX */#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;};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(){	if (is_xterm()) return 0;	return ENV_OS2VIO;		/* !!! FIXME: telnet */}#elif defined(BEOS)int get_system_env(){	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(){	if (is_xterm()) return 0;	return ENV_WIN32;}#elseint get_system_env(){	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);}#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	{ 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;	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(){}#elsevoid set_highpri(){	DosSetPriority(PRTYS_PROCESS, PRTYC_FOREGROUNDSERVER, 0, 0);}#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 + =
减小字号Ctrl + -
显示快捷键?