Example #1
0
int dos_rename(const char *oldpath, const char *newpath)
{
	/* This function isn't fully atomic like on Unix,
	   but it's as close as I know how to do under DOS.  */

	struct trap_state ts;
	oskit_addr_t dos_buf_phys = (oskit_addr_t)kvtophys(dos_buf);
	int err;

	init_ts(&ts);

	/* Put the oldpath in the first half of dos_buf,
	   and the newpath in the second half.  */
	if ((strlen(oldpath)+1 > DOS_BUF_SIZE/2)
	    || (strlen(newpath)+1 > DOS_BUF_SIZE/2))
		{ errno = E2BIG; return -1; }
	strcpy(dos_buf, oldpath);
	strcpy(dos_buf+DOS_BUF_SIZE/2, newpath);

	/* Try once to rename the file.  */
	ts.trapno = 0x21;
	ts.eax = 0x5600;
	ts.v86_ds = dos_buf_phys >> 4;
	ts.edx = dos_buf_phys & 15;
	ts.v86_es = dos_buf_phys >> 4;
	ts.edi = (dos_buf_phys & 15) + DOS_BUF_SIZE/2;
	base_real_int(&ts);

	/* If that failed, delete newpath and then retry the rename.
	   We _hope_ the failure was because newpath already existed;
	   the DOS error codes I'm getting back seem to be bogus.  */
	if ((err = dos_check_err(&ts)) != 0)
	{
		ts.trapno = 0x21;
		ts.eax = 0x4100;
		ts.v86_ds = dos_buf_phys >> 4;
		ts.edx = (dos_buf_phys & 15) + DOS_BUF_SIZE/2;
		base_real_int(&ts);
		if ((err = dos_check_err(&ts)) != 0)
			return err;

		ts.trapno = 0x21;
		ts.eax = 0x5600;
		ts.v86_ds = dos_buf_phys >> 4;
		ts.edx = dos_buf_phys & 15;
		ts.v86_es = dos_buf_phys >> 4;
		ts.edi = (dos_buf_phys & 15) + DOS_BUF_SIZE/2;
		base_real_int(&ts);
		err = dos_check_err(&ts);
	}
Example #2
0
int dos_read(dos_fd_t fd, void *buf, oskit_size_t size, oskit_size_t *out_actual)
{
	int err;
	int actual = 0;
	struct trap_state ts;
	oskit_addr_t dos_buf_phys = (oskit_addr_t)kvtophys(dos_buf);

	assert(dos_buf); assert(dos_buf_phys);
	assert(dos_buf_phys < 0x100000);

	init_ts(&ts);

	while (size > 0)
	{
		int little_size = size;
		int little_actual;

		if (little_size > DOS_BUF_SIZE)
			little_size = DOS_BUF_SIZE;

		ts.trapno = 0x21;
		ts.eax = 0x3f00;
		ts.ebx = fd;
		ts.ecx = little_size;
		ts.v86_ds = dos_buf_phys >> 4;
		ts.edx = dos_buf_phys & 15;
		base_real_int(&ts);
		if ((err = dos_check_err(&ts)) != 0)
			return err;
		little_actual = ts.eax & 0xffff;
		assert(little_actual <= little_size);

		/* XXX don't copy if buf is <1MB */
		memcpy(buf, dos_buf, little_actual);

		buf += little_actual;
		size -= little_actual;
		actual += little_actual;

		if (little_actual < little_size)
			break;
	}

	*out_actual = actual;
	return 0;
}
Example #3
0
int dos_read(dos_fd_t fd, void *buf, vm_size_t size, vm_size_t *out_actual)
{
	int err;
	int actual = 0;
	struct real_call_data real_call_data;
	vm_offset_t dos_buf_phys = (vm_offset_t)kvtophys(dos_buf);

	assert(dos_buf); assert(dos_buf_phys);
	assert(dos_buf_phys < 0x100000);

	dos_init_rcd(&real_call_data);

	while (size > 0)
	{
		int little_size = size;
		int little_actual;

		if (little_size > DOS_BUF_SIZE)
			little_size = DOS_BUF_SIZE;

		real_call_data.eax = 0x3f00;
		real_call_data.ebx = fd;
		real_call_data.ecx = little_size;
		real_call_data.ds = dos_buf_phys >> 4;
		real_call_data.edx = dos_buf_phys & 15;
		real_int(0x21, &real_call_data);
		if (err = dos_check_err(&real_call_data))
			return err;
		little_actual = real_call_data.eax & 0xffff;
		assert(little_actual <= little_size);

		/* XXX don't copy if buf is <1MB */
		memcpy(buf, dos_buf, little_actual);

		buf += little_actual;
		size -= little_actual;
		actual += little_actual;

		if (little_actual < little_size)
			break;
	}

	*out_actual = actual;
	return 0;
}