www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1998/01/30/15:57:06

Message-Id: <m0xyHnZ-000S2dC@inti.gov.ar>
Comments: Authenticated sender is <salvador AT natacha DOT inti DOT gov DOT ar>
From: "Salvador Eduardo Tropea (SET)" <salvador AT inti DOT gov DOT ar>
Organization: INTI
To: djgpp-workers AT delorie DOT com
Date: Fri, 30 Jan 1998 18:00:27 +0000
MIME-Version: 1.0
Subject: fopen and shared files question

Hi All:

  I was experimenting a problem with my editor and found that it can be
solved patching fopen, so I'll expose here my case.

My problem:
  If I run 2 copies of my editor under Win 3.1 + Share the second copy is
totally unable to open the help file because the first one opened it (too
bad for me).

Previous cases:
 Some time ago a user was asking for help because he was unable to open a
file already opened by a very bad editor (you know the one from M$). After
some little experiment Eli found that it can be solved with the following
patch: (I include the whole message)

From:             bukinm AT inp DOT nsk DOT su (Michael Bukin)
Subject:          Re: Desperately need help with "fopen"
Date sent:        Tue, 15 Apr 1997 14:16:27 GMT
Organization:     BINP SD RAS
Send reply to:    bukinm AT inp DOT nsk DOT su
To:               djgpp AT delorie DOT com

On Tue, 15 Apr 1997 09:11:41 GMT, Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
wrote:

> Thanks.  But I wanted to ask you to change the source of `fopen' so that 
> it tries to call `open' once in compatinility mode, and if that fails, 
> call it again with DENYNONE bit.  Can you please do that and see if that 
> solves the problem?

  Yes, it does. Here is a patch that was used:

*** src/libc/ansi/stdio/fopen.c	Wed Aug 23 03:49:24 1995
--- src/libc/ansi/stdio/fopen.c	Tue Apr 15 18:57:02 1997
***************
*** 53,59 ****
  
    fd = open(file, oflags, 0666);
    if (fd < 0)
!     return NULL;
  
    if (*mode == 'a')
      lseek(fd, 0, SEEK_END);
--- 53,63 ----
  
    fd = open(file, oflags, 0666);
    if (fd < 0)
!     {
!       fd = open(file, oflags | SH_DENYNO, 0666);
!       if (fd < 0)
!         return NULL;
!     }
  
    if (*mode == 'a')
      lseek(fd, 0, SEEK_END);
----------------------------------- End of message ------------------------

I taked a look to the v2.02 alpha (980101) and the patch isn't there.

What I proposse:
The Eli/Michael's patch is good if the file was opened by other application
with the DENYWR flag, but not if the other application used the "compatible
mode". The last is the current status of djgpp programs. So two djgpp
programs doesn't get any benefit from this patch; and that's my case.
So I proposse the following code:

  fd = open(file, oflags | SH_DENYWR, 0666);
  if (fd < 0)
    {
      fd = open(file, oflags | SH_DENYNO, 0666);
      if (fd < 0)
        return NULL;
    }

That means: ever open the files trying to deny write access to other
applications and if it fails try to open it without any deny. (sorry for the
use of the deny word in this way).

Note that this ISN'T a patch, is a code to show what I want (I tested it
successfully) and get the opinion of the rest.

Other options are: open the file with SH_DENYRW (deny all) if we will write,
SH_DENYWR if we will read and SH_DENYNO if the open fails.
And yet another option is to add a special variable to control it.

I like the code expossed, the only thing that can be dangerous is when we
open to write and other djgpp process opens for reading, in this case both
will be successfull, and the results will be unpredictable in the "reading"
program; but in UNIX it could happend too (or not?).
Perhaps the best is to add a variable like this:

int __djgpp_share_mode=SH_DENYWR;

...

  fd = open(file, oflags | __djgpp_share_mode, 0666);
  if (fd < 0)
    {
      fd = open(file, oflags | SH_DENYNO, 0666);
      if (fd < 0)
        return NULL;
    }

giving to the user the oportunity to make __djgpp_share_mode=SH_DENYRW; or
even __djgpp_share_mode=0;

I want the opinions of the rest.

SET

P.S. If anyone is wondering what Borland does here is what C/C++ Run Time
Library - Version 5.0 uses:

They use an internal open defined like this:

static FILE * pascal near __openfp (FILE *fp,
                        const char *filename, const char *type, int shflag);

And fopen is like this:

FILE    * _FARFUNC fopen (const char *filename, const char *type)
{
        register FILE   *fp;

        if ((fp = __getfp()) == NULL)
                return NULL;
        else
                return __openfp (fp, filename, type, 0);

}

So they clearly do (or at least did in BC++ 3.1) the same that the current
djgpp fopen does, but they provide functions to "open shared".
------------------------------------ 0 --------------------------------
Visit my home page: http://set-soft.home.ml.org/
or
http://www.geocities.com/SiliconValley/Vista/6552/
Salvador Eduardo Tropea (SET). (Electronics Engineer)
Alternative e-mail: set-sot AT usa DOT net - ICQ: 2951574
Address: Curapaligue 2124, Caseros, 3 de Febrero
Buenos Aires, (1678), ARGENTINA
TE: +(541) 759 0013

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019