Beispiel #1
0
int
_sock_srv(char *path, int fd)
{
    int sfd;
    char msg[8+256+1];

    /* change the path to something in srv */
    _sock_srvname(msg, path);

    /* remove any previous instance */
    unlink(msg);

    /* put the fd in /srv and then close it */
    sfd = creat(msg, 0666);
    if(sfd < 0) {
        close(fd);
        _syserrno();
        return -1;
    }
    snprintf(msg, sizeof msg, "%d", fd);
    if(write(sfd, msg, strlen(msg)) < 0) {
        _syserrno();
        close(sfd);
        close(fd);
        return -1;
    }
    close(sfd);
    close(fd);
    return 0;
}
Beispiel #2
0
int
tcsetattr(int fd, int optactions, const struct termios *t)
{
	int n, i;
	char buf[100];

	if(!isptty(fd)) {
		if(!isatty(fd)) {
			errno = ENOTTY;
			return -1;
		} else
			return 0;
	}
	n = sprintf(buf, "IOW %4.4x %4.4x %4.4x %4.4x ",
		t->c_iflag, t->c_oflag, t->c_cflag, t->c_lflag);

	for(i = 0; i < NCCS; i++)
		n += sprintf(buf+n, "%2.2x ", t->c_cc[i]);

	if(_SEEK(fd, -2, 0) != -2) {
		_syserrno();
		return -1;
	}

	n = _WRITE(fd, buf, n);
	if(n < 0) {
		_syserrno();
		return -1;
	}

	return 0;
}
Beispiel #3
0
int
tcsetpgrp(int fd, pid_t pgrpid)
{
	int n;
	char buf[30];

	if(!isptty(fd)) {
		if(!isatty(fd)) {
			errno = ENOTTY;
			return -1;
		} else
			return 0;
	}
	n = sprintf(buf, "IOW note %d", pgrpid);

	if(_SEEK(fd, -2, 0) != -2) {
		_syserrno();
		return -1;
	}

	n = _WRITE(fd, buf, n);
	if(n < 0) {
		_syserrno();
		return -1;
	}
}
Beispiel #4
0
int
writev(int fd, struct iovec *v, int ent)
{
	int i, n, written;
	char *t, *e, *f;
	char buf[10*1024];

	written = n = 0;
	t = buf;
	e = buf+sizeof(buf);
	for(;ent ; v++, ent--){
		n = v->iov_len;
		f = v->iov_base;
		while(n > 0){
			i = e-t;
			if(n < i){
				memmove(t, f, n);
				t += n;
				break;
			}
			memmove(t, f, i);
			n -= i;
			f += i;
			i = write(fd, buf, sizeof(buf));
			if(i < 0){
				if(written > 0){
					return written;
				}else{
					_syserrno();
					return -1;
				}
			}
			written += i;
			if(i != sizeof(buf)) {
				return written;
			}
			t = buf;
		}
	}
	i = t - buf;
	if(i > 0){
		n = write(fd, buf, i);
		if(n < 0){
			if(written == 0){
				_syserrno();
				return -1;
			}
		} else
			written += n;
	}
	return written;
}
Beispiel #5
0
int
tcgetattr(int fd, struct termios *t)
{
	int n;
	char buf[60];

	if(!isptty(fd)) {
		if(isatty(fd)) {
			/* If there is no emulation return sensible defaults */
			t->c_iflag = ISTRIP|ICRNL|IXON|IXOFF;
			t->c_oflag = OPOST|TAB3|ONLCR;
			t->c_cflag = B9600;
			t->c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
			t->c_cc[VINTR] = CINTR;
			t->c_cc[VQUIT] = CQUIT;
			t->c_cc[VERASE] = CERASE;
			t->c_cc[VKILL] = CKILL;
			t->c_cc[VEOF] = CEOF;
			t->c_cc[VEOL] = CEOL;
			t->c_cc[VSTART] = CSTART;
			t->c_cc[VSTOP] = CSTOP;
			return 0;
		} else {
			errno = ENOTTY;
			return -1;
		}
	}
	if(_SEEK(fd, -2, 0) != -2) {
		_syserrno();
		return -1;
	}

	n = _READ(fd, buf, 57);
	if(n < 0) {
		_syserrno();
		return -1;
	}

	t->c_iflag = strtoul(buf+4, 0, 16);
	t->c_oflag = strtoul(buf+9, 0, 16);
	t->c_cflag = strtoul(buf+14, 0, 16);
	t->c_lflag = strtoul(buf+19, 0, 16);

	for(n = 0; n < NCCS; n++)
		t->c_cc[n] = strtoul(buf+24+(n*3), 0, 16);

	return 0;
}
Beispiel #6
0
int
chown(const char *path, uid_t owner, gid_t group)
{
	int num;
	Dir d;

	_nulldir(&d);

	/* find owner, group */
	d.uid = nil;
	num = owner;
	if(!_getpw(&num, &d.uid, 0)) {
		errno = EINVAL;
		return -1;
	}

	d.gid = nil;
	num = group;
	if(!_getpw(&num, &d.gid, 0)) {
		errno = EINVAL;
		return -1;
	}

	if(_dirwstat(path, &d) < 0){
		_syserrno();
		return -1;
	}
	return 0;
}
Beispiel #7
0
int
close(int d)
{
	int n;
	Fdinfo *f;

	n = -1;
	f = &_fdinfo[d];
	if(d<0 || d>=OPEN_MAX || !(f->flags&FD_ISOPEN))
		errno = EBADF;
	else{
		if(f->flags&(FD_BUFFERED|FD_BUFFEREDX)) {
			if(f->flags&FD_BUFFERED)
				_closebuf(d);
			f->flags &= ~FD_BUFFERED;
		}
		n = _CLOSE(d);
		if(n < 0)
			_syserrno();
		_fdinfo[d].flags = 0;
		_fdinfo[d].oflags = 0;
		if(_fdinfo[d].name){
			free(_fdinfo[d].name);
			_fdinfo[d].name = 0;
		}
	}
	return n;
}
Beispiel #8
0
int
pipe(int fildes[2])
{
	Fdinfo *fi;
	int i;

	if(!fildes){
		errno = EFAULT;
		return -1;
	}
	if(_PIPE(fildes) < 0)
		_syserrno();
	else
	if(fildes[0] < 0 || fildes[0]>=OPEN_MAX ||
	   fildes[1] < 0 || fildes[1]>=OPEN_MAX) {
		errno = EMFILE;
		return -1;
	}
	for(i = 0; i <=1; i++) {
		fi = &_fdinfo[fildes[i]];
		fi->flags = FD_ISOPEN;
		fi->oflags = O_RDWR;
		fi->uid = 0;	/* none */
		fi->gid = 0;
	}
	return 0;
}
Beispiel #9
0
int
socket(int domain, int stype, int protocol)
{
	Rock *r;
	int cfd;
	int pfd[2];
	char *net;

	switch(domain){
	case PF_INET:
		/* get a free network directory */
		switch(stype){
		case SOCK_DGRAM:
			net = "udp";
			cfd = open("/net/udp/clone", O_RDWR);
			break;
		case SOCK_STREAM:
			net = "tcp";
			cfd = open("/net/tcp/clone", O_RDWR);
			break;
		default:
			errno = EPROTONOSUPPORT;
			return -1;
		}
		if(cfd < 0){
			_syserrno();
			return -1;
		}
		return _sock_data(cfd, net, domain, stype, protocol, 0);
	case PF_UNIX:
		if(pipe(pfd) < 0){
			_syserrno();
			return -1;
		}
		r = _sock_newrock(pfd[0]);
		r->domain = domain;
		r->stype = stype;
		r->protocol = protocol;
		r->other = pfd[1];
		return pfd[0];
	default:
		errno = EPROTONOSUPPORT;
		return -1;
	}
}
Beispiel #10
0
int
chdir(const char *f)
{
	int n;

	n = _CHDIR(f);
	if(n < 0)
		_syserrno();
	return n;
}
Beispiel #11
0
pid_t
setsid(void)
{
	if(_RFORK(RFNAMEG|RFNOTEG) < 0){
		_syserrno();
		return -1;
	}
	_sessleader = 1;
	return getpgrp();
}
Beispiel #12
0
int
fstat(int fd, struct stat *buf)
{
	Dir *d;

	if((d = _dirfstat(fd)) == nil){
		_syserrno();
		return -1;
	}
	_dirtostat(buf, d, &_fdinfo[fd]);
	free(d);
	return 0;
}
Beispiel #13
0
Datei: fork.c Projekt: 8l/harvey
pid_t
fork(void)
{
	int n;

	n = _RFORK(RFENVG|RFFDG|RFPROC);
	if(n < 0)
		_syserrno();
	if(n == 0) {
		_detachbuf();
		_sessleader = 0;
	}
	return n;
}
Beispiel #14
0
pid_t
tcgetpgrp(int fd)
{
	int n;
	pid_t pgrp;
	char buf[100];

	if(!isptty(fd)) {
		errno = ENOTTY;
		return -1;
	}
	if(_SEEK(fd, -2, 0) != -2) {
		_syserrno();
		return -1;
	}
	n = _READ(fd, buf, sizeof(buf));
	if(n < 0) {
		_syserrno();
		return -1;
	}
	pgrp = atoi(buf+24+(NCCS*3));
	return pgrp;
}
Beispiel #15
0
pid_t
getpid(void)
{
	int n, f;
	char pidbuf[15];

	f = __sys_open("#c/pid", 0);
	n = __sys_read(f, pidbuf, sizeof pidbuf);
	if(n < 0)
		_syserrno();
	else
		n = atoi(pidbuf);
	__sys_close(f);
	return n;
}
Beispiel #16
0
ssize_t
write(int d, const void *buf, size_t nbytes)
{
	int n;

	if(d<0 || d>=OPEN_MAX || !(_fdinfo[d].flags&FD_ISOPEN)){
		errno = EBADF;
		return -1;
	}
	if(_fdinfo[d].oflags&O_APPEND)
		_SEEK(d, 0, 2);
	n = _WRITE(d, buf, nbytes);
	if(n < 0)
		_syserrno();
	return n;
}
Beispiel #17
0
/*
 * BUG: errno mapping
 */
