Mail Archives: djgpp-workers/2001/08/16/03:38:51
_open.c cleaned up a bit. Testing looks good. Test program below, use it
to look at results from _open linked in (plus see what happens on other
calls using old _open). Please make comments, then we test?
*** _open.c_ Tue Aug 14 23:14:02 2001
--- _open2.c Thu Aug 16 01:16:08 2001
*************** _open(const char* filename, int oflag)
*** 30,31 ****
--- 30,73 ----
+ if(use_lfn && _osmajor == 5 && _get_dos_version(1) == 0x532) {
+ /* Windows 2000 or XP; or NT with LFN TSR. Windows 2000 behaves
+ badly when using IOCTL and write-truncate calls on LFN handles.
+ We convert the long name to a short name and open existing files
+ via short name. New files use LFN, but we know they aren't
+ character devices. */
+ r.x.ax = 0x7160;
+ r.x.cx = 1; /* Get short name equivalent */
+ r.x.ds = __tb_segment;
+ r.x.si = __tb_offset; /* Long name to convert - putpath */
+ r.x.es = __tb_segment;
+ r.x.di = __tb_offset + _put_path(filename); /* Short name destination */
+ __dpmi_int(0x21, &r);
+ if(!(r.x.flags & 1)) { /* Get short name success */
+ r.x.ax = 0x6c00;
+ r.x.bx = (oflag & 0xff);
+ r.x.dx = 1; /* Open existing file */
+ r.x.si = r.x.di;
+ goto do_open;
+ } else {
+ /* Short name get failed, file doesn't exist or is device (same error) */
+ r.x.ax = 0x7143; /* Get attributes */
+ r.h.bl = 0;
+ r.x.dx = __tb_offset; /* Treat original name as short */
+ __dpmi_int(0x21, &r); /* This is same as lfn _chmod */
+ if(!(r.x.flags & 1)) { /* Name exists */
+ r.x.ax = 0x6c00;
+ r.x.bx = (oflag & 0xff);
+ r.x.dx = 1; /* Open existing file */
+ r.x.si = __tb_offset;
+ r.x.cx = 0;
+ __dpmi_int(0x21, &r);
+ if(!(r.x.flags & 1)) { /* Success! */
+ goto do_hset;
+ }
+ /* Fail on short name open after _chmod said OK.
+ Device with directory? We should re-try with LFN.
+ Permission? Readonly file? We should quit.
+ Let it fall through to the LFN open which should succeed. */
+ }
+ }
+ }
if(use_lfn) {
*************** _open(const char* filename, int oflag)
*** 56,60 ****
}
- r.x.cx = 0;
r.x.ds = __tb_segment;
_put_path(filename);
__dpmi_int(0x21, &r);
--- 98,103 ----
}
r.x.ds = __tb_segment;
_put_path(filename);
+ do_open:
+ r.x.cx = 0;
__dpmi_int(0x21, &r);
*************** _open(const char* filename, int oflag)
*** 65,66 ****
--- 108,110 ----
}
+ do_hset:
__file_handle_set(r.x.ax, O_BINARY);
\\test\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dpmi.h>
#include <go32.h>
#include <libc/dosio.h>
#define TEST argv[1]
int main(int argc, char** argv) {
int i;
struct stat tstat;
for(i=0;i<5;i++)
printf("Dev info[%d]: 0x%x\n",i,_get_dev_info(i));
if(_USE_LFN)
printf("Long names are active.\n");
else
printf("Long names are *NOT* active.\n");
if(argc != 2)
return printf("Usage: test <devnam>\n");
printf("_chmod: 0x%x\n",_chmod(TEST,0));
if(_USE_LFN) {
__dpmi_regs r;
r.x.ax = 0x7160;
r.x.cx = 1; /* Get short name equivalent */
r.x.ds = __tb_segment;
r.x.si = __tb_offset;
r.x.es = __tb_segment;
r.x.di = __tb_offset + _put_path(TEST);
__dpmi_int(0x21, &r);
if(!(r.x.flags & 1)) {
char longname[255];
dosmemget(__tb_segment*16+r.x.di,255,longname);
printf("7160 returned %s\n",longname);
} else {
printf("7160 failure 0x%x\n",r.x.ax);
}
}
{
char name[255];
if(_truename(TEST,name))
printf("Truename returned %s\n",name);
else
printf("Truename failed.\n");
}
i = open(TEST,
O_WRONLY | O_BINARY
| O_APPEND,
S_IREAD | S_IWRITE);
printf("Append Handle=%d\n",i);
printf("Dev info: 0x%x\n",_get_dev_info(i));
if(i != -1) {
__dpmi_regs r;
int fsbuff[16],j;
r.x.ax = 0x71a6;
r.x.bx = i;
r.x.ds = __tb_segment;
r.x.dx = 0;
__dpmi_int(0x21, &r);
if(r.x.flags & 1)
printf("71a6 failure 0x%x\n",r.x.ax);
else {
dosmemget(__tb_segment*16,sizeof(fsbuff),fsbuff);
printf("71a6:");
for(j=0;j<13;j++)
printf(" 0x%x",fsbuff[j]);
printf("\n");
}
i = fstat(i, &tstat);
printf("ret=%d atime=%d ctime=%d dev=%d ino=%d mode=%d mtime=%d nlink=%d size=%d blksiz=%d\n",
i,tstat.st_atime,tstat.st_ctime,tstat.st_dev,tstat.st_ino,tstat.st_mode,tstat.st_mtime,
tstat.st_nlink,tstat.st_size,tstat.st_blksize);
/* _djstat_describe_lossage(stdout); */
}
i = open(TEST,
O_WRONLY | O_BINARY
| O_TRUNC,
S_IREAD | S_IWRITE);
printf("Trunc Handle=%d\n",i);
printf("Dev info: 0x%x\n",_get_dev_info(i));
return 0;
}
- Raw text -