Opening file using PLAIN_TEXT_FILE or RAW_FILE and getting OS error status back 
Author Message
 Opening file using PLAIN_TEXT_FILE or RAW_FILE and getting OS error status back

Okay, I continue to hack on eiffel and love it, when my current project is
done I will post a detailed account of my experience using eiffel for the
first time.

But opening files using IO_MEDIUM, either RAW_FILE or PLAIN_TEXT_FILE has
troubled me. I wish to open a file and if it fails, I want to know why?
Permission problems? File doesn't exist? Etc....

If the open operation fails, the damn thing asserts on me. I am forced to do
a bunch of pre-checks on the filename before attempting the open operation.
And how can I be sure that I have checked every possible error situation?

So my question is: What is ISE's official approach to doing the following:

        fp = fopen("/tmp/blah.txt", "r");
       if ( fp == NULL ) {
             error_code = errno;
       }

Thanks,
    Ken



Sat, 20 Sep 2003 23:22:57 GMT  
 Opening file using PLAIN_TEXT_FILE or RAW_FILE and getting OS error status back

Quote:

> Okay, I continue to hack on eiffel and love it, when my current project is
> done I will post a detailed account of my experience using eiffel for the
> first time.

> But opening files using IO_MEDIUM, either RAW_FILE or PLAIN_TEXT_FILE has
> troubled me. I wish to open a file and if it fails, I want to know why?
> Permission problems? File doesn't exist? Etc....

> If the open operation fails, the damn thing asserts on me. I am forced to do
> a bunch of pre-checks on the filename before attempting the open operation.
> And how can I be sure that I have checked every possible error situation?

> So my question is: What is ISE's official approach to doing the following:

>         fp = fopen("/tmp/blah.txt", "r");
>        if ( fp == NULL ) {
>              error_code = errno;
>        }

It seems there is just one workable way
Check what you need beforehand

Here's an example
indexing
        description: "Answer to question from Ken Stauffer %
    %on comp.lang.eiffel";
        note: "one way how one can do it";
    Date: "2000-04-04"

class
        FILE_READ_TEST

creation

        make

