summaryrefslogtreecommitdiff
path: root/com32/lib/readdir.c
blob: 2ec7c7b301ba4cc8844bba41832a04f04a504a19 (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;
}