Bug 32784 - [win32] Using 'CONOUT$', 'CONIN$', or 'CONERR$' as assigned file generates Fortran runtime error: Bad file descriptor
Summary: [win32] Using 'CONOUT$', 'CONIN$', or 'CONERR$' as assigned file generates Fo...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libfortran (show other bugs)
Version: 4.3.0
: P3 enhancement
Target Milestone: ---
Assignee: Jerry DeLisle
URL:
Keywords:
Depends on:
Blocks: 37515
  Show dependency treegraph
 
Reported: 2007-07-16 21:32 UTC by Steve Chapel
Modified: 2009-08-15 00:50 UTC (History)
1 user (show)

See Also:
Host:
Target: i386-
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-07-18 02:54:22


Attachments
Disregard, found another problem (461 bytes, patch)
2007-07-23 02:59 UTC, Jerry DeLisle
Details | Diff
Update patch (497 bytes, patch)
2007-07-23 04:41 UTC, Jerry DeLisle
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Steve Chapel 2007-07-16 21:32:18 UTC
When this program is compiled and run:

       character*72 fnint
       data fnint /'con'/
       i=index(fnint,' ');
       open(unit=29,file=fnint(1:i-1),status='new')
       write(29,100)
100    format('1Hello, world!')
       end

It generates this error message:

At line 4 of file bug.for (unit = 29, file = '')
Fortran runtime error: File 'con' does not exist

The same error message is generated when status='new' is omitted.

Here is the info for the compiler I used (it's FX's prebuilt mingw binary):

Using built-in specs.
Target: i386-pc-mingw32
Configured with: ../trunk/configure --prefix=/mingw --enable-languages=c,fortran
 --with-gmp=/home/coudert/local --disable-nls --with-ld=/mingw/bin/ld --with-as=
/mingw/bin/as --disable-werror --enable-bootstrap --enable-threads --build=i386-
pc-mingw32 --disable-shared --enable-libgomp
Thread model: win32
gcc version 4.3.0 20070706 (experimental)

I am not able to run NONMEM <http://c255.ucsf.edu/nonmem1.html> built with gfortran because of this bug.
Comment 1 Andrew Pinski 2007-07-16 22:15:19 UTC
This is a windows only issue as using special files (device files) under GNU/Linux works just fine.
Comment 2 Jerry DeLisle 2007-07-17 02:25:45 UTC
Under Cygwin we get:

$ ./a.exe 
At line 4 of file test.f90 (unit = 29, file = '')
Fortran runtime error: File 'con' already exists

con is a reserved device name from MS DOS:

See http://www.tcs.org/ioport/jul98/driver-3.htm

Under cygwin, if I just try to cat to con:

$ cat test.f90 | con
-bash: /home/Jerry/bin/con: Bad file descriptor

This problem has nothing to do with gfortran.  I am afraid you will have to edit and change the name to something other than 'con'

Even if I try to edit a file named con.f with vi it locks up vi.

Unless someone has a better idea, I suggest closing this bug as invalid.  How difficult is it to change that name from 'con' to something else? 
Comment 3 Andrew Pinski 2007-07-17 02:37:02 UTC
Except con should be the console aka /dev/pts/?? .
Comment 4 Steve Chapel 2007-07-17 02:52:24 UTC
What name should I change 'con' to so that the write statement writes to the console? I asked on the gfortran mailing list, and I was told to submit this bug report. If it's as simple as changing the name, let me know and I can code it in a change to NONMEM so that I can use gfortran to compile NONMEM.

It seems that con should work though. At the command prompt in Windows XP, the following commands work just as I'd expect:
C:\> copy afile con
C:\> copy con anewfile
C:\> dir > con

Piping to con doesn't work, because con is a device, not a process:
C:\> dir | con
' ' is not recognized as an internal or external command,
operable program or batch file.
Comment 5 Jerry DeLisle 2007-07-17 04:38:48 UTC
I will investigate further, but if all its trying to do is WRITE to the console use WRITE(unit=6) and don't give it a filename at all. You don't even need to OPEN it.  It will be OPENed implicitly for you.  READ (unit=5) to read from the console.

Will this work for you?