feature -- Initialization

        make is
        do
            Create ptf.make(file_name);
            if ptf.exists then
                if ptf.is_plain then
                    if ptf.is_readable then
                        ptf.open_read;
                    else
                        message_and_exit ("File is not readable, %
                                            %giving up %N", exit_error);
                    end;
                else
                    message_and_exit("not a plain file, giving up%N",
                                     exit_error);
                end
            else
                message_and_exit("File does not exist, cannot %
                                 %proceed %N",exit_error);
            end;
            read_and_print;            
        end;

feature -- some useless work ;-)

    read_and_print is
        local
            line: STRING;
        do
            from ptf.read_line;
            until ptf.end_of_file
            loop
                line := clone(ptf.last_string);
                io.put_string(line);
                io.new_line;
                ptf.read_line;
            end;
        end;

feature {NONE}

    message_and_exit (message: STRING; exit_code: INTEGER) is
        do
            io.error.put_string(message);
            exc.die(exit_code);
        end;

   exc: EXCEPTIONS is
        once
            !!Result;
        end;
    file_name : String is "t1.txt";
    ptf: PLAIN_TEXT_FILE;
    exit_error: INTEGER is 1;

end -- class FILE_READ_TEST

I was thinking to catch errors after you tried the things but that
won't work you can easily try with
make_open_read(file_name).

if the file does not exist you get an operating signal, it seems that
can't be promoted a level higher that you can catch it in your
methods. So in fact make_open_read etc. seem to be pretty useless.

I hope others can prove me wrong. It seems the exception facilities
are not useful enough. Otherwise one could use them. But on the other
hand exceptions should be extraordinary so checking beforehand seems
to be the right way.

Anyway I feel this is a uselessre restriction. I'm not feeling all to
comfortable with the Eiffel exceptions. So probably it's not just me
who feels that way. If you check in the standard libraries you fill
hardly find any exception handling and even less understandable loop
variants and invariants.

But I hope my message clarifies some things

Regards
Friedrich



Sun, 21 Sep 2003 16:15:50 GMT  
 Opening file using PLAIN_TEXT_FILE or RAW_FILE and getting OS error status back

Quote:

> Okay, I continue to hack on eiffel and love it, when my current project is
> done I will post a detailed account of my experience using eiffel for the
> first time.

> But opening files using IO_MEDIUM, either RAW_FILE or PLAIN_TEXT_FILE has
> troubled me. I wish to open a file and if it fails, I want to know why?
> Permission problems? File doesn't exist? Etc....

> If the open operation fails, the damn thing asserts on me. I am forced to do
> a bunch of pre-checks on the filename before attempting the open operation.
> And how can I be sure that I have checked every possible error
> situation?

> Okay, I continue to hack on eiffel and love it, when my current project is
> done I will post a detailed account of my experience using eiffel for the
> first time.

> But opening files using IO_MEDIUM, either RAW_FILE or PLAIN_TEXT_FILE has
> troubled me. I wish to open a file and if it fails, I want to know why?
> Permission problems? File doesn't exist? Etc....

> If the open operation fails, the damn thing asserts on me. I am forced to do
> a bunch of pre-checks on the filename before attempting the open operation.
> And how can I be sure that I have checked every possible error situation?

> So my question is: What is ISE's official approach to doing the following:

>         fp = fopen("/tmp/blah.txt", "r");
>        if ( fp == NULL ) {
>              error_code = errno;
>        }

There are possible some different other way but in general
- Check what you need beforehand
- fix if something is broken

Here's an example for both
indexing
        description: "Answer to question from Ken Stauffer %
    %on comp.lang.eiffel";
        note: "one way how one can do it";
    Date: "2000-04-04"

class
        FILE_READ_TEST

creation

        make, make_with_exception

feature -- Initialization

        make is
        do
            Create ptf.make(file_name);
            if ptf.exists then
                if ptf.is_plain then
                    if ptf.is_readable then
                        ptf.open_read;
                    else
                        message_and_exit ("File is not readable, %
                                            %giving up %N", exit_error);
                    end;
                else
                    message_and_exit("not a plain file, giving up%N",
                                     exit_error);
                end
            else
                message_and_exit("File does not exist, cannot %
                                 %proceed %N",exit_error);
            end;
            read_and_print;            
        end;

    make_with_exception is
        do
            Create ptf.make_open_read(file_name);
            read_and_print;
        rescue
            io.error.put_string("Could not proceed, either the file %
                                 %does not exist, %Nis not readable or %
                                 %not a plain text file%N");
            exc.die(exit_error);
        end;

feature -- some useless work ;-)

    read_and_print is
        local
            line: STRING;
        do
            from ptf.read_line;
            until ptf.end_of_file
            loop
                line := clone(ptf.last_string);
                io.put_string(line);
                io.new_line;
                ptf.read_line;
            end;
        end;

feature {NONE}

    message_and_exit (message: STRING; exit_code: INTEGER) is
        do
            io.error.put_string(message);
            exc.die(exit_code);
        end;

   exc: EXCEPTIONS is
        once
            !!Result;
        end;
    file_name : String is "t1.txt";
    ptf: PLAIN_TEXT_FILE;
    exit_error: INTEGER is 1;

end -- class FILE_READ_TEST

You can see the checks beforehand are somewhat hefty, but usually it
should not come to a suprise that a file you want to open is not there
or is not readable etc.

So although the solutions with exceptons is IMHO more readable I'm not
sure what way to go here.

REMARKS: you must run the program from the command line otherwise
the exception is shown in the IDE. But you like to fall the exception
through and catch it later. The exception I catched here as an example
was an Operating System signal (file not found)

I hope you got the picture

Regards
Friedrich



Sun, 21 Sep 2003 16:43:00 GMT  
 Opening file using PLAIN_TEXT_FILE or RAW_FILE and getting OS error status back

Quote:

>         make is
>         do
>             Create ptf.make(file_name);
>             if ptf.exists then
>                 if ptf.is_plain then
>                     if ptf.is_readable then
>                         ptf.open_read;

Sure, until someone changes the permissions between the time you do
is_readable and open_read.

--
Darren New / Senior MTS & Free Radical / Invisible Worlds Inc.
San Diego, CA, USA (PST).  Cryptokeys on demand.
        schedule.c:7: warning: assignment makes calendar_week
                          from programmer_week without a cast.



Mon, 22 Sep 2003 00:25:42 GMT  
 Opening file using PLAIN_TEXT_FILE or RAW_FILE and getting OS error status back

Quote:

> If the open operation fails, the damn thing asserts on me.

Is it an assertion failure, or a developer exception indicating an I/O
error? If the latter, just use rescue to do whatever is appropriate.

Quote:
> I am forced to do
> a bunch of pre-checks on the filename before attempting the open operation.

That principle doesn't work in general, because of multi-tasking the situation might
change between the check and the action, for example:

  - you check if file exists,
  - another task removes it
  - you open it

(Please don't tell me that "this is unlikely".)

Quote:
> And how can I be sure that I have checked every possible error situation?

Just open it, and afterwards check if it worked out.

AFAIK ISE files are implemented on the POSIX API, so C's errno should
be set.

Just write a C wrapper for errno and strerror(). I can't test it
because I don't use ISE, but it should look something like:

   error_code: INTEGER is
      external
         "C [macro <errno.h>] : EIF_INTEGER"
      alias
         "errno"
      end

   error_details (code: INTEGER): POINTER is
      external
         "C (int): EIF_POINTER | <string.h>"
      alias
         "strerror"
      end

See http://www.eiffel.com/doc/online/eiffel45/papers/externals.html
for some more info. In future, there should be a nicer syntax for
that, but I suppose you want a solution now.

If it doesn't work like that, you might have to write some C to wrap
these functions, compile it manually, and link with the C stuff Eiffel
generates (which is not very funny).

Then you can do something like

   details: STRING

   ...try to open...
   if error_code /= 0 then
      create details.from_external (error_details (error_code))
      io.put_string("cannot read %"file.txt"%": " + details)
      io.put_new_line
   end

No, I don't think this makes sense. It's a stupid workaround, and
Eiffel really *should* provide this information without any hacks.

Regards, Thomas.



Mon, 22 Sep 2003 00:16:09 GMT  
 Opening file using PLAIN_TEXT_FILE or RAW_FILE and getting OS error status back

Quote:


> >         make is
> >         do
> >             Create ptf.make(file_name);
> >             if ptf.exists then
> >                 if ptf.is_plain then
> >                     if ptf.is_readable then
> >                         ptf.open_read;

> Sure, until someone changes the permissions between the time you do
> is_readable and open_read.

you are right that can and will happen. I don't know how likely it is
but alternativly I suggested catching the exception after things wen
wrong.

Regards
Friedrich



Mon, 22 Sep 2003 14:24:27 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. OS/390 Now getting open error on VSAM

2. error 37 File not open using a variable file name

3. Using OS/2 REXX to modify file objects opening menu

4. Problem opening files while using os.path.walk

5. File Status error with VSAM files in IBM Enterprise COBOL V3R2

6. Intermittant Error 37 File Not Open Error on Network

7. Windows XP file access errors (View open error)

8. Status number 39 on opening file

9. Getting error level from OS calls

10. getting error -1073807257 when opening visa

11. error by file read in dll subroutine with in main opened File

12. Issue: file open error on a Novell Netware 4 network file

 

 
Powered by phpBB® Forum Software