syscalls.c

来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· C语言 代码 · 共 926 行 · 第 1/2 页

C
926
字号
 * Threaded socket accept. */intjthreadedAccept(int fd, struct sockaddr* addr, int* len, 		int timeout, int* out){	/* absolute time at which time out is reached */#if defined(SO_RCVTIMEO)	int ret;	struct timeval old_tv;	struct timeval new_tv;	int old_tv_sz = sizeof (old_tv);	getsockopt (fd, SOL_SOCKET, SO_RCVTIMEO, &old_tv, &old_tv_sz);	new_tv.tv_sec = 0;	/* Guessed according to the former behaviour of jthreadedAccept	 * Even if it is wrong	 */	if (timeout == NOTIMEOUT)		new_tv.tv_usec = 0;	else		new_tv.tv_usec = timeout*1000;	ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &new_tv, sizeof(new_tv));        if (!ret) {		ret = accept (fd, addr, len);		setsockopt (fd, SOL_SOCKET, SO_RCVTIMEO, &old_tv, sizeof (old_tv));		if( ret < 0 )		{		    switch( errno )		    {		    case EAGAIN:			errno = ETIMEDOUT;			break;		    }		}	}	SET_RETURN_OUT(ret, out, ret)	return ret;#else	int r=-1, ret;		ret = waitForTimeout(fd,timeout);	if (ret > 0) {		r = accept(fd,addr,len);		SET_RETURN_OUT(r, out, r)		return (r);	}	else {		errno = ETIMEDOUT;		r = -1;	}		SET_RETURN_OUT(r, out, r)	return (r);#endif}/* * Threaded read with timeout */intjthreadedTimedRead(int fd, void* buf, size_t len, int timeout, ssize_t *out){	ssize_t r = -1;	/* absolute time at which timeout is reached */	int ret;		ret = waitForTimeout(fd,timeout);	if (ret > 0) {		r = read(fd, buf, len);	}		SET_RETURN_OUT(r, out, r)	return (r);}/* * Threaded write with timeout */intjthreadedTimedWrite(int fd, const void* buf, size_t len, int timeout, ssize_t *out){	ssize_t r = -1;	/* absolute time at which timeout is reached */	int ret;		ret = waitForWritable(fd,timeout);	if (ret > 0) {		r = write(fd, buf, len);	}		SET_RETURN_OUT(r, out, r)	return (r);}/* * Threaded read with no time out */intjthreadedRead(int fd, void* buf, size_t len, ssize_t *out){	ssize_t r = -1;	r = read(fd, buf, len);	SET_RETURN_OUT(r, out, r);	return (r);}/* * Threaded write */intjthreadedWrite(int fd, const void* buf, size_t len, ssize_t *out){	ssize_t r = 1;	const void* ptr;	ptr = buf;	while (len > 0 && r > 0) {		r = (ssize_t)write(fd, ptr, len);		if (r >= 0) {			ptr += r;			len -= r;			r = ptr - buf;			continue;		}		if (errno == EINTR) {			/* ignore */			r = 1;			continue;		}		if (!(errno == EWOULDBLOCK || errno == EAGAIN)) {			/* real error */			break;		}		r = 1;	}	SET_RETURN_OUT(r, out, r)	return (r); }/* * Threaded recvfrom  */int jthreadedRecvfrom(int fd, void* buf, size_t len, int flags, 	struct sockaddr* from, int* fromlen, int timeout, ssize_t *out){	int r;	jlong deadline = 0; 	SET_DEADLINE(deadline, timeout)	for (;;) {		r = recvfrom(fd, buf, len, flags, from, fromlen);		if (r >= 0 || !(errno == EWOULDBLOCK || errno == EINTR 					|| errno == EAGAIN)) {			break;		}		IGNORE_EINTR(r)		BREAK_IF_LATE(deadline, timeout)	}	SET_RETURN_OUT(r, out, r)	return (r);}/* helper function for forkexec, close fd[0..n-1] */static voidclose_fds(int fd[], int n){        int i = 0;        while (i < n) {                close(fd[i++]);	}}int jthreadedForkExec(char **argv, char **arge,	int ioes[4], int *outpid, const char *dir){/* these defines are indices in ioes */#define IN_IN		0#define IN_OUT		1#define OUT_IN		2#define OUT_OUT		3#define ERR_IN		4#define ERR_OUT		5#define SYNC_IN		6#define SYNC_OUT	7	int fds[8];	int nfd;		/* number of fds in `fds' that are valid */	sigset_t nsig;	char b[1];	int pid, i, err;	/* 	 * we need execve() and fork() for this to work.  Don't bother if	 * we don't have them.	 */#if !defined(HAVE_EXECVE) && !defined(HAVE_EXECVP)	unimp("neither execve() nor execvp() provided");#endif#if !defined(HAVE_FORK)	unimp("fork() not provided");#endif	/* Create the pipes to communicate with the child */	/* Make sure fds get closed if we can't create all pipes */	for (nfd = 0; nfd < 8; nfd += 2) {		int e;		err = pipe(fds + nfd);		e = errno;		if (err == -1) {			close_fds(fds, nfd);			return (e);		}	}	/* 	 * We must avoid that the child dies because of SIGVTALRM or	 * other signals.  We disable interrupts before forking and then	 * reenable signals in the child after we cleaned up.	 */	sigfillset(&nsig);	sigprocmask(SIG_BLOCK, &nsig, 0);	pid = fork();	switch (pid) {	case 0:		/* Child */		/* set all signals back to their default state */		for (i = 0; i < NSIG; i++) {			clearSignal(i);		}		/* now reenable interrupts */		sigprocmask(SIG_UNBLOCK, &nsig, 0);		/* set stdin, stdout, and stderr up from the pipes */		dup2(fds[IN_IN], 0);		dup2(fds[OUT_OUT], 1);		dup2(fds[ERR_OUT], 2);		/* What is sync about anyhow?  Well my current guess is that		 * the parent writes a single byte to it when it's ready to		 * proceed.  So here I wait until I get it before doing		 * anything.		 */		/* note that this is a blocking read */		read(fds[SYNC_IN], b, sizeof(b));		/* now close all pipe fds */		close_fds(fds, 8);		/* change working directory */#if defined(HAVE_CHDIR)		(void)chdir(dir);#endif		/*		 * If no environment was given and we have execvp, we use it.		 * If an environment was given, we use execve.		 * This is roughly was the linux jdk seems to do.		 */		/* execute program */#if defined(HAVE_EXECVP)		if (arge == NULL)			execvp(argv[0], argv);		else#endif			execve(argv[0], argv, arge);		break;	case -1:		/* Error */		err = errno;		/* Close all pipe fds */		close_fds(fds, 8);		sigprocmask(SIG_UNBLOCK, &nsig, 0);		return (err);	default:		/* Parent */		/* close the fds we won't need */		close(fds[IN_IN]);		close(fds[OUT_OUT]);		close(fds[ERR_OUT]);		close(fds[SYNC_IN]);		/* copy and fix up the fds we do need */		ioes[0] = fds[IN_OUT];		ioes[1] = fds[OUT_IN];		ioes[2] = fds[ERR_IN];		ioes[3] = fds[SYNC_OUT];		sigprocmask(SIG_UNBLOCK, &nsig, 0);		*outpid = pid;		return (0);	}	exit(-1);	/* NEVER REACHED */	}/*  * Wait for a child process. */intjthreadedWaitpid(int wpid, int* status, int options, int *outpid){#if defined(HAVE_WAITPID)	int npid;	npid = waitpid(wpid, status, options);	if (npid > 0) {		*outpid = npid;		return (0);	}	else {		return (-1);	}#else	return (-1);#endif}intjthreadedMmap(void **memory, size_t *size, int mode, int fd, off_t *offset){#if defined(HAVE_MMAP)	size_t pages_sz;	off_t pages_offset;	int sysmode, sysflags;	int rc = 0;	pages_sz = (*size)/getpagesize();	*size = (pages_sz+1)*getpagesize();  	pages_offset = (*offset)/getpagesize();	*offset = pages_offset*getpagesize();	switch (mode) {		case KAFFE_MMAP_READ:			sysflags = MAP_SHARED;			sysmode = PROT_READ;			break;		case KAFFE_MMAP_WRITE:			sysflags = MAP_SHARED;			sysmode = PROT_WRITE | PROT_READ;			break;		case KAFFE_MMAP_PRIVATE:			sysflags = MAP_PRIVATE;			sysmode = PROT_WRITE | PROT_READ;			break;		default:			return -EINVAL;	}	*memory = mmap(*memory, *size, sysmode, sysflags, fd, *offset);	return (rc);#else	return (ENOTSUP);#endif}static intjthreadedMunmap(void *memory, size_t size){#if defined(HAVE_MMAP)	int rc = 0;		if (munmap(memory, size) < 0) {		rc = errno;	}	return (rc);#else	return (ENOTSUP);#endif}static intjthreadedMsync(void *memory, size_t size){#if defined(HAVE_MMAP)        int rc = 0;        memory = (void *)(((size_t)memory/getpagesize()) * getpagesize());        size += getpagesize();        /* TODO: Try not to freeze the entire VM. */        if (msync(memory, size, MS_SYNC | MS_INVALIDATE) < 0) {            rc = errno;        }        return rc;#else        return (ENOTSUP);#endif}int jthreadedPipeCreate(int *read_fd, int *write_fd){	int pairs[2];	assert(read_fd != NULL);	assert(write_fd != NULL);	if (pipe(pairs) < 0)		return errno;	*read_fd = pairs[0];	*write_fd = pairs[1];	return 0;}/* * The syscall interface as provided by the internal jthread system. */SystemCallInterface Kaffe_SystemCallInterface = {        jthreadedOpen,        jthreadedRead,	        jthreadedWrite,         jthreadedLSeek,        jthreadedClose,        jthreadedFStat,        jthreadedStat,        jthreadedFTruncate,        jthreadedFSync,        jthreadedMkdir,        jthreadedRmdir,        jthreadedRename,        jthreadedRemove,        jthreadedSocket,        jthreadedConnect,        jthreadedBind,        jthreadedListen,        jthreadedAccept,         jthreadedTimedRead,	        jthreadedRecvfrom,        jthreadedWrite,         jthreadedSendto,	        jthreadedSetSockOpt,	        jthreadedGetSockOpt,        jthreadedGetSockName,         jthreadedGetPeerName,         jthreadedClose,        jthreadedGetHostByName,        jthreadedGetHostByAddr,        jthreadedSelect,	        jthreadedForkExec,        jthreadedWaitpid,        jthreadedKill,        jthreadedMmap,        jthreadedMunmap,	jthreadedMsync,	jthreadedPipeCreate,	jthreadedTimedRead,	jthreadedTimedWrite};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?