On Tue, 16 Jul 2002, Arnaldo Pereira wrote:
> I'm running a foxpro program under dosemu(1.1.3.2)+drdos(7.03).
> The foxpro system seems to work fine, but under some circunstances, it can't
> open a database file, especially when another user has already opened it.
> It seems the foxpro application is trying to lock an unique database
> register, but dosemu is locking the entire database file.
> I've already tried the share.exe, but it works the same way as without it.
> Any thought about the solution ?
Could you try this patch and see if it makes any difference?
Bart
diff -ur -x*.o -x*~ -x*.d dosemu-1.1.3.2/src/dosext/mfs/mangle.c
dosemu-1.1.3.3/src/dosext/mfs/mangle.c
--- dosemu-1.1.3.2/src/dosext/mfs/mangle.c Sun Jun 16 12:22:43 2002
+++ dosemu-1.1.3.3/src/dosext/mfs/mangle.c Sat Jun 29 18:54:14 2002
@@ -149,6 +149,7 @@
{
int len = strlen(fname);
char *dot_pos = strchr(fname,'.');
+ char *s;
int l;
DEBUG(5,("checking %s for 8.3\n",fname));
@@ -158,7 +159,7 @@
return(False);
/* can't be an MS-DOS Special file such as lpt1 or even lpt1.txt */
- if (is_reserved_msdos(fname))
+ if ((s = is_reserved_msdos(fname)) && strcmp(s, "NUL") != 0)
return(False);
/* can't contain invalid dos chars */
diff -ur -x*.o -x*~ -x*.d dosemu-1.1.3.2/src/dosext/mfs/mfs.c
dosemu-1.1.3.3/src/dosext/mfs/mfs.c
--- dosemu-1.1.3.2/src/dosext/mfs/mfs.c Sun Jun 16 00:48:05 2002
+++ dosemu-1.1.3.3/src/dosext/mfs/mfs.c Sat Jun 29 19:22:25 2002
@@ -1051,8 +1051,8 @@
*
* DANG_END_REMARK
*/
- if (strncasecmpDOS(mname, "NUL ", strlen(mname)) == 0 &&
- strncasecmpDOS(mext, " ", strlen(mext)) == 0) {
+ if (strncasecmpDOS(mname, "NUL ", 8) == 0 &&
+ strncasecmpDOS(mext, " ", 3) == 0) {
entry = make_entry();
dir_list = entry;
@@ -1702,10 +1702,12 @@
Debug0((dbg_fd, "dos_fs: build_ufs_path for DOS path '%s'\n", path));
- if ((s=is_reserved_msdos(path))) {
+ /* we handle only NUL ourselves; this needs to be changed though
+ to handle other devices too ! */
+ if ((s=is_reserved_msdos(path)) && (strcmp(s, "NUL") != 0)) {
Debug0((dbg_fd,"MFS: Special File, so name changed to '%s'\n", s));
- strcpy (path, s);
strcpy (ufs, s);
+ strcpy (path, s);
return FALSE;
}
else {
@@ -1806,8 +1808,19 @@
/* check for device files like NUL, CON, etc. */
if ((slash1=is_reserved_msdos(fpath))) {
if (strcmp(slash1, "NUL") == 0) {
+ slash1 = fpath + strlen(fpath);
+ while (*slash1 != '/' && slash1 > fpath)
+ slash1--;
+ if (*slash1 == '/') {
+ *slash1 = '\0';
+ /* check if path exists */
+ if (stat(fpath, st) || !S_ISDIR(st->st_mode))
+ return (FALSE);
+ *slash1 = '/';
+ }
Debug0((dbg_fd, "nul cmpr\n"));
stat("/dev/null", st);
+ strcpy(fpath, "/dev/null");
return (TRUE);
} else {
Debug0((dbg_fd, "Device file %s\n", slash1));
@@ -2538,7 +2551,7 @@
}
static boolean_t
-share(int fd, boolean_t writing, sft_t sft)
+share(int fd, int mode, sft_t sft)
{
/*
* Return whether FD doesn't break any sharing rules. FD was opened for
@@ -2567,51 +2580,128 @@
fl.l_start = 0x7fffffff;
fl.l_len = 1;
fl.l_pid = 0;
+ fl.l_type = F_WRLCK;
+ /* see whatever locks are possible */
+
+ if ( fcntl( fd, F_GETLK, &fl ) ) {
+ /* work around Linux's NFS locking problems (June 1999) -- sw */
+ static unsigned char u[26] = { 0, };
+ if(current_drive < 26) {
+ if(!u[current_drive])
+ fprintf(stderr,
+ "SHAREing doesn't work on drive %c: (probably NFS volume?)\n",
+ current_drive + 'A'
+ );
+ u[current_drive] = 1;
+ }
+ return (TRUE);
+ }
+
+ /* end NFS fix */
+
+ /* file is already locked? then do not even open */
+ /* a Unix read lock prevents writing;
+ a Unix write lock prevents reading and writing,
+ but for DOS compatibility we allow reading for write locks */
+ if ((fl.l_type == F_RDLCK && mode != O_RDONLY) ||
+ (fl.l_type == F_WRLCK && mode != O_WRONLY))
+ return FALSE;
+
switch ( share_mode ) {
+ /* this is a little heuristic and does not completely
+ match to DOS behaviour. That would require tracking
+ how existing fd's are opened and comparing st_dev
+ and st_ino fields
+ from Ralf Brown's interrupt list:
+ (Table 01403)
+Values of DOS 2-6.22 file sharing behavior:
+ | Second and subsequent Opens
+ First |Compat Deny Deny Deny Deny
+ Open | All Write Read None
+ |R W RW R W RW R W RW R W RW R W RW
+ - - - - -| - - - - - - - - - - - - - - - - -
+ Compat R |Y Y Y N N N 1 N N N N N 1 N N
+ W |Y Y Y N N N N N N N N N N N N
+ RW|Y Y Y N N N N N N N N N N N N
+ - - - - -|
+ Deny R |C C C N N N N N N N N N N N N
+ All W |C C C N N N N N N N N N N N N
+ RW|C C C N N N N N N N N N N N N
+ - - - - -|
+ Deny R |2 C C N N N Y N N N N N Y N N
+ Write W |C C C N N N N N N Y N N Y N N
+ RW|C C C N N N N N N N N N Y N N
+ - - - - -|
+ Deny R |C C C N N N N Y N N N N N Y N
+ Read W |C C C N N N N N N N Y N N Y N
+ RW|C C C N N N N N N N N N N Y N
+ - - - - -|
+ Deny R |2 C C N N N Y Y Y N N N Y Y Y
+ None W |C C C N N N N N N Y Y Y Y Y Y
+ RW|C C C N N N N N N N N N Y Y Y
+
+ our sharing behaviour:
+ Compat R |Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
+ W |Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
+ RW|Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
+ - - - - -|
+ Deny R |Y N N N N N Y N N N N N Y N N
+ All W |N N N N N N N N N N Y N N Y N
+ RW|N N N N N N N N N N Y N N Y N
+ - - - - -|
+ Deny R |Y N N N N N Y N N N N N Y N N
+ Write W |Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
+ RW|Y N N N N N Y N N N N N Y N N
+ - - - - -|
+ Deny R |Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
+ Read W |N N N N N N N N N N Y N N Y N
+ RW|N N N N N N N N N N Y N N Y N
+ - - - - -|
+ Deny R |Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
+ None W |Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
+ RW|Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
+
+ Legend: Y = open succeeds, N = open fails with error code 05h
+ C = open fails, INT 24 generated
+ 1 = open succeeds if file read-only, else fails with error code
+ 2 = open succeeds if file read-only, else fails with INT 24
+ */
case COMPAT_MODE:
- case DENY_ALL:
+ if (fl.l_type == F_WRLCK) return FALSE;
+ case DENY_NONE:
+ return TRUE; /* do not set locks at all */
case DENY_WRITE:
+ if (fl.l_type == F_WRLCK) return FALSE;
+ if (mode == O_WRONLY) return TRUE; /* only apply read locks */
+ fl.l_type = F_RDLCK;
+ break;
case DENY_READ:
- fl.l_type = !writing ? F_RDLCK : F_WRLCK;
+ if (fl.l_type == F_RDLCK) return FALSE;
+ if (mode == O_RDONLY) return TRUE; /* only apply write locks */
+ fl.l_type = F_WRLCK;
break;
- case DENY_ANY:
- fl.l_type = F_RDLCK;
+ case DENY_ALL:
+ if (fl.l_type == F_WRLCK || fl.l_type == F_RDLCK) return FALSE;
+ fl.l_type = mode == O_RDONLY ? F_RDLCK : F_WRLCK;
break;
default:
- fl.l_type = F_WRLCK;
Debug0((dbg_fd, "internal SHARE: unknown sharing mode %x\n",
share_mode));
+ return FALSE;
break;
}
- if ( fcntl( fd, F_SETLK, &fl ) == 0 ) return (TRUE);
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0x7fffffff;
+ fl.l_len = 1;
+ fl.l_pid = 0;
+ fcntl( fd, F_SETLK, &fl );
Debug0((dbg_fd,
- "internal SHARE: locking failed: drive %c:, fd %d, type %d whence %d pid %d\n",
+ "internal SHARE: locking: drive %c:, fd %d, type %d whence %d pid %d\n",
current_drive + 'A', fd, fl.l_type, fl.l_whence, fl.l_pid
));
- /* work around Linux's NFS locking problems (June 1999) -- sw */
-
- {
- static unsigned char u[26] = { 0, };
-
- if ( fcntl( fd, F_GETLK, &fl ) ) {
- if(current_drive < 26) {
- if(!u[current_drive])
- fprintf(stderr,
- "SHAREing doesn't work on drive %c: (probably NFS volume?)\n",
- current_drive + 'A'
- );
- u[current_drive] = 1;
- }
-
- return (TRUE);
- }
- }
-
- /* end NFS fix */
-
- return (FALSE);
+ return (TRUE);
}
static int
@@ -3180,6 +3270,11 @@
return (FALSE);
}
build_ufs_path(fpath, filename1);
+ for (i = 0, bs_pos = 0; fpath[i] != EOS; i++) {
+ if (fpath[i] == SLASH)
+ bs_pos = i;
+ }
+ auspr(fpath + bs_pos + 1, fname, fext);
if (!find_file(fpath, &st)) {
Debug0((dbg_fd, "open failed: '%s'\n", fpath));
SETWORD(&(state->eax), FILE_NOT_FOUND);
@@ -3191,6 +3286,7 @@
SETWORD(&(state->eax), FILE_NOT_FOUND);
return (FALSE);
}
+ attr = get_dos_attr(st.st_mode,is_hidden(fpath));
if (dos_mode == READ_ACC) {
unix_mode = O_RDONLY;
}
@@ -3212,33 +3308,19 @@
return (FALSE);
}
- /* Handle DOS requests for drive:\patch\NUL */
- if (!strncmpDOS((u_char *) (fpath + strlen(fpath) - 3), "nul", 3)) {
- if ((fd = open("/dev/null", unix_mode)) < 0) {
- Debug0((dbg_fd, "access denied:'%s'\n", fpath));
- SETWORD(&(state->eax), ACCESS_DENIED);
- return (FALSE);
- }
- }
- else {
- if ((fd = open(fpath, unix_mode )) < 0) {
- Debug0((dbg_fd, "access denied:'%s'\n", fpath));
- SETWORD(&(state->eax), ACCESS_DENIED);
- return (FALSE);
- }
- if (!share(fd, unix_mode != O_RDONLY, sft)) {
- close( fd );
- SETWORD(&(state->eax), ACCESS_DENIED);
- return (FALSE);
- }
+ if ((fd = open(fpath, unix_mode )) < 0) {
+ Debug0((dbg_fd, "access denied:'%s'\n", fpath));
+ SETWORD(&(state->eax), ACCESS_DENIED);
+ return (FALSE);
}
-
- for (i = 0, bs_pos = 0; fpath[i] != EOS; i++) {
- if (fpath[i] == SLASH)
- bs_pos = i;
+ if (!share(fd, unix_mode & O_ACCMODE, sft)) {
+ close( fd );
+ SETWORD(&(state->eax), ACCESS_DENIED);
+ return (FALSE);
}
- auspr(fpath + bs_pos + 1, sft_name(sft), sft_ext(sft));
+ memcpy(sft_name(sft), fname, 8);
+ memcpy(sft_ext(sft), fext, 3);
#if 0
if (FCBcall)
@@ -3249,11 +3331,7 @@
sft_dev_drive_ptr(sft) = (u_long)strdup(fpath);
sft_directory_entry(sft) = 0;
sft_directory_sector(sft) = 0;
-#ifdef NOTEST
sft_attribute_byte(sft) = attr;
-#else
- sft_attribute_byte(sft) = 0x20;
-#endif /* NOTEST */
sft_device_info(sft) = current_drive + (0x8040);
time_to_dos(&st.st_mtime,
&sft_date(sft), &sft_time(sft));
@@ -3322,7 +3400,13 @@
return (FALSE);
}
build_ufs_path(fpath, filename1);
-
+ bs_pos=0;
+ for (i = 0, bs_pos = 0; fpath[i] != EOS; i++) {
+ if (fpath[i] == SLASH)
+ bs_pos = i;
+ }
+ auspr(fpath + bs_pos + 1, fname, fext);
+
if (find_file(fpath, &st)) {
Debug0((dbg_fd, "st.st_mode = 0x%02x, handles=%d\n", st.st_mode,
sft_handle_cnt(sft)));
if ( /* !(st.st_mode & S_IFREG) || */ create_file) {
@@ -3332,12 +3416,6 @@
}
}
- bs_pos=0;
- for (i = 0, bs_pos = 0; fpath[i] != EOS; i++) {
- if (fpath[i] == SLASH)
- bs_pos = i;
- }
-
if ((fd = open(fpath, (O_RDWR | O_CREAT),
get_unix_attr(0664, attr))) < 0) {
strncpy(buf, fpath, bs_pos);
@@ -3358,7 +3436,7 @@
}
}
- if (!share(fd, TRUE, sft) || ftruncate(fd, 0) != 0) {
+ if (!share(fd, O_RDWR, sft) || ftruncate(fd, 0) != 0) {
Debug0((dbg_fd, "unable to truncate %s: %s (%d)\n",
fpath, strerror(errno), errno));
close(fd);
@@ -3372,7 +3450,8 @@
leave_priv_setting();
}
- auspr(fpath + bs_pos + 1, sft_name(sft), sft_ext(sft));
+ memcpy(sft_name(sft), fname, 8);
+ memcpy(sft_ext(sft), fext, 3);
sft_dev_drive_ptr(sft) = (u_long)strdup(fpath);
/* This caused a bug with temporary files so they couldn't be read,
@@ -3483,8 +3562,8 @@
fpath[bs_pos] = EOS;
auspr(fpath + bs_pos + 1, fname, fext);
- strncpy(sdb_template_name(sdb), fname, 8);
- strncpy(sdb_template_ext(sdb), fext, 3);
+ memcpy(sdb_template_name(sdb), fname, 8);
+ memcpy(sdb_template_ext(sdb), fext, 3);
sdb_attribute(sdb) = attr;
sdb_drive_letter(sdb) = 0x80 + current_drive;
sdb_dir_entry(sdb) = HLIST_STACK_SIZE*2; /* correct value later */
@@ -3542,6 +3621,8 @@
strncpy(sdb_file_name(sdb), fname, 8);
strncpy(sdb_file_ext(sdb), fext, 3);
sdb_file_attr(sdb) = VOLUME_LABEL;
+ if (attr == VOLUME_LABEL)
+ return TRUE; /* no findnext */
sdb_dir_entry(sdb) = 0x0;
/* if (attr != VOLUME_LABEL)
find_in_progress = TRUE; */
diff -ur -x*.o -x*~ -x*.d dosemu-1.1.3.2/src/dosext/mfs/mfs.h
dosemu-1.1.3.3/src/dosext/mfs/mfs.h
--- dosemu-1.1.3.2/src/dosext/mfs/mfs.h Sun May 26 16:57:56 2002
+++ dosemu-1.1.3.3/src/dosext/mfs/mfs.h Thu Jun 20 18:37:54 2002
@@ -387,7 +387,7 @@
#define DENY_ALL 0x01
#define DENY_WRITE 0x02
#define DENY_READ 0x03
-#define DENY_ANY 0x04
+#define DENY_NONE 0x04
#define CHILD_INHERIT 0x00
#define NO_INHERIT 0x01