off_t
lseek(int d, off_t offset, int whence)
{
	long long n;
	int flags;

	flags = _fdinfo[d].flags;
	if(flags&(FD_BUFFERED|FD_BUFFEREDX|FD_ISTTY)) {
		errno = ESPIPE;
		return -1;
	}
	n = _SEEK(d, offset, whence);
	if(n < 0)
		_syserrno();
	return n;
}
Beispiel #18
0
pid_t
getpgrp(void)
{
	int n, f, pid;
	char pgrpbuf[15], fname[30];

	pid = getpid();
	sprintf(fname, "/proc/%d/noteid", pid);
	f = open(fname, 0);
	n = read(f, pgrpbuf, sizeof pgrpbuf);
	if(n < 0)
		_syserrno();
	else
		n = atoi(pgrpbuf);
	close(f);
	return n;
}
Beispiel #19
0
int
utime(const char *path, const struct utimbuf *times)
{
	int n;
	Dir nd;
	time_t curt;

	_nulldir(&nd);
	if(times == 0) {
		curt = time(0);
		nd.atime = curt;
		nd.mtime = curt;
	} else {
		nd.atime = times->actime;
		nd.mtime = times->modtime;
	}
	n = _dirwstat(path, &nd);
	if(n < 0)
		_syserrno();
	return n;
}
Beispiel #20
0
ssize_t
read(int d, void *buf, size_t nbytes)
{
	int n, noblock, isbuf;
	Fdinfo *f;

	if(d<0 || d>=OPEN_MAX || !(_fdinfo[d].flags&FD_ISOPEN)){
		errno = EBADF;
		return -1;
	}
	if(nbytes <= 0)
		return 0;
	if(buf == 0){
		errno = EFAULT;
		return -1;
	}
	f = &_fdinfo[d];
	noblock = f->oflags&O_NONBLOCK;
	isbuf = f->flags&(FD_BUFFERED|FD_BUFFEREDX);
	if(noblock || isbuf){
		if(f->flags&FD_BUFFEREDX) {
			errno = EIO;
			return -1;
		}
		if(!isbuf) {
			if(_startbuf(d) != 0) {
				errno = EIO;
				return -1;
			}
		}
		n = _readbuf(d, buf, nbytes, noblock);
	}else{
		n = _READ(d,  buf, nbytes);
		if(n < 0)
			_syserrno();
	}
	return n;
}
Beispiel #21
0
int
__close(int d)
{
	int n;
	Fdinfo *f;

	n = -1;
	f = &_fdinfo[d];
	if(d<0 || d>=OPEN_MAX || !(f->flags&FD_ISOPEN))
		errno = EBADF;
	else{
		n = __sys_close(d);
		if(n < 0)
			_syserrno();
		_fdinfo[d].flags = 0;
		_fdinfo[d].oflags = 0;
		if(_fdinfo[d].name){
			free(_fdinfo[d].name);
			_fdinfo[d].name = 0;
		}
	}
	return n;
}
Beispiel #22
0
static int
seterrno(void)
{
	_syserrno();
	return -1;
}
Beispiel #23
0
/*
 *  for inet addresses only
 */
