Esempio n. 1
0
arg_t _connect(void)
{
	uint8_t flag;
	struct socket *s = sock_get(fd, &flag);
	struct sockaddr_in sin;
	if (s == NULL)
		return -1;
	if (s->s_state == SS_CONNECTING) {
		udata.u_error = EALREADY;
		return -1;
	}
	if (s->s_state == SS_UNCONNECTED && sock_autobind(s))
		return -1;
	
	if (s->s_state == SS_BOUND) {
		if (sa_getremote(uaddr, &sin) == -1)
			return -1;
		s->s_addr[SADDR_DST].addr = sin.sin_addr.s_addr;
		s->s_addr[SADDR_DST].port = sin.sin_port;
		s->s_state = SS_CONNECTING;
		/* Protocol op to kick off */
	}

	do {
		/* FIXME: return EINPROGRESS not EINTR for SS_CONNECTING */
		if (psleep_flags(s, flag))
			return -1;
		/* Protocol state check */
	} while (s->s_state == SS_CONNECTING);
	return sock_error(s);
}
Esempio n. 2
0
File: tty.c Progetto: jfernand/FUZIX
int tty_read(uint8_t minor, uint8_t rawflag, uint8_t flag)
{
	uint16_t nread;
	unsigned char c;
	struct s_queue *q;
	struct termios *t;

	rawflag;
	flag;			// shut up compiler

	/* Minor == 0 means that it is the controlling tty of the process */
	if (!minor)
		minor = udata.u_ptab->p_tty;
	if (!udata.u_ptab->p_tty)
		udata.u_ptab->p_tty = minor;

	q = &ttyinq[minor];
	t = &ttydata[minor];
	nread = 0;
	while (nread < udata.u_count) {
		for (;;) {
		        if (deadflag[minor]) {
		                udata.u_error = ENXIO;
		                return -1;
                        }
			if (remq(q, &c)) {
				if (udata.u_sysio)
					*udata.u_base = c;
				else
					uputc(c, udata.u_base);
				break;
			}
			if (psleep_flags(q, flag))
				return -1;
		}

		++nread;

		/* return according to mode */
		if (!(t->c_lflag & ICANON)) {
			if (nread >= t->c_cc[VMIN])
				break;
		} else {
			if (nread == 1 && (c == t->c_cc[VEOF])) {
				/* ^D */
				nread = 0;
				break;
			}
			if (c == '\n')
				break;
		}

		++udata.u_base;
	}
	wakeup(&q->q_count);
	return nread;
}
Esempio n. 3
0
/* Wait to enter a state. This will eventually need interrupt locking etc */
static int sock_wait_enter(struct socket *s, uint8_t flag, uint8_t state)
{
	irqflags_t irq;
	irq = di();
	while (s->s_state != state) {
		if (psleep_flags(s, flag)) {
			irqrestore(irq);
			return -1;
		}
	}
	irqrestore(irq);
	return 0;
}
Esempio n. 4
0
File: tty.c Progetto: jfernand/FUZIX
int tty_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
{
	struct termios *t;
	int towrite;
	uint8_t c;

	rawflag;
	flag;			// shut up compiler

	/* Minor == 0 means that it is the controlling tty of the process */
	if (!minor)
		minor = udata.u_ptab->p_tty;
	if (!udata.u_ptab->p_tty)
		udata.u_ptab->p_tty = minor;

	t = &ttydata[minor];

	towrite = udata.u_count;

	while (udata.u_count-- != 0) {
		for (;;) {	/* Wait on the ^S/^Q flag */
		        if (deadflag[minor]) {
		                udata.u_error = ENXIO;
		                return -1;
                        }
			if (!stopflag[minor])
				break;
			if (psleep_flags(&stopflag[minor], flag))
				return -1;
		}

		if (!flshflag[minor]) {
			if (udata.u_sysio)
				c = *udata.u_base;
			else
				c = ugetc(udata.u_base);

			if (t->c_oflag & OPOST) {
				if (c == '\n' && (t->c_oflag & ONLCR))
					tty_putc_wait(minor, '\r');
				if (c == '\r' && (t->c_oflag & OCRNL))
					c = '\n';
			}
			tty_putc_wait(minor, c);
		}
		++udata.u_base;
	}
	return towrite;
}
Esempio n. 5
0
File: tty.c Progetto: jfernand/FUZIX
int tty_open(uint8_t minor, uint16_t flag)
{
	struct termios *t;

	/* FIXME : open/carrier logic is needed here, definitely before we
	   enable ptys */
	/* Minor == 0 means that it is the controlling tty of the process */
	/* FIXME: need to propogate this minor change back into the file handle
	   and inode somehow ??? */
	if (!minor)
		minor = udata.u_ptab->p_tty;
	if (minor < 1 || minor > NUM_DEV_TTY + 1) {
		udata.u_error = ENODEV;
		return (-1);
	}
	/* Hung up but not yet cleared of users */
	if (deadflag[minor]) {
	        udata.u_error = ENXIO;
	        return -1;
        }

	t = &ttydata[minor];

	/* If there is no controlling tty for the process, establish it */
	if (!udata.u_ptab->p_tty && !(flag & O_NOCTTY)) {
		udata.u_ptab->p_tty = minor;
		tty_pgrp[minor] = udata.u_ptab->p_pgrp;
	}
	tty_setup(minor);
	if ((t->c_cflag & CLOCAL) || (flag & O_NDELAY))
	        return 0;

        if (!tty_carrier(minor)) {
                if (psleep_flags(&t->c_cflag, flag))
                        return -1;
        }
        /* Carrier spiked ? */
        if (deadflag[minor]) {
                udata.u_error = ENXIO;
                deadflag[minor] = 0;
                return -1;
        }
        return 0;
}
Esempio n. 6
0
File: tty.c Progetto: jfernand/FUZIX
int pty_read(uint8_t minor, uint8_t rawflag, uint8_t flag)
{
	struct s_queue q = &ttyinq[minor + PTY_OFFSET + PTY_PAIR];
	char c;

	while (nread < udata.u_count) {
		if (remq(q, &c)) {
			if (udata.u_sysio)
				*udata.u_base = c;
			else
				uputc(c, udata.u_base);
			udata.u_base++;
			nread++;
			continue;
		}
		if (nread == 0 && psleep_flags(q, flag))
			return -1;
	}
	return nread;
}
Esempio n. 7
0
File: tty.c Progetto: jfernand/FUZIX
int pty_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
{
	uint16_t nwritten;
	minor += PTY_OFFSET;

	while (nwritten < udata.u_count) {
		if (udata.u_sysio)
			c = udata.u_base;
		else
			c = ugetc(udata.u_base);
		if (tty_inproc(minor, c)) {
			nwritten++;
			udata.u_count++;
			continue;
		}
		if (nwritten == 0
		    && psleep_flags(&ttyinq[minor].q_count, flag))
			return -1;
	}

	return nwritten;
}
Esempio n. 8
0
File: tty.c Progetto: aralbrec/FUZIX
int tty_open(uint8_t minor, uint16_t flag)
{
	struct tty *t;

	if (minor > NUM_DEV_TTY) {
		udata.u_error = ENODEV;
		return -1;
	}

	t = &ttydata[minor];

	/* Hung up but not yet cleared of users */
	if (t->flag & TTYF_DEAD) {
	        udata.u_error = ENXIO;
	        return -1;
        }

	if (t->users) {
	        t->users++;
	        return 0;
        }
	tty_setup(minor);
	if ((t->termios.c_cflag & CLOCAL) || (flag & O_NDELAY))
		goto out;

        /* FIXME: racy - need to handle IRQ driven carrier events safely */
        if (!tty_carrier(minor)) {
                if (psleep_flags(&t->termios.c_cflag, flag))
                        return -1;
        }
        /* Carrier spiked ? */
        if (t->flag & TTYF_DEAD) {
                udata.u_error = ENXIO;
                t->flag &= ~TTYF_DEAD;
                return -1;
        }
 out:   t->users++;
        return 0;
}
Esempio n. 9
0
arg_t net_read(struct socket *s, uint8_t flag)
{
  uint16_t n = 0;
  
  while(1) {
    if (s->s_state < SS_CONNECTED) {
      udata.u_error = EINVAL;
      return -1;
    }
    
    while(netat_ready() && n < udata.u_count) {
      uputc(netat_byte(), udata.u_base++);
      n++;
    }
    if (n)
      return n;
    s->s_iflag &= ~SI_DATA;
    netat_wake();
    /* Could do with using timeouts here to be clever for non O_NDELAY so
       we aggregate data. For now assume a fifo */
    if (psleep_flags(&s->s_iflag, flag))
      return -1;
  }
}
Esempio n. 10
0
arg_t net_read(struct socket *s, uint8_t flag)
{
	uint16_t n = 0xFFFF;
	uint16_t r;
	uint16_t i = sock2wiz_map[s - sockets];
	uint8_t st;

	i <<= 8;

	/* FIXME: IRQ protection */
	/* Wait for data - push int core code ? */
	while (1) {
		/* See if we have lost the link */
		if (s->s_state < SS_CONNECTED) {
			udata.u_error = EINVAL;
			return -1;
		}
		/* Check for an EOF (covers post close cases too) */
		if (s->s_iflag & SI_EOF)
			return 0;
		/* Keep waiting until we get the right state */
		/* Bytes available */
		n = w5100_readw(Sn_RX_RSR + i);
		if (n) {
			s->s_iflag |= SI_DATA;
			break;
		}
		st = w5100_readb(Sn_SR);
		if (st >= SOCK_CLOSING && st <= SOCK_UDP)
			return 0;
		/* Need IRQ protection to avoid sleep race */
		if (psleep_flags(&s->s_iflag, flag))
			return -1;
	}
	switch (s->s_type) {
	case SOCKTYPE_RAW:
	case SOCKTYPE_UDP:
		/* UDP comes with a header */
		w5100_dequeue(i, 4, (uint8_t *) & s->s_addr[SADDR_TMP].addr);
		if (s->s_type == SOCKTYPE_UDP)
			w5100_dequeue(i, 2,
				    (uint8_t *) & s->s_addr[SADDR_TMP].
				    port);
		w5100_dequeue(i, 2, (uint8_t *) & n);	/* Actual packet size */
		n = ntohs(n);	/* Big endian on device */
		/* Fall through */
	case SOCKTYPE_TCP:
		/* Bytes to consume */
		r = min(n, udata.u_count);
		/* Now dequeue some bytes into udata.u_base */
		w5100_dequeue_u(i, r, udata.u_base);
		/* For datagrams we always discard the entire frame */
		if (s->s_type == SOCKTYPE_UDP)
			r = n + 8;
		w5100_writew(Sn_RX_RD0 + i, w5100_readw(Sn_RX_RD0 + i) + r);
		/* FIXME: figure out if SI_DATA should be cleared */
		/* Now tell the device we ate the data */
		w5100_writeb(Sn_CR, RECV);
	}
	return r;
}
Esempio n. 11
0
arg_t _flock(void)
{
	inoptr ino;
	struct oft *o;
	staticfast uint8_t c;
	staticfast uint8_t lock;
	staticfast int self;

	lock = lockop & ~LOCK_NB;
	self = 0;

	if (lock > LOCK_UN) {
		udata.u_error = EINVAL;
		return -1;
	}

	if ((ino = getinode(file)) == NULLINODE)
		return -1;
	o = &of_tab[udata.u_files[file]];

	c = ino->c_flags & CFLOCK;

	/* Upgrades and downgrades. Check if we are in fact doing a no-op */
	if (o->o_access & O_FLOCK) {
		self = 1;
		/* Shared or exclusive to shared can't block and is easy */
		if (lock == LOCK_SH) {
			if (c == CFLEX)
				c = 1;
			goto done;
		}
		/* Exclusive to exclusive - no op */
		if (c == CFLEX && lock == LOCK_EX)
			return 0;
		/* Shared to exclusive - handle via the loop */
	}
		
		
	/* Unlock - drop the locks, mark us not a lock holder. Doesn't block */
	if (lockop == LOCK_UN) {
		o->o_access &= ~O_FLOCK;
		deflock(o);
		return 0;
	}

	do {
		/* Exclusive lock must have no holders */
		if (c == self && lock == LOCK_EX) {
			c = CFLEX;
			goto done;
		}
		if (c < CFMAX) {
			c++;
			goto done;
		}
		if (c == CFMAX) {
			udata.u_error = ENOLCK;
			return -1;
		}
		/* LOCK_NB is defined as O_NDELAY... */
		if (psleep_flags(&ino->c_flags, (lockop & LOCK_NB)))
			return -1;
		/* locks will hopefully have changed .. */
		c = ino->c_flags & CFLOCK;
	} while (1);

done:
	if (o->o_access & O_FLOCK)
		deflock(o);
	ino->c_flags &= ~CFLOCK;
	ino->c_flags |= c;
	o->o_access |= O_FLOCK;
	wakeup(&ino->c_flags);
	return 0;
}