예제 #1
0
arg_t _acct(void)
{
#ifdef CONFIG_ACCT
        inoptr inode;
        if (esuper())
                return -1;
        if (acct_fh != -1)
                oft_deref(acct_fh);
        if (fd != -1) {
                if ((inode = getinode(fd)) == NULLINODE)
                        return -1;
                if (getmode(inode) != MODE_R(F_REG)) {
                        udata.u_error = EINVAL;
                        return -1;
                }
		if (inode->c_flags & CRDONLY) {
			udata.u_error = EROFS;
			return -1;
		}
        	acct_fh = udata.u_files[fd];
        	++of_tab[acct_fh].o_refs;
        }
	return 0;
#else
        udata.u_error = EINVAL;
        return -1;
#endif        
}
예제 #2
0
arg_t _link(void)
{
	inoptr ino;
	inoptr ino2;
	inoptr parent2;
	char fname[FILENAME_LEN + 1];

	if (!(ino = n_open(name1, NULLINOPTR)))
		return (-1);

	if (getmode(ino) == MODE_R(F_DIR) && esuper())
		goto nogood;

	if (ino->c_node.i_nlink == 0xFFFF) {
		udata.u_error = EMLINK;
		goto nogood;
	}

	/* Make sure file2 doesn't exist, and get its parent */
	if ((ino2 = n_open(name2, &parent2)) != NULL) {
		i_deref(ino2);
		i_deref(parent2);
		udata.u_error = EEXIST;
		goto nogood;
	}

	if (!parent2)
		goto nogood;

	if (ino->c_dev != parent2->c_dev) {
		i_deref(parent2);
		udata.u_error = EXDEV;
		goto nogood;
	}

	filename(name2, fname);

	if (!ch_link(parent2, "", fname, ino)) {
		i_deref(parent2);
		goto nogood;
	}

	/* Update the link count. */
	++ino->c_node.i_nlink;
	wr_inode(ino);
	setftime(ino, C_TIME);

	i_deref(parent2);
	i_deref(ino);
	return 0;

      nogood:
	i_deref(ino);
	return -1;
}
예제 #3
0
static arg_t chdiroot_op(inoptr ino, inoptr * p)
{
	if (getmode(ino) != MODE_R(F_DIR)) {
		udata.u_error = ENOTDIR;
		i_deref(ino);
		return (-1);
	}
	i_deref(*p);
	*p = ino;
	return 0;
}
예제 #4
0
파일: syscall_fs.c 프로젝트: 8l/FUZIX
/* We copy the 32bit offset in and out rather than passing it
   as a 32bit OS might */
arg_t _lseek(void)
{
	inoptr ino;
	struct oft *o;
	off_t p;
	off_t n;
	
	if (uget(offset, &n, sizeof(n)))
	        return -1;

	if ((ino = getinode(file)) == NULLINODE)
		return (-1);

	if (getmode(ino) == MODE_R(F_PIPE)) {
		udata.u_error = ESPIPE;
		return (-1);
	}

	o = &of_tab[udata.u_files[file]];
	p = o->o_ptr;

	switch (flag) {
	case 0:
		p = n;
		break;
	case 1:
		p += n;
		break;
	case 2:
		p = ino->c_node.i_size + n;
		break;
	default:
                goto bad;
	}
	if (p < 0)
	        goto bad;
        o->o_ptr = p;
	uput(&p, offset, sizeof(n));
	return 0;
bad:
	udata.u_error = EINVAL;
	return (-1);

}
예제 #5
0
arg_t _open(void)
{
	int8_t uindex;
	int8_t oftindex;
	staticfast inoptr ino;
	int16_t perm;
	staticfast inoptr parent;
	char fname[FILENAME_LEN + 1];
	int trunc;
	int r;
	int w;
	int j;

	parent = NULLINODE;

	trunc = flag & O_TRUNC;
	r = (flag + 1) & 1;
	w = (flag + 1) & 2;

	if (O_ACCMODE(flag) == 3 || (flag & O_BADBITS)) {
		udata.u_error = EINVAL;
		return (-1);
	}
	if ((uindex = uf_alloc()) == -1)
		return (-1);

	if ((oftindex = oft_alloc()) == -1)
		goto nooft;

	ino = n_open(name, &parent);
	if (ino) {
		i_deref(parent);
		/* O_EXCL test */
		if ((flag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {
			udata.u_error = EEXIST;
			goto idrop;
		}
	} else {
		/* The n_open failed */
		if (udata.u_error == EFAULT || parent == NULL)
			goto cantopen;

		/* New file */
		if (!(flag & O_CREAT)) {
			udata.u_error = ENOENT;
			goto cantopen;
		}
		filename(name, fname);

		/* newfile drops parent for us */
		ino = newfile(parent, fname);
		if (!ino) {
			/* on error, newfile sets udata.u_error */
			goto cantopen;
		}

		/* new inode, successfully created */
		ino->c_node.i_mode =
		    (F_REG | (mode & MODE_MASK & ~udata.u_mask));
		setftime(ino, A_TIME | M_TIME | C_TIME);
		wr_inode(ino);
	}

	/* Book our slot in case we block opening a device */
	of_tab[oftindex].o_inode = ino;

	perm = getperm(ino);
	if ((r && !(perm & OTH_RD)) || (w && !(perm & OTH_WR))) {
		udata.u_error = EACCES;
		goto cantopen;
	}
	if (w) {
		if (getmode(ino) == MODE_R(F_DIR)) {
			udata.u_error = EISDIR;
			goto cantopen;
		}
		/* Special case - devices on a read only file system may
		   be opened read/write */
		if (!isdevice(ino) && (ino->c_flags & CRDONLY)) {
			udata.u_error = EROFS;
			goto cantopen;
		}
	}

	if (isdevice(ino)) {
		inoptr *iptr = &of_tab[oftindex].o_inode;
		/* d_open may block and thus ino may become invalid as may
		   parent (but we don't need it again). It may also be changed
		   by the call to dev_openi */

		if (dev_openi(iptr, flag) != 0)
			goto cantopen;

		/* May have changed */
		/* get the static pointer back in case it changed via dev 
		   usage or just because we blocked */
		ino = *iptr;
	}

	if (w && trunc && getmode(ino) == MODE_R(F_REG)) {
		if (f_trunc(ino))
			goto idrop;
		for (j = 0; j < OFTSIZE; ++j)
			/* Arguably should fix at read/write */
			if (of_tab[j].o_inode == ino)
				of_tab[j].o_ptr = 0;
	}

	udata.u_files[uindex] = oftindex;

	of_tab[oftindex].o_ptr = 0;
	of_tab[oftindex].o_access = flag;	/* Save the low bits only */
	if (flag & O_CLOEXEC)
		udata.u_cloexec |= (1 << oftindex);

	if (O_ACCMODE(flag) != O_RDONLY)
		ino->c_writers++;
	if (O_ACCMODE(flag) != O_WRONLY)
		ino->c_readers++;

	/* FIXME: ATIME ? */
/*
 *         Sleep process if no writer or reader.
 *	   FIXME: check for other of pair now we have proper counts
 */
	if (getmode(ino) == MODE_R(F_PIPE) && of_tab[oftindex].o_refs == 1
	    && !(flag & O_NDELAY))
		psleep(ino);

        /* From the moment of the psleep ino is invalid */

	return (uindex);
      idrop:
	i_deref(ino);
      cantopen:
	oft_deref(oftindex);	/* This will call i_deref() */
      nooft:
	udata.u_files[uindex] = NO_FILE;
	return (-1);
}