struct hostent*
gethostbyname(const char *name)
{
	int i, t, fd, m;
	char *p, *bp;
	int nn, na;
	unsigned long x;
	static struct hostent h;
	static char buf[1024];
	static char *nptr[Nname+1];
	static char *aptr[Nname+1];
	static char addr[Nname][4];

	h.h_name = 0;
	t = _sock_ipattr(name);

	/* connect to server */
	fd = open("/net/cs", O_RDWR);
	if(fd < 0){
		_syserrno();
		h_errno = NO_RECOVERY;
		return 0;
	}

	/* construct the query, always expect an ip# back */
	switch(t){
	case Tsys:
		snprintf(buf, sizeof buf, "!sys=%s ip=*", name);
		break;
	case Tdom:
		snprintf(buf, sizeof buf, "!dom=%s ip=*", name);
		break;
	case Tip:
		snprintf(buf, sizeof buf, "!ip=%s", name);
		break;
	}

	/* query the server */
	if(write(fd, buf, strlen(buf)) < 0){
		_syserrno();
		h_errno = TRY_AGAIN;
		return 0;
	}
	lseek(fd, 0, 0);
	for(i = 0; i < sizeof(buf)-1; i += m){
		m = read(fd, buf+i, sizeof(buf) - 1 - i);
		if(m <= 0)
			break;
		buf[i+m++] = ' ';
	}
	close(fd);
	buf[i] = 0;

	/* parse the reply */
	nn = na = 0;
	for(bp = buf;;){
		p = strchr(bp, '=');
		if(p == 0)
			break;
		*p++ = 0;
		if(strcmp(bp, "dom") == 0){
			if(h.h_name == 0)
				h.h_name = p;
			if(nn < Nname)
				nptr[nn++] = p;
		} else if(strcmp(bp, "sys") == 0){
			if(nn < Nname)
				nptr[nn++] = p;
		} else if(strcmp(bp, "ip") == 0){
			x = inet_addr(p);
			x = ntohl(x);
			if(na < Nname){
				addr[na][0] = x>>24;
				addr[na][1] = x>>16;
				addr[na][2] = x>>8;
				addr[na][3] = x;
				aptr[na] = addr[na];
				na++;
			}
		}
Beispiel #24
0
int
rename(const char *from, const char *to)
{
	int n;
	char *f, *t;
	Dir *d, nd;

	if(access(to, 0) >= 0){
		if(_REMOVE(to) < 0){
			_syserrno();
			return -1;
		}
	}
	if((d = _dirstat(to)) != nil){
		free(d);
		errno = EEXIST;
		return -1;
	}
	if((d = _dirstat(from)) == nil){
		_syserrno();
		return -1;
	}
	f = strrchr(from, '/');
	t = strrchr(to, '/');
	f = f? f+1 : (char *)from;
	t = t? t+1 : (char *)to;
	n = 0;
	if(f-from==t-to && strncmp(from, to, f-from)==0){
		/* from and to are in same directory (we miss some cases) */
		_nulldir(&nd);
		nd.name = t;
		if(_dirwstat(from, &nd) < 0){
			_syserrno();
			n = -1;
		}
	}else{
		/* different directories: have to copy */
		int ffd, tfd;
		char buf[8192];

		tfd = -1;
		if((ffd = _OPEN(from, 0)) < 0 ||
		   (tfd = _CREATE(to, 1, d->mode)) < 0){
			_CLOSE(ffd);
			_syserrno();
			n = -1;
		}
		while(n>=0 && (n = _READ(ffd, buf, 8192)) > 0)
			if(_WRITE(tfd, buf, n) != n){
				_syserrno();
				n = -1;
			}
		_CLOSE(ffd);
		_CLOSE(tfd);
		if(n>0)
			n = 0;
		if(n == 0) {
			if(_REMOVE(from) < 0){
				_syserrno();
				return -1;
			}
		}
	}
	free(d);
	return n;
}
Beispiel #25
0
int
execve(const char *name, const char *argv[], const char *envp[])
{
	int n, f, i;
	char **e, *ss, *se;
	Fdinfo *fi;
	unsigned long flags;
	char nam[256+5];
	char buf[1000];

	_RFORK(RFCENVG);
	/*
	 * To pass _fdinfo[] across exec, put lines like
	 *   fd flags oflags
	 * in $_fdinfo (for open fd's)
	 */

	f = _CREATE("#e/_fdinfo", OWRITE, 0666);
	ss = buf;
	for(n = 0; n<OPEN_MAX; n++){
		fi = &_fdinfo[n];
		flags = fi->flags;
		if(flags&FD_CLOEXEC){
			_CLOSE(n);
			fi->flags = 0;
			fi->oflags = 0;
		}else if(flags&FD_ISOPEN){
			ss = _ultoa(ss, n);
			*ss++ = ' ';
			ss = _ultoa(ss, flags);
			*ss++ = ' ';
			ss = _ultoa(ss, fi->oflags);
			*ss++ = '\n';
			if(ss-buf < sizeof(buf)-50){
				_WRITE(f, buf, ss-buf);
				ss = buf;
			}
		}
	}
	if(ss > buf)
		_WRITE(f, buf, ss-buf);
	_CLOSE(f);
	/*
	 * To pass _sighdlr[] across exec, set $_sighdlr
	 * to list of blank separated fd's that have
	 * SIG_IGN (the rest will be SIG_DFL).
	 * We write the variable, even if no signals
	 * are ignored, in case the current value of the
	 * variable ignored some.
	 */
	f = _CREATE("#e/_sighdlr", OWRITE, 0666);
	if(f >= 0){
		ss = buf;
		for(i = 0; i <=MAXSIG && ss < &buf[sizeof(buf)]-5; i++) {
			if(_sighdlr[i] == SIG_IGN) {
				ss = _ultoa(ss, i);
				*ss++ = ' ';
			}
		}
		_WRITE(f, buf, ss-buf);
		_CLOSE(f);
	}
	if(envp){
		strcpy(nam, "#e/");
		for(e = (char **)envp; (ss = *e); e++) {
			se = strchr(ss, '=');
			if(!se || ss==se)
				continue;	/* what is name? value? */
			n = se-ss;
			if(n >= sizeof(nam)-3)
				n = sizeof(nam)-3-1;
			memcpy(nam+3, ss, n);
			nam[3+n] = 0;
			f = _CREATE(nam, OWRITE, 0666);
			if(f < 0)
				continue;
			se++; /* past = */
			n = strlen(se);
			/* temporarily decode nulls (see _envsetup()) */
			for(i=0; i < n; i++)
				if(se[i] == 1)
					se[i] = 0;
			_WRITE(f, se, n);
			/* put nulls back */
			for(i=0; i < n; i++)
				if(se[i] == 0)
					se[i] = 1;
			_CLOSE(f);
		}
	}
	n = _EXEC(name, argv);
	_syserrno();
	return n;
}
Beispiel #26
0
/*
 *  for inet addresses only
 */
struct servent*
getservbyname(const char *name, const char *proto)
{
	int i, fd, m, num;
	const char *p;
	char *bp;
	int nn, na;
	static struct servent s;
	static char buf[1024];
	static char *nptr[Nname+1];

	num = 1;
	for(p = name; *p; p++)
		if(!isdigit(*p))
			num = 0;

	s.s_name = 0;

	/* connect to server */
	fd = open("/net/cs", O_RDWR);
	if(fd < 0){
		_syserrno();
		return 0;
	}

	/* construct the query, always expect an ip# back */
	if(num)
		snprintf(buf, sizeof buf, "!port=%s %s=*", name, proto);
	else
		snprintf(buf, sizeof buf, "!%s=%s port=*", proto, name);

	/* query the server */
	if(write(fd, buf, strlen(buf)) < 0){
		_syserrno();
		return 0;
	}
	lseek(fd, 0, 0);
	for(i = 0; i < sizeof(buf)-1; i += m){
		m = read(fd, buf+i, sizeof(buf) - 1 - i);
		if(m <= 0)
			break;
		buf[i+m++] = ' ';
	}
	close(fd);
	buf[i] = 0;

	/* parse the reply */
	nn = na = 0;
	for(bp = buf;;){
		p = strchr(bp, '=');
		if(p == 0)
			break;
		/* *p++ = 0; not sure */
		if(strcmp(bp, proto) == 0){
			if(nn < Nname)
				nptr[nn++] = (char *)p;
		} else if(strcmp(bp, "port") == 0){
			s.s_port = htons(atoi(p));
		}
		while(*p && *p != ' ')
			p++;
		/* if(*p)
			*p++ = 0; realy I can't understand this */
		bp = (char *)p;
	}
	if(nn+na == 0)
		return 0;

	nptr[nn] = 0;
	s.s_aliases = nptr;
	if(s.s_name == 0)
		s.s_name = nptr[0];

	return &s;
}
Beispiel #27
0
int
listen(int fd, int i)
{
	Rock *r;
	int n, cfd;
	char msg[128];
	struct sockaddr_in *lip;
	struct sockaddr_un *lunix;

	r = _sock_findrock(fd, 0);
	if(r == 0){
		errno = ENOTSOCK;
		return -1;
	}

	switch(r->domain){
	case PF_INET:
		cfd = open(r->ctl, O_RDWR);
		if(cfd < 0){
			errno = EBADF;
			return -1;
		}
		lip = (struct sockaddr_in*)&r->addr;
		if(1 || lip->sin_port >= 0) {	/* sin_port is unsigned */
			if(write(cfd, "bind 0", 6) < 0) {
				errno = EGREG;
				close(cfd);
				return -1;
			}
			snprintf(msg, sizeof msg, "announce %d",
				ntohs(lip->sin_port));
		}
		else
			strcpy(msg, "announce *");
		n = write(cfd, msg, strlen(msg));
		if(n < 0){
			errno = EOPNOTSUPP;	/* Improve error reporting!!! */
			close(cfd);
			return -1;
		}
		close(cfd);

		return listenproc(r, fd);
	case PF_UNIX:
		if(r->other < 0){
			errno = EGREG;
			return -1;
		}
		lunix = (struct sockaddr_un*)&r->addr;
		if(_sock_srv(lunix->sun_path, r->other) < 0){
			_syserrno();
			r->other = -1;
			return -1;
		}
		r->other = -1;
		return 0;
	default:
		errno = EAFNOSUPPORT;
		return -1;
	}
}
Beispiel #28
0
int
fcntl(int fd, int cmd, ...)
{
	int arg, i, ans, err;
	Fdinfo *fi, *fans;
	va_list va;
	unsigned long oflags;

	err = 0;
	ans = 0;
	va_start(va, cmd);
	arg = va_arg(va, int);
	va_end(va);
	fi = &_fdinfo[fd];
	if(fd<0 || fd>=OPEN_MAX || !(fi->flags&FD_ISOPEN))
		err = EBADF;
	else switch(cmd){
		case F_DUPFD:
			if(fi->flags&(FD_BUFFERED|FD_BUFFEREDX)){
				err = EGREG;	/* dup of buffered fd not implemented */
				break;
			}
			oflags = fi->oflags;
			for(i = (arg>0)? arg : 0; i<OPEN_MAX; i++)
				if(!(_fdinfo[i].flags&FD_ISOPEN))
					break;
			if(i == OPEN_MAX)
				err = EMFILE;
			else {
				ans = _DUP(fd, i);
				if(ans != i){
					if(ans < 0){
						_syserrno();
						err = errno;
					}else
						err = EBADF;
				}else{
					fans = &_fdinfo[ans];
					fans->flags = fi->flags&~FD_CLOEXEC;
					fans->oflags = oflags;
					fans->uid = fi->uid;
					fans->gid = fi->gid;
				}
			}
			break;
		case F_GETFD:
			ans = fi->flags&FD_CLOEXEC;
			break;
		case F_SETFD:
			fi->flags = (fi->flags&~FD_CLOEXEC)|(arg&FD_CLOEXEC);
			break;
		case F_GETFL:
			ans = fi->oflags&OFL;
			break;
		case F_SETFL:
			fi->oflags = (fi->oflags&~OFL)|(arg&OFL);
			break;
		case F_GETLK:
		case F_SETLK:
		case F_SETLKW:
			err = EINVAL;
			break;
		}
	if(err){
		errno = err;
		ans = -1;
	}
	return ans;
}
Beispiel #29
0
int
accept(int fd, void *a, int *alen)
{
	int n, nfd, cfd;
	Rock *r, *nr;
	struct sockaddr_in *ip;
	char name[Ctlsize];
	char file[8+Ctlsize+1];
	char *net;

	r = _sock_findrock(fd, 0);
	if(r == 0){
		errno = ENOTSOCK;
		return -1;
	}

	switch(r->domain){
	case PF_INET:
		switch(r->stype){
		case SOCK_DGRAM:
			net = "udp";
			break;
		case SOCK_STREAM:
			net = "tcp";
			break;
		default:
			net = "gok";
			break;
		}

		/* get control file name from listener process */
		n = read(fd, name, sizeof(name)-1);
		if(n <= 0){
			_syserrno();
			return -1;
		}
		name[n] = 0;
		cfd = open(name, O_RDWR);
		if(cfd < 0){
			_syserrno();
			return -1;
		}

		nfd = _sock_data(cfd, net, r->domain, r->stype, r->protocol, &nr);
		if(nfd < 0){
			_syserrno();
			return -1;
		}

		if(write(fd, "OK", 2) < 0){
			close(nfd);
			_syserrno();
			return -1;
		}

		/* get remote address */
		ip = (struct sockaddr_in*)&nr->raddr;
		_sock_ingetaddr(nr, ip, &n, "remote");
		if(a){
			memmove(a, ip, sizeof(struct sockaddr_in));
			*alen = sizeof(struct sockaddr_in);
		}

		return nfd;
	case PF_UNIX:
		if(r->other >= 0){
			errno = EGREG;
			return -1;
		}

		for(;;){
			/* read path to new connection */
			n = read(fd, name, sizeof(name) - 1);
			if(n < 0)
				return -1;
			if(n == 0)
				continue;
			name[n] = 0;

			/* open new connection */
			_sock_srvname(file, name);
			nfd = open(file, O_RDWR);
			if(nfd < 0)
				continue;

			/* confirm opening on new connection */
			if(write(nfd, name, strlen(name)) > 0)
				break;

			close(nfd);
		}

		nr = _sock_newrock(nfd);
		if(nr == 0){
			close(nfd);
			return -1;
		}
		nr->domain = r->domain;
		nr->stype = r->stype;
		nr->protocol = r->protocol;

		return nfd;
	default:
		errno = EOPNOTSUPP;
		return -1;
	}
}
Beispiel #30
0
struct protoent *getprotobyname(const char *name) {
	int fd, i, m;
	char *p, *bp;
	int nn, na;
	static char buf[1024];
	static char *nptr[Nname+1];

	/* connect to server */
	fd = open("/net/cs", O_RDWR);
	if(fd < 0){
		_syserrno();
		h_errno = NO_RECOVERY;
		return 0;
	}

	/* construct the query, always expect a protocol# back */
	snprintf(buf, sizeof buf, "!protocol=%s ipv4proto=*", name);

	/* query the server */
	if(write(fd, buf, strlen(buf)) < 0){
		_syserrno();
		h_errno = TRY_AGAIN;
		return 0;
	}
	lseek(fd, 0, 0);
	for(i = 0; i < sizeof(buf)-1; i += m){
		m = read(fd, buf+i, sizeof(buf) - 1 - i);
		if(m <= 0)
			break;
		buf[i+m++] = ' ';
	}
	close(fd);
	buf[i] = 0;

	/* parse the reply */
	nn = na = 0;
	for(bp = buf;;){
		p = strchr(bp, '=');
		if(p == 0)
			break;
		*p++ = 0;
		if(strcmp(bp, "protocol") == 0){
			if(!nn)
				r.p_name = p;
			if(nn < Nname)
				nptr[nn++] = p;
		} else if(strcmp(bp, "ipv4proto") == 0){
			r.p_proto = atoi(p);
			na++;
		}
		while(*p && *p != ' ')
			p++;
		if(*p)
			*p++ = 0;
		bp = p;
	}
	nptr[nn] = 0;
	r.p_aliases = nptr;
	if (nn+na == 0)
		return 0;

	return &r;
}