X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f From: Juan Manuel Guerrero 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 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit 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 #include #include 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