open command

Help
Frank
2012-06-18
2012-12-29
  • Frank
    Frank
    2012-06-18

    I tried to use open command to open a file and got error.  Here is my code

    s aug="REWIND:READONLY"
    o filename:@aug:1

    if I just set aug="READONLY" or aug="REWIND", there is no error.  So there must be something wrong with the indirection code.  Can someone help?  Thanks,

     
  • Bob Isch
    Bob Isch
    2012-06-18

    Hi Try,

    When you have more than one device option you need to enclose them in parenthesis.  Try:

    s aug="(REWIND:READONLY)"
    

    while the above should work, you might ALSO want to just use full argument indirection:

    s aug="filename:(REWIND:READONLY):1"
    

    but, that should not be necessary in this case.

    Hope that helps,
    -bob

     
  • Frank
    Frank
    2012-06-18

    that works.  Thanks a lot. 

    BTW, even I checked the "Monitor this" box, I still do not have email when someone replied my topic.  I checked my junk mail folded and did not find it either.

     
  • Frank
    Frank
    2012-06-18

    One more question, I have open command like
       o filename:READONLY:1

    if the file does not exist, it never time out.  Did I miss something?

    Andy

     
  • Frank
    Frank
    2012-06-18

    The previous example was wrong.  Here is what I had

      aug=(READONLY:REWIND:VARIABLE:EXCEPTION="g erropen"):1

      o filename:@aug

    or
       aug=(READONLY:REWIND:VARIABLE:EXCEPTION="g erropen")
     
      o filename:@aug:1

    If the filename does not exist, neither of them time out.  The process just hang there.

     
  • Bob Isch
    Bob Isch
    2012-06-18

    Hi Andy,

    I don't think GT.M will wait for a file to come into existence.  If it does exist, and it cannot be opened for some reason that might be expected to change (someone else has opened it in "write" mode, not permissions or existence though) then GT.M might wait.  However a file not existing or a permission issue would generate an error.

    You should check to see if the file exists before the open, set an error trap before you do the open, or do so with the "exception" device parameter.

    if $zsearch(filename)="" w "File does not exist.",! q
    

    or

    open filename:(REWIND:READONLY:EXCEPTION="g oops")
    ...e.
    oops w "Error opening file.",! q
    

    Let us know if you have any more problems.
    -bob

    P.S. you might want to check the upper right of the page with this tread on it.  Mine says "Stop Monitoring>" and "Stop Watching>" which I assume indicates I'm Monitoring and Watching this topic (or forum maybe).  I'm not real sure how that works these days.  Sourceforge enhanced all that a while back but it seems to work pretty good for me most of the time.

     
  • Bob Isch
    Bob Isch
    2012-06-18

    Well, assuming you are doing something like the following, I get a branch to "erropen" in both cases:

    gtm> zp ^foo
    foo     ;
            d tryopen("foo2.dat")
            q  ;
    tryopen(filename)       ;
            ;
            s zd=$zsearch(filename)
            zwr zd
            ;s aug="(READONLY:REWIND:VARIABLE:EXCEPTION=""g erropen""):1"
            ;zwr aug
            ;o filename:@aug
            s aug="(READONLY:REWIND:VARIABLE:EXCEPTION=""g erropen"")"
            zwr aug
            o filename:@aug:1
            w !
            zwr
            q  ; >>> tryopen
    erropen ;
            w "Error opening file: "_$zstatus,!
            q  ; >>> tryopen
    gtm> d ^foo
    zd=""
    aug="(READONLY:REWIND:VARIABLE:EXCEPTION=""g erropen"")"
    Error opening file: 2,tryopen+9^foo,%SYSTEM-E-ENO2, No such file or directory
    gtm>
    

    Are you seeing something like this?

    -bob

     
  • Frank
    Frank
    2012-06-18

    Thanks a lot Bob.  I tried to create a fopen function that I can use for all future file open operation. 

    Here is my library function code

    fopen(filename,mode,error,timeout,recordsize) n aug
    s aug=$s(mode="R":"READONLY:REWIND",mode="W":"NEWVERSION:NOREADONLY",mode="A":"APPEND:NOREADONLY",1:"")
    i aug="" s error="Invalid Mode" q ""
    s:$g(timeout,0)<1 timeout=1
    s aug=aug_$s($g(recordsize,0)<1:":VARIABLE",1:":FIXED:RECORDSIZE="_+recordsize)
    s aug="("_aug_":EXCEPTION=""g erropen""):"_+timeout
    o filename:@aug
    i '$t s error="Unable to open/create file" q ""
    q filename
    erropen s error="Unable to open/create file" q ""

    Here is the application test code to test the fopen function
    read n fname,str,err,ttl
    s ttl=1,err=""
    s fname="/home/andy/test.txt1"
    s fname=$$fopen(fname,"R",.err)
    f  u fname r str s ttl=ttl+1 u $p q:$zeof  w !,str  q:ttl>10
    c fname
    q

    I know for sure the /home/andy/test.txt1 does not exist on the server.  When I run it, I have to use ctrl-C to stop it.

    GTM>d read^ZIO
    %GTM-I-CTRLC, CTRL_C encountered

     
  • Frank
    Frank
    2012-06-18

    BTW, for your last two response, I got email notification from sourceforge.

     
  • Bob Isch
    Bob Isch
    2012-06-18

    Well…  I copied your code and got the following:

    gtm> zp ^foo1
            ;Here is the application test code to test the fopen function
    read    ;
            n fname,str,err,ttl
            s ttl=1,err=""
            s fname="/home/andy/test.txt1"
            s fname=$$fopen(fname,"R",.err)
            f  u fname r str s ttl=ttl+1 u $p q:$zeof  w !,str q:ttl>10
            c fname
            q
    fopen(filename,mode,error,timeout,recordsize) ;
            n aug
            s aug=$s(mode="R":"READONLY:REWIND",mode="W":"NEWVERSION:NOREADONLY",mode="A":"APPEND:NOREADONLY",1:"")
            i aug="" s error="Invalid Mode" q ""
            s:$g(timeout,0)<1 timeout=1
            s aug=aug_$s($g(recordsize,0)<1:":VARIABLE",1:":FIXED:RECORDSIZE="_+recordsize)
            s aug="("_aug_":EXCEPTION=""g erropen""):"_+timeout
            o filename:@aug
            i '$t s error="Unable to open/create file" q ""
            q filename
    erropen ;
            s error="Unable to open/create file" q ""
    gtm> d ^foo1
    %GTM-I-CTRLC, CTRL_C encountered
    gtm> zshow
    read+5^foo1    (Direct mode)
    midm1+1^midm    (Direct mode)
    gtm> zp @$zpos
            f  u fname r str s ttl=ttl+1 u $p q:$zeof  w !,str q:ttl>10
    gtm> zwr
    err="Unable to open/create file"
    fname=""
    str=""
    ttl=1
    

    This shows a couple of obvious things:

    1) It is "hung" somewhere in the "for loop".  I would expand that out to be multiple lines so you know exactly which command, but it's most likely the READ command if it is hanging.

    2) the value of 'fname' is null ("").  In GT.M if you do a

    USE ""
    

    it will use the primary device.  In other words it is basically the same as a USE 0 or USE $P.

    So, the reason it is hanging is because it is trying to read from the terminal device ("").  Your fopen() function is working just fine in that it is returning the error condition as intended.  However, you are not checking it.

    A couple of other "code critiques":

    a) You are checking $ZEOF after you do the USE $P.  You need to do that before the USE $P or while you are still referencing the file.
    b) If you continue to use the timeout, especially conditionally, you will want to be careful with your check of $TEST afterwards.  If you do not have a timeout in 'aug' $TEST will not be set.
    c) Your EXCEPTION may also be executed during READs after the file is open, in which case QUIT "" is not going to make sense among other stuff.  It might also interact with your $ZEOF checks.

    Best of luck,
    -bob

     
  • Frank
    Frank
    2012-06-18

    Thank you so much!

     
  • Frank
    Frank
    2012-06-19

    Bob, do you know how I can set up the Exception only for the fopen function?  After that, it uses the error handling function whatever is set at the calling function.  Also is there some good sample code for the open, read, write and close function for file operation?  Thanks