delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2009/05/30/17:00:17

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
From: Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
Newsgroups: comp.os.msdos.djgpp
Subject: Using rename() with files still opened.
Date: Sat, 30 May 2009 13:51:40 -0700 (PDT)
Organization: http://groups.google.com
Lines: 94
Message-ID: <4cc1f101-88b2-4cda-a7b5-b01eaa9a77bf@c9g2000yqm.googlegroups.com>
NNTP-Posting-Host: 93.207.23.67
Mime-Version: 1.0
X-Trace: posting.google.com 1243716700 5485 127.0.0.1 (30 May 2009 20:51:40 GMT)
X-Complaints-To: groups-abuse AT google DOT com
NNTP-Posting-Date: Sat, 30 May 2009 20:51:40 +0000 (UTC)
Complaints-To: groups-abuse AT google DOT com
Injection-Info: c9g2000yqm.googlegroups.com; posting-host=93.207.23.67;
posting-account=OsAajgoAAADdKJnkJkmhzqP0jo6I_P_0
User-Agent: G2/1.0
X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET
CLR 2.0.50727),gzip(gfe),gzip(gfe)
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

Please note the following code snippet:

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


int main(void)
{
  FILE *source_file, *target_file;
  char source_file_name[FILENAME_MAX], target_file_name[FILENAME_MAX];
  int fd, status;


  sprintf(target_file_name, "./targetXXXXXX");
  fd = mkstemp(target_file_name);
  target_file = fdopen (fd, "w");
  fprintf(target_file, "target file = \"%s\"", target_file_name);
  fclose(target_file);

  target_file = fopen(target_file_name, "rt");


  sprintf(source_file_name, "./sourceXXXXXX");
  fd = mkstemp(source_file_name);
  source_file = fdopen (fd, "w");
  fprintf(source_file, "source file = \"%s\"", source_file_name);
  fclose(source_file);


  errno = 0;
  status = rename(source_file_name, target_file_name);
  printf("rename status=%d   errno=%d\n", status, errno);

  return 0;
}



The goal is to rename the source file into the target file.  With
DJGPP's
rename() and _rename() functions this fails because the target file is
still open.  Of course, if the line:
  target_file = fopen(target_file_name, "rt");
is removed then the codes works flawlessly.  An inspection of
_rename.c
shows that function 0x7156 cannot rename the still opened target file.
After failing _rename tries a second time but before it tries to
remove
the target file but this also fails to due to the same reasson, so the
whole function does not work very well in this particular case when
the
target file has not been closed before the function call has been
issued.
On my linux box the code snippet works no matter if the target file to
be
replaced by the source file has been closed or not.  Now the question
arises if this is a bug or a feature?
Please note that the issue is not trivial.  I have noticed this while
I
was trying to port GNU sed 4.2.  This sed version and also the
previous
one has a new option "-i" called something like "in place replacement"
or something similar.  That means that it will be possible to start
sed
like this:
  sed -i s/foobar/raboof/ 1.txt
and this will perform the ordered subtitution but instead of writting
to stdout it will replace the source file (1.txt) with the result of
the
sed program.  Of course, this is done by storing the output of the sed
program in some temporary file and then renaming/replacing the input
file
with the tempory file by renaming it to the input file name.  For some
reason I have still not fully understood, sed does not fclose the
input
file before trying to replace it with the output file.  As explained
before, this causes no difficulty on linux but fails misserably when
sed
is compiled with DJGPP.
The question arises if _rename() shall be modified in such a way that
the file corresponding to the new file name is fclose/closed before
trying to replace it with the old file.  Because in case of success
the
file corrresponding to the new file name *before* calling _rename()
will
be deleted and replaced anyway, I think that closing it without
notifying
the function that called _rename() will not harm.
Some comments on this issue would be appreciated.


Regards,
Juan M. Guerrero

- Raw text -


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