1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00
elinks/src/osdep/beos/beos.c

254 lines
4.1 KiB
C
Raw Normal View History

/* BeOS system-specific routines. */
/* Note that this file is currently unmaintained and basically dead. Noone
* cares about BeOS support, apparently. This file may yet survive for some
* time, but it will probably be removed if noone will adopt it. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "osdep/system.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <be/kernel/OS.h>
#include "elinks.h"
#include "osdep/beos/beos.h"
#include "terminal/terminal.h"
#include "util/lists.h"
/* Misc trivial stuff */
int
is_xterm(void)
{
return 0;
}
int
get_system_env(void)
{
int env = get_common_env();
unsigned char *term = getenv("TERM");
if (!term || (c_toupper(term[0]) == 'B' && c_toupper(term[1]) == 'E'))
env |= ENV_BE;
return env;
}
/* Threads */
int thr_sem_init = 0;
sem_id thr_sem;
struct active_thread {
LIST_HEAD(struct active_thread);
thread_id tid;
void (*fn)(void *);
void *data;
};
2007-07-26 15:39:08 -04:00
INIT_LIST_OF(struct active_thread, active_threads);
int32
started_thr(void *data)
{
struct active_thread *thrd = data;
thrd->fn(thrd->data);
if (acquire_sem(thr_sem) < B_NO_ERROR) return 0;
del_from_list(thrd);
free(thrd);
release_sem(thr_sem);
return 0;
}
int
start_thr(void (*fn)(void *), void *data, unsigned char *name)
{
struct active_thread *thrd;
int tid;
if (!thr_sem_init) {
thr_sem = create_sem(0, "thread_sem");
if (thr_sem < B_NO_ERROR) return -1;
thr_sem_init = 1;
} else if (acquire_sem(thr_sem) < B_NO_ERROR) return -1;
thrd = malloc(sizeof(*thrd));
if (!thrd) goto rel;
thrd->fn = fn;
thrd->data = data;
thrd->tid = spawn_thread(started_thr, name, B_NORMAL_PRIORITY, thrd);
tid = thrd->tid;
if (tid < B_NO_ERROR) {
free(thrd);
rel:
release_sem(thr_sem);
return -1;
}
resume_thread(thrd->tid);
add_to_list(active_threads, thrd);
release_sem(thr_sem);
return tid;
}
void
terminate_osdep(void)
{
2007-07-26 15:39:08 -04:00
LIST_OF(struct active_thread) *p;
struct active_thread *thrd;
if (acquire_sem(thr_sem) < B_NO_ERROR) return;
foreach (thrd, active_threads) kill_thread(thrd->tid);
2007-07-26 15:39:08 -04:00
/* Cannot use free_list(active_threads) because it would call
* mem_free(p) and we need free(p). */
while ((p = active_threads.next) != &active_threads) {
del_from_list(p);
free(p);
}
release_sem(thr_sem);
}
int
start_thread(void (*fn)(void *, int), void *ptr, int l)
{
int p[2];
struct tdata *t;
if (c_pipe(p) < 0) return -1;
t = malloc(sizeof(*t) + l);
if (!t) return -1;
t->fn = fn;
t->h = p[1];
memcpy(t->data, ptr, l);
if (start_thr((void (*)(void *)) bgt, t, "elinks_thread") < 0) {
close(p[0]);
close(p[1]);
mem_free(t);
return -1;
}
return p[0];
}
int ihpipe[2];
int inth;
void
input_handle_th(void *p)
{
char c;
int b = 0;
setsockopt(ihpipe[1], SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
while (1) if (read(0, &c, 1) == 1) be_write(ihpipe[1], &c, 1);
}
int
get_input_handle(void)
{
static int h = -1;
if (h >= 0) return h;
if (be_pipe(ihpipe) < 0) return -1;
if ((inth = start_thr(input_handle_th, NULL, "input_thread")) < 0) {
closesocket(ihpipe[0]);
closesocket(ihpipe[1]);
return -1;
}
return h = ihpipe[0];
}
void
block_stdin(void)
{
suspend_thread(inth);
}
void
unblock_stdin(void)
{
resume_thread(inth);
}
#if 0
int ohpipe[2];
#define O_BUF 16384
void
output_handle_th(void *p)
{
char *c = malloc(O_BUF);
int r, b = 0;
if (!c) return;
setsockopt(ohpipe[1], SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
while ((r = be_read(ohpipe[0], c, O_BUF)) > 0) write(1, c, r);
free(c);
}
int
get_output_handle(void)
{
static int h = -1;
if (h >= 0) return h;
if (be_pipe(ohpipe) < 0) return -1;
if (start_thr(output_handle_th, NULL, "output_thread") < 0) {
closesocket(ohpipe[0]);
closesocket(ohpipe[1]);
return -1;
}
return h = ohpipe[1];
}
#endif
#if defined(HAVE_SETPGID)
int
exe(unsigned char *path)
{
pid_t pid = fork();
if (!pid) {
setpgid(0, 0);
system(path);
_exit(0);
}
if (pid > 0) {
int s;
waitpid(pid, &s, 0);
} else
return system(path);
return 0;
}
#endif