Message ID | 4C4B8BA3.2070202@verizon.net |
---|---|
State | New |
Headers | show |
Dear Jerry, Dave, and Kai, Dave and Kai: I have CCed you as I have a question regarding MinGW/Cygwin. Jerry DeLisle wrote: > The attach patch uses ttyname to return the device file name for > inquire by unit. > Regression tested on x86-64. > > Test case attached, but the reulst are system dependent so I will not > add it to the testsuite. Kai, Dave: The idea is that INQUIRE returns for stdin, stdout, and stderr a "filename", which can be used to '(re)open' ([re]associate) a Fortran I/O unit number with those standard I/O "streams". (Non normative note in the standard: "the value [for NAME=] returned [by "INQUIRE(UNIT=...,NAME=...)"] shall be suitable for use as the value of the file-name-expr in the FILE= specifier in an OPEN statement.") Under Unix, ttynam should roughly do this, but I fear it might not work under Windows - in particular under MinGW(.org,64). Or does it? Would it be an option to use conout$, conin$ and conerr$ for those? I think on MinGW, libgfortran (io/unix.c) uses them directly (well conerr$ = conout$) while on cygwin those are mapped to /dev/con{in,out,err}. At least for MinGW this seems to be required as Windows does not seem to have a tty concept. For Cygwin the Unix approach should work. > OK for trunk? I think you need to guard the use of ttyname by #ifdef HAVE_TTYNAME ... #else ... #endif Besides, I wonder whether using "" as string is better than using the default std{in,out,err} in case ttyname fails. (This happens for instance if the standard I/O redirected to a file or pipe.) Otherwise, the patch looks fine to me. Tobias > 2010-07-24 Jerry DeLisle <jvdelisle@gcc.gnu.org> > > PR libfortran/44931 > * io/inquire.c (inquire_via_unit): Use ttyname to return actual > device > file name for stdin, stdout, and stderr. If ttyname does not succeed > fall back to default names for these units. Include string.h to allow > using strlen function. > * unix.c: Remove typedef of unix_stream structure, move to unix.h. > * unix.h: Add typedef of unix_stream structure so that it is > accessible to inquire.c.
Tobias Burnus wrote: > Besides, I wonder whether using "" as string is better than using the > default std{in,out,err} in case ttyname fails. (This happens for > instance if the standard I/O redirected to a file or pipe.) For Linux, we could return /proc/self/fd/1 for standard output (0 and 2 correspondingly). This appears to work, as this little program shows: program main implicit none open(unit=10,file='/proc/self/fd/1') write (10,*) 'Hello, world!' end program main Thomas
Thomas Koenig wrote: > Tobias Burnus wrote >> Besides, I wonder whether using "" as string is better than using the >> default std{in,out,err} in case ttyname fails. (This happens for >> instance if the standard I/O redirected to a file or pipe.) >> > For Linux, we could return /proc/self/fd/1 for standard output (0 and 2 > correspondingly). This appears to work, as this little program shows: > Well, I think using /dev/std{in,out,err} is more portable than /proc/self/fd/{0,1,2}. However, the question is whether those device files are just common or truly ubiquitous on non-Windows GCC platforms; I fear they are just common. I have checked the File Hierarchy Standard it it does not specify anything under /dev/*. One could (on non-Windows) of course check the existence of "/dev/std*" and if it does not exist fall back to ttypname and if it also fails (or HAS_TTYNAME is not defined) fall back to "". But the question is whether one should do so much effort - most of the time one simply uses the units without INQUIREing the filename - to (re)open the standard I/O streams. (Side note: The 0,1,2 numbers are defined in POSIX; they are the values of the unistd.h's symbolic constants STD{IN,OUT,ERR}_FILENO.) Tobias
On 25 Jul 2010, at 10:39, Tobias Burnus wrote: > Thomas Koenig wrote: >> Tobias Burnus wrote >>> Besides, I wonder whether using "" as string is better than using >>> the >>> default std{in,out,err} in case ttyname fails. (This happens for >>> instance if the standard I/O redirected to a file or pipe.) >>> >> For Linux, we could return /proc/self/fd/1 for standard output (0 >> and 2 >> correspondingly). This appears to work, as this little program >> shows: >> > > Well, I think using /dev/std{in,out,err} is more portable than > /proc/self/fd/{0,1,2}. FWIW: /dev/std{in,out,err} exist on Darwin /proc does not. cheers, Iain
On 07/25/2010 02:00 AM, Tobias Burnus wrote: > Dear Jerry, Dave, and Kai, > > Dave and Kai: I have CCed you as I have a question regarding MinGW/Cygwin. > > Jerry DeLisle wrote: >> The attach patch uses ttyname to return the device file name for >> inquire by unit. >> Regression tested on x86-64. >> >> Test case attached, but the results are system dependent so I will not >> add it to the testsuite. > > Kai, Dave: The idea is that INQUIRE returns for stdin, stdout, and > stderr a "filename", which can be used to '(re)open' ([re]associate) a > Fortran I/O unit number with those standard I/O "streams". (Non > normative note in the standard: "the value [for NAME=] returned [by > "INQUIRE(UNIT=...,NAME=...)"] shall be suitable for use as the value of > the file-name-expr in the FILE= specifier in an OPEN statement.") > > Under Unix, ttynam should roughly do this, but I fear it might not work > under Windows - in particular under MinGW(.org,64). Or does it? ttynam is supported under Cygwin according to their documentation. I will test it. Regarding mingw-32/64 I will defer to Kai, but it looks like they do from googling. > > Would it be an option to use conout$, conin$ and conerr$ for those? I > think on MinGW, libgfortran (io/unix.c) uses them directly (well conerr$ > = conout$) while on cygwin those are mapped to /dev/con{in,out,err}. At > least for MinGW this seems to be required as Windows does not seem to > have a tty concept. For Cygwin the Unix approach should work. > >> OK for trunk? > > I think you need to guard the use of ttyname by > > #ifdef HAVE_TTYNAME > ... > #else > ... > #endif > > Besides, I wonder whether using "" as string is better than using the > default std{in,out,err} in case ttyname fails. (This happens for > instance if the standard I/O redirected to a file or pipe.) > > Otherwise, the patch looks fine to me. I have guarded it with HAVE_TTYNAME and if not defined we fall back to current gfortran behavior which almost everyone is happy with. I have tested that it works. To me this is the safest way to go initially with this. OK to commit? Jerry
On 25/07/2010 16:31, Jerry DeLisle wrote: > On 07/25/2010 02:00 AM, Tobias Burnus wrote: >> Dear Jerry, Dave, and Kai, >> >> Dave and Kai: I have CCed you as I have a question regarding >> MinGW/Cygwin. Forgot to actually Cc us! >> Jerry DeLisle wrote: >>> The attach patch uses ttyname to return the device file name for >>> inquire by unit. >>> Regression tested on x86-64. >>> >>> Test case attached, but the results are system dependent so I will not >>> add it to the testsuite. >> >> Kai, Dave: The idea is that INQUIRE returns for stdin, stdout, and >> stderr a "filename", which can be used to '(re)open' ([re]associate) a >> Fortran I/O unit number with those standard I/O "streams". (Non >> normative note in the standard: "the value [for NAME=] returned [by >> "INQUIRE(UNIT=...,NAME=...)"] shall be suitable for use as the value of >> the file-name-expr in the FILE= specifier in an OPEN statement.") >> >> Under Unix, ttynam should roughly do this, but I fear it might not work >> under Windows - in particular under MinGW(.org,64). Or does it? > > ttynam is supported under Cygwin according to their documentation. I > will test it. I gave it a quick check, it works, returns "/dev/console" or "/dev/ttyN" depending if you're running in a DOS box or a graphical shell. > Regarding mingw-32/64 I will defer to Kai, but it looks like they do > from googling. Kai Cc'd in. Kai, thread begins at: http://gcc.gnu.org/ml/gcc-patches/2010-07/threads.html#01977 >> Would it be an option to use conout$, conin$ and conerr$ for those? I >> think on MinGW, libgfortran (io/unix.c) uses them directly (well conerr$ >> = conout$) That's how I understand it as well, so it makes a ton of sense to me if those names get used here as well. >> while on cygwin those are mapped to /dev/con{in,out,err}. At >> least for MinGW this seems to be required as Windows does not seem to >> have a tty concept. For Cygwin the Unix approach should work. And if it doesn't, we'll fix it in Cygwin for you :) cheers, DaveK
On Sat, Jul 24, 2010 at 5:56 PM, Jerry DeLisle <jvdelisle@verizon.net> wrote: > Hi Folks, > > The attach patch uses ttyname to return the device file name for inquire by > unit. > > Regression tested on x86-64. > > Test case attached, but the reulst are system dependent so I will not add it > to the testsuite. > > OK for trunk? > > Regards, > > Jerry > > 2010-07-24 Jerry DeLisle <jvdelisle@gcc.gnu.org> > > PR libfortran/44931 > * io/inquire.c (inquire_via_unit): Use ttyname to return actual > device > file name for stdin, stdout, and stderr. If ttyname does not succeed > fall back to default names for these units. Include string.h to allow > using strlen function. > * unix.c: Remove typedef of unix_stream structure, move to unix.h. > * unix.h: Add typedef of unix_stream structure so that it is > accessible to inquire.c. > > This caused: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45131
Index: inquire.c =================================================================== --- inquire.c (revision 162497) +++ inquire.c (working copy) @@ -26,6 +26,7 @@ see the files COPYING3 and COPYING.RUNTIME respect /* Implement the non-IOLENGTH variant of the INQUIRY statement */ +#include <string.h> #include "io.h" #include "unix.h" @@ -66,7 +67,23 @@ inquire_via_unit (st_parameter_inquire *iqp, gfc_u if ((cf & IOPARM_INQUIRE_HAS_NAME) != 0 && u != NULL && u->flags.status != STATUS_SCRATCH) - fstrcpy (iqp->name, iqp->name_len, u->file, u->file_len); + { + if (u->unit_number == options.stdin_unit + || u->unit_number == options.stdout_unit + || u->unit_number == options.stderr_unit) + { + char * tmp = ttyname (((unix_stream *) u->s)->fd); + if (tmp != NULL) + { + int tmplen = strlen (tmp); + fstrcpy (iqp->name, iqp->name_len, tmp, tmplen); + } + else /* If ttyname does not work, go with the default. */ + fstrcpy (iqp->name, iqp->name_len, u->file, u->file_len); + } + else + fstrcpy (iqp->name, iqp->name_len, u->file, u->file_len); + } if ((cf & IOPARM_INQUIRE_HAS_ACCESS) != 0) { Index: unix.c =================================================================== --- unix.c (revision 162497) +++ unix.c (working copy) @@ -135,28 +135,6 @@ typedef struct stat gfstat_t; static const int BUFFER_SIZE = 8192; -typedef struct -{ - stream st; - - gfc_offset buffer_offset; /* File offset of the start of the buffer */ - gfc_offset physical_offset; /* Current physical file offset */ - gfc_offset logical_offset; /* Current logical file offset */ - gfc_offset file_length; /* Length of the file, -1 if not seekable. */ - - char *buffer; /* Pointer to the buffer. */ - int fd; /* The POSIX file descriptor. */ - - int active; /* Length of valid bytes in the buffer */ - - int prot; - int ndirty; /* Dirty bytes starting at buffer_offset */ - - int special_file; /* =1 if the fd refers to a special file */ -} -unix_stream; - - /* fix_fd()-- Given a file descriptor, make sure it is not one of the * standard descriptors, returning a non-standard descriptor. If the * user specifies that system errors should go to standard output, Index: unix.h =================================================================== --- unix.h (revision 162497) +++ unix.h (working copy) @@ -41,6 +41,29 @@ struct stream int (*close) (struct stream *); }; + +typedef struct +{ + stream st; + + gfc_offset buffer_offset; /* File offset of the start of the buffer */ + gfc_offset physical_offset; /* Current physical file offset */ + gfc_offset logical_offset; /* Current logical file offset */ + gfc_offset file_length; /* Length of the file, -1 if not seekable. */ + + char *buffer; /* Pointer to the buffer. */ + int fd; /* The POSIX file descriptor. */ + + int active; /* Length of valid bytes in the buffer */ + + int prot; + int ndirty; /* Dirty bytes starting at buffer_offset */ + + int special_file; /* =1 if the fd refers to a special file */ +} +unix_stream; + + /* Inline functions for doing file I/O given a stream. */ static inline ssize_t sread (stream * s, void * buf, ssize_t nbyte)