In the mean time I will go look at this code for this application a little.
Comment 6 Danny Smith 2007-07-17 08:43:58 UTC
(In reply to comment #4)
> What name should I change 'con' to so that the write statement writes to the
> console? 

I think it should be CONOUT$ (ie you had it right the first time).
The following works with g77 (and the old Intel Fortran ivf compiler)

      open(unit=29,file='CONOUT$')
      write(29,100)
100   format('1Hello, world!')
      end 

The following works in C

#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>

int main()
{
 int fd= _open ("CONOUT$", _O_RDWR));
  if (fd >= 0)
   _write (fd, "Hello world", sizeof ("Hello world"));   
 return 0;
}
Comment 7 Steve Chapel 2007-07-17 12:49:51 UTC
(In reply to comment #5)
> if all its trying to do is WRITE to the console
> use WRITE(unit=6) and don't give it a filename at all.
> 
> Will this work for you?

Not really. It's been written that way so that you can easily change where the output goes by changing one line of code. Hardcoding the output to go to the console defeats the purpose. I'm also not the author of the code, and I don't want to have to manually change every line of code like that in my local copy with each release of NONMEM.

> I think it should be CONOUT$ (ie you had it right the first time).
> The following works with g77 (and the old Intel Fortran ivf compiler)

That's what it was the first time, when I got Fortran runtime error: Bad file descriptor. That's why I changed it to con. If there's something else I can change it to, I can fairly easily manually make that change with each release of NONMEM because it's only one line of code.
Comment 8 Jerry DeLisle 2007-07-18 02:54:21 UTC
I can't get anything to work, but I have some ideas.
Comment 9 Jerry DeLisle 2007-07-21 19:39:29 UTC
The following simple patch enables gfortran to run for the tet case.  I need to get the proper #ifdef #endif condition set up and do a similar thing for CONIN$ and CONERR$ ( or whatever the windows equivalents are) and this will be all set. I tested this on cygwin.

Index: unix.c
===================================================================
--- unix.c      (revision 126808)
+++ unix.c      (working copy)
@@ -1259,6 +1259,13 @@ regular_file (st_parameter_open *opp, un
   crflag |= O_BINARY;
 #endif
 
+  if (strncmp (path, "CONOUT$", 7) == 0)
+    {
+      fd = STDOUT_FILENO;
+      flags->action = ACTION_WRITE;
+      return fd;
+    }
+
   mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
   fd = open (path, rwflag | crflag, mode);
   if (flags->action != ACTION_UNSPECIFIED)
Comment 10 Jerry DeLisle 2007-07-21 23:08:48 UTC
Here is a complete patch, tested on Cygwin.  I need to test on mingw.  Can anyone help with that?

Index: unix.c
===================================================================
--- unix.c      (revision 126808)
+++ unix.c      (working copy)
@@ -81,6 +81,13 @@ Boston, MA 02110-1301, USA.  */
 #define S_IWOTH 0
 #endif
 
+#ifdef __CYGWIN__
+#define HAVE_DOS_CONIO
+#endif
+
+#ifdef __MINGW32__
+#define HAVE_DOS_CONIO
+#endif
 
 /* Unix stream I/O module */
 
@@ -1259,6 +1266,27 @@ regular_file (st_parameter_open *opp, un
   crflag |= O_BINARY;
 #endif
 
+#ifdef HAVE_DOS_CONIO
+  if (strncmp (path, "CONOUT$", 7) == 0)
+    {
+      fd = STDOUT_FILENO;
+      flags->action = ACTION_WRITE;
+      return fd;
+    }
+  if (strncmp (path, "CONIN$", 6) == 0)
+    {
+      fd = STDIN_FILENO;
+      flags->action = ACTION_READ;
+      return fd;
+    }
+  if (strncmp (path, "CONERR$", 7) == 0)
+    {
+      fd = STDERR_FILENO;
+      flags->action = ACTION_WRITE;
+      return fd;
+    }
+#endif
+
   mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
   fd = open (path, rwflag | crflag, mode);
   if (flags->action != ACTION_UNSPECIFIED)
Comment 11 Danny Smith 2007-07-22 08:42:20 UTC
(In reply to comment #10)
> Here is a complete patch, tested on Cygwin.  I need to test on mingw.  Can
> anyone help with that?
> 
      open(unit=29,file='CONOUT$')
      write(29,100)
100   format('Hello, world!')
      end

On mingw, with your patch, I get this on stdout:
Hello, world!

and this on stderr:

At line 2 of file conout.f (unit = 29, file = 'CONOUT$')
Fortran runtime error: Bad file descriptor
Comment 12 Jerry DeLisle 2007-07-22 14:21:02 UTC
Yes, I found similar on Cygwin, so I am still at it on this one.
Comment 13 Jerry DeLisle 2007-07-23 02:59:48 UTC
Created attachment 13950 [details]
Disregard, found another problem

Danny, can you please check this new patch.  Works on Cygwin as far as I can tell.
Comment 14 Jerry DeLisle 2007-07-23 04:41:28 UTC
Created attachment 13951 [details]
Update patch

This one does not fail when there is no filename, :)
Comment 15 Danny Smith 2007-07-23 04:44:09 UTC
(In reply to comment #13)
> Created an attachment (id=13950) [edit]
> Patch to provide conio support
> 
> Danny, can you please check this new patch.  Works on Cygwin as far as I can
> tell.
> 
Not on mingw.  If you run the app generated from conout.f  in an environ that dup's and redirects stderr, it appears to work.  If you run from a plain ordinary Windows console, I still get 
Hello, world! 
At line 2 of file a1.f (unit = 29, file = 'CONOUT$')
Fortran runtime error: Bad file descriptor

Try testing your cygwin-built app from DOS (with cygwin1.dll in %PATH, of course).

Danny


Comment 16 Jerry DeLisle 2007-07-23 05:46:27 UTC
I tried my latest updated patch in DOS terminal window as you suggested and it works OK, provided the file name is CONOUT$.  If it is con or CON, I get an error of file already exists.  I will think about that some more.  Maybe we should make it match "con" with case ignored.
Comment 17 Danny Smith 2007-07-23 08:04:15 UTC
(In reply to comment #16)

 Maybe we
> should make it match "con" with case ignored.


No, please. "con", "nul", "prn" (with or without suffix) are reserved device names on windows.  
(eg "gcc -v -dM -E  nul.c" is equivalent  to gcc -v -dM -E  -xc  /dev/null)

CONOUT$ is the win32api name for console output and is used in GUI progs that don't have  default console output.

Danny
Comment 18 Jerry DeLisle 2007-07-25 23:00:41 UTC
More info for everyone.

Under Cygwin, reading and writing from/to /dev/conin$ and /dev/conout$ respectively works fine with gfortran now. (Thanks David Korn for info)

I think this is sufficient for Cygwin.

Under mingw, gfortran has some trouble.  I am still experimenting and testing on mingw which I just got installed on my test machine here.  I should be able to finish this when I get the time free to do it. 
Comment 19 Jerry DeLisle 2007-07-25 23:35:48 UTC
Regarding my comment #18 on cygwin.  There should be no dollar signs in the device name.

Thus:  /dev/conout  and /dev/conin
Comment 20 Danny Smith 2007-07-26 00:34:20 UTC
(In reply to comment #18)
> 
> Under mingw, gfortran has some trouble.  I am still experimenting and testing
> on mingw which I just got installed on my test machine here.  I should be able
> to finish this when I get the time free to do it. 
> 

For complete testing, I suppose you we need to test GUI progs where stdout/stdin/stderr default to bitbuckets,  A windows GUI prog is compiled with "gcc/gfortran  -mwindows ..."
IMO, this is not a critical bug, so don't fritter too much time on it.  
'CONOUT$' etc are  non-portable identifiers that should probably only be used in w32api context.

Danny 


Comment 21 Jerry DeLisle 2007-08-11 15:38:17 UTC
Changing to enhancement.  STANDARD I/O works fine.
Comment 22 Steve Chapel 2007-08-11 15:54:41 UTC
This is *not* an enhancement. It is a *regression* that causes an important application not to work.
Comment 23 Steve Kargl 2007-08-11 16:11:44 UTC
(In reply to comment #22)
> This is *not* an enhancement. It is a *regression* that causes an important
> application not to work.
> 

A regression with respect to what version of gfortran?  A scan of the
audit trail did not reveal the working version.

If the important application is that important, you can always roll
up your sleeves and help fix the problem.
Comment 24 Jerry DeLisle 2007-08-11 17:49:14 UTC
Sorry for the spin up here.  I have a patch ready, still trying to test.
Comment 25 Steve Chapel 2007-08-12 22:45:05 UTC
> A regression with respect to what version of gfortran?  A scan of the
> audit trail did not reveal the working version.

The code above works with gcc 3.4.5.

> If the important application is that important, you can always roll
> up your sleeves and help fix the problem.

I suppose, but I'm just using gcc 3.4.5 for the time being. I actually busy working on cleaning up the Getting Started instructions on the MinGW wiki because most of the people running this application seem to be using gcc 2.95!
Comment 26 pinskia@gmail.com 2007-08-12 23:07:51 UTC
Subject: Re:  [win32] Using 'con' as assigned file generates Fortran runtime error: File 'con' does not exist

On 12 Aug 2007 22:45:07 -0000, steven dot chapel at sbcglobal dot net
<gcc-bugzilla@gcc.gnu.org> wrote:
> The code above works with gcc 3.4.5.

Which means it worked in g77 and not in gfortran (which is new for
4.0.0).  Now we have this weird thing about how gfortran is a new
front-end and g77 was removed.  So this could go either as a
regression or really a new feature.  Also why does this program use
con anyways, shouldn't it just use the default units which are
connected to stdio/stdout anyways as they might not be connected to
the console anyways?

Thanks,
Andrew Pinski
Comment 27 Steve Chapel 2007-08-12 23:23:57 UTC
(In reply to comment #26)
> Which means it worked in g77 and not in gfortran.

I don't know if it never worked in gfortran. Until a few days ago, the only MinGW build of gfortran was a trunk version of 4.3.0. I haven't tested gfortran 4.2.1 or any other version yet.

> Also why does this program use
> con anyways, shouldn't it just use the default units which are
> connected to stdio/stdout anyways as they might not be connected to
> the console anyways?

The program opens a large number of file units, some of them actual files, and one of them 'con'. I believe one of them is also 'nul'. These are defined at one place in the program that you can change (similar to the code in the sample program in the first comment), so that at compile time you can change the names of the files. That's just the way the program is written, and not being the author, I can't reasonably change it all around to use the default units instead.
Comment 28 Steve Chapel 2008-11-17 15:01:08 UTC
I'm changing the summary of this bug report to better indicate the problem that the patch fixes.

Could we get the patch into gfortran 4.5? There is discussion on the NONMEM users mailing list about how to get NONMEM to work with gfortran on Windows, and users are waiting for a resolution to this issue.

Thanks.
Comment 29 Jerry DeLisle 2008-11-18 03:02:20 UTC
Steve, I will try but we also still have the issue of 38122 as well.
Comment 30 Steve Chapel 2008-11-18 12:59:03 UTC
Although bug 38122 causes NONMEM to not run as is, all it takes is a simple one-line change to get it to run normally on Linux.

This bug, on the other hand, makes it effectively impossible to run NONMEM normally on Windows, that is, sending output to the console output.
Comment 31 Jerry DeLisle 2009-04-11 16:45:08 UTC
now that 4.5 branch is alive I will try once again to submit patch for approval.
Comment 32 Steven Bosscher 2009-06-04 12:54:03 UTC
Jerry, was the patch submitted already?
Comment 33 Jerry DeLisle 2009-06-14 00:59:03 UTC
Patch tested on Cygwin and submitted for approval.  Need a tester for mingw.
Comment 34 Jerry DeLisle 2009-07-19 13:43:13 UTC
Cygwin only patch submitted. MingW next.
Comment 35 Jerry DeLisle 2009-07-23 00:59:09 UTC
Subject: Bug 32784

Author: jvdelisle
Date: Thu Jul 23 00:58:46 2009
New Revision: 149970

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=149970
Log:
2009-07-22  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libfortran/32784
	* unix.c (regular_file): Check for CONIN$ CONOUT$, and CONERR$ and open
	the respective /dev/conin or /dev/conout devices.  This is Cygwin
	specific.

Modified:
    trunk/libgfortran/ChangeLog
    trunk/libgfortran/io/unix.c

Comment 36 Jerry DeLisle 2009-08-14 21:10:32 UTC
Subject: Bug 32784

Author: jvdelisle
Date: Fri Aug 14 21:10:06 2009
New Revision: 150779

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=150779
Log:
2009-08-14  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libfortran/32784
	io/unix.c (regular_file): Add support for CONIO on mingw.

Modified:
    trunk/libgfortran/io/unix.c

Comment 37 Jerry DeLisle 2009-08-15 00:50:15 UTC
Fixed on 4.5.