[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

MiNT 1.10 biosfs.c patch



 Hey you all!

 The 'old' Dcntl() function in biosfs.c didn't check for an already existing
entry with the same name if you wanted to install a new device. Since the new
device was linked into the chain at top position, it was at least guaranteed
to be able to be opened in susequent open calls, but the old entry remained
visible for directory listing. This version completely replaces an old entry,
if it exists, and therefore makes directory listing looks much nicer... :-)

 Sorry, but I momentarily fail to have a working (good) version of diff, so
if you like it, just take the following code and make it completely replace
the old Dcntl() function in biosfs.c... ;-(

 I'm still thinking about a good way to make it more easier to replace the old
device drivers, say, split the biosfs.c file into a real filesystem code plus
several device driver codes and still being flexible enough so that one driver
can install several devices (there wouldn't be a statically declared array of
bios devices any more, or, at least, not ONE containing EVERY possible
devices), but for the moment I think it's easier (and therefore better) to
implement them as XDD's, and that's where I hope this patch comes handy...

 And I'd also like to wait for 1.11 before implementing this... :-)

 Any new rumours about it? ;-)

ciao,
TeSche
--
Torsten Scherer (TeSche, Schiller...)
Faculty of Technology, University of Bielefeld, Germany, Europe, Earth...
| Use any of "finger itschere@129.70.131.2-15" for adresses and more.	|
| Last updated: Probably yesterday.					|

--- cut cut cut ---

static long ARGS_ON_STACK
bios_fscntl(dir, name, cmd, arg)
	fcookie *dir;
	const char *name;
	int cmd;
	long arg;
{
	struct bios_file *b;
	static int devindex = 0;

	if (curproc->euid) {
		DEBUG(("biosfs: Dcntl() by non-privileged process"));
		return ((unsigned)cmd == DEV_INSTALL) ? 0 : EACCDN;
	}

	if (IS_FD_DIR(dir))
		return EACCDN;

	/* ts: let's see if such an entry already exists */
	for (b=broot; b; b=b->next)
		if (!strcmp(b->name, name))
			break;

	switch ((unsigned) cmd) {
		case DEV_INSTALL: {
			struct dev_descr *d = (struct dev_descr *)arg;

			if (!b) {
				b = kmalloc(SIZEOF(struct bios_file));
				if (!b)
					return 0;
				b->next = broot;
				broot = b;
				strncpy(b->name, name, BNAME_MAX);
				b->name[BNAME_MAX] = 0;
			}
			b->device = d->driver;
			b->private = d->dinfo;
			b->flags = d->flags;
			b->tty = d->tty;
			set_xattr(&(b->xattr), S_IFCHR|DEFAULT_MODE, UNK_RDEV|devindex);
			devindex = (devindex+1) & 0x00ff;
			return (long)&kernelinfo;
		}
		case DEV_NEWTTY:
			if (!b) {
				b = kmalloc(SIZEOF(struct bios_file));
				if (!b)
					return ENSMEM;
				strncpy(b->name, name, BNAME_MAX);
				b->name[BNAME_MAX] = 0;
				b->tty = kmalloc(SIZEOF(struct tty));
				if (!b->tty) {
					kfree(b);
					return ENSMEM;
				}
				b->next = broot;
				broot = b;
			} else {
				/*  ts: it's probably better to use a new tty
				 * structure here, but don't touch the old
				 * pointers until we know we've got enough
				 * memory to do it!
				 */
				struct tty *ttyptr;

				if (!(ttyptr = kmalloc(SIZEOF(struct tty))))
					return ENSMEM;
				b->tty = ttyptr;
			}
			b->device = &bios_tdevice;
			b->private = arg;
			b->flags = O_TTY;
			*b->tty = default_tty;
			set_xattr(&(b->xattr), S_IFCHR|DEFAULT_MODE, BIOS_RDEV|(b->private&0x00ff));
			return 0;

		case DEV_NEWBIOS: {
			if (!b) {
				b = kmalloc(SIZEOF(struct bios_file));
				if (!b)
					return ENSMEM;
				b->next = broot;
				broot = b;
				strncpy(b->name, name, BNAME_MAX);
				b->name[BNAME_MAX] = 0;
			}
			/*  ts: it's probably better not to free an old tty
			 * structure here, cause we don't know if any process
			 * who didn't recognize this change is still using it.
			 */
			b->tty = 0;
			b->device = &bios_ndevice;
			b->private = arg;
			b->flags = 0;
			set_xattr(&(b->xattr), S_IFCHR|DEFAULT_MODE, BIOS_RDEV|(b->private&0x00ff));
			return 0;
		}
	}

	return EINVFN;
}