aboutsummaryrefslogtreecommitdiffstats
path: root/com32/lib/readdir.c
blob: bfa52526df4bc54cfda1b4169b97747afea41039 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/*
 * readdir.c
 */

#include <dirent.h>
#include <stdio.h>
#include <errno.h>

#include <com32.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

struct dirent *readdir(DIR *dir)
{
	struct dirent *newde;
	com32sys_t regs;

	newde = NULL;
	if ((dir != NULL) && (dir->dd_fd != 0) && (dir->dd_stat >= 0)) {
		memset(__com32.cs_bounce, 0, 32);
		memset(&regs, 0, sizeof(regs));

		regs.eax.w[0] = 0x0021;
		regs.esi.w[0] = dir->dd_fd;
		regs.edi.w[0] = OFFS(__com32.cs_bounce);
		regs.es = SEG(__com32.cs_bounce);

		__com32.cs_intcall(0x22, &regs, &regs);

		/* Don't do this as we won't be able to rewind.
		dir->dd_fd = regs.esi.w[0];	/* Shouldn't be needed? */
		if ((!(regs.eflags.l & EFLAGS_CF)) && (regs.esi.w[0] != 0)) {
			newde = calloc(1, sizeof(newde));
			if (newde != NULL) {
				strcpy(newde->d_name, __com32.cs_bounce);
				newde->d_mode = regs.edx.b[0];
				newde->d_size = regs.eax.l;
				newde->d_ino = regs.ebx.l;
				dir->dd_stat = 1;
			} else {
				dir->dd_stat = -2;
				errno = ENOMEM;
			}
		} else {
			dir->dd_stat = -1;
			errno = EIO;	/* Is this the right nmber? */
		}
	} else {
		errno = EBADF;
	}

	return newde;
}