BookmarkSubscribeRSS Feed
sspkmnd
Obsidian | Level 7

Greetings.

 

This post is actually a solution to a problem. I can't find any appropriate information about this issue, so it may be helpful for someone in the future.

 

I was doing a file reading stuff using FDB and caught the issue which I couldn't find a way to solve. But in the end, I figured out that the issue was with FILENAME function, specifically with the length of a variable which I was passing to the second argument - filename. 

 

Affected SAS version and systems:

 

  1. SAS 9.2 Unix HP UX. &SYSLONG4=9.02.02M3P04132010, &SYSSCP=HP IPF.
    Error reference rc=-20009 WARNING: Truncated record.
  2. SAS 9.2 Linux. &SYSLONG4=9.02.02M3P04132010, &SYSSCP=LIN X64.
    Error reference rc=20026 ERROR: Undetermined I/O failure.

My task was to open a file using FOPEN, then read the file till the end of file (EOF) and then assign the pointer to the beginning of the file (basically, reopen the file) using FREWIND function and read it again. Since I was working on Unix, I assumed the maximum possible path coming from an external source has 4096 length (which is considered as the programmatic limit for Unix/Linux). And that was a huge mistake and made me spend around 1 day of debugging. So, the file reading was ok, but at the end of the file I was getting the return code -20009 or 20026 (depending on the system, see affected sas version list) instead of expected rc=-1 WARNING: End of file. And the problem was that FREWIND doesn't work. Later I identified that the issue was with the variable length where I stored the path, so when I declared a file reference using FILENAME function I did that in a next way:

 

length fileref $8 filepath $4096;
fileref = "fref1";
filepath = "&file";
rc = filename(fileref, filepath);

And everything was ok, no issues in return code, no errors or warnings. But as I said issues were when I reached the end of a file. As I identified afterward you must use a variable with the length no-longer than 1025 (1026 doesn't work). Also, I couldn't find any notes in SAS Documentation about this.

 

Interesting note, that on SAS 9.4 Linux everything works fine, and you can even use a variable with the length more than 4096.

 

The code to reproduce the issue (change the file parameter to an arbitrary textfile in your system)

 

%macro _frewind(l, file=/etc/passwd);
    %macro __report(msg=%str(Unseccessfully));
        if rc=0 then do;
            put 'DBG: Successfully';
        end;
        else do;
            msg = sysmsg();
            put "ERR" "OR: &msg: rc=" rc 'message=' msg;
        end;
    %mend;
    
    data debug_&l;
        length v $32767;

        length fileref $8 filepath $&l;

        fileref = "fref1";
        filepath = "&file";
        put 'DBG: Trying to assign a fileref';
        rc = filename(fileref, filepath);
        %__report;
        put 'DBG: Trying to open the file';
        fileid = fopen(fileref);
        %__report;

        put 'DBG: READ file with path 1025 length';

        length v $32767;
        
        counter = 0;
        do while (rc ne -1 and counter < 10);
           /* Read a record. */
           rc=fread(fileid);
           select(rc);
               when(0) do;
                   put 'DBG: Observation was read successfully';
                   rc = fget(fileid, v, 32767);
               end;
               when(-1) do;
                   put 'DBG: End of file reached';
               end;
               otherwise do;
                   %__report(msg=Error upon attempt to read the file)
                   counter = counter + 1;
               end;
           end;
           output;
        end;

        put 'DBG: Trying to reposition the pointer at the beginning of the file';
        if rc= -1  then rc=frewind(fileid);
        %__report;
        put 'DBG: Read the first record';
        rc=fread(fileid);
        %__report;
        rc=fget(fileid,v,32767);
        %__report;
        put 'DBG: Trying to close the file';
        rc=fclose(fileid);
        %__report;
        put 'DBG: Trying to deassign the fileref';
        rc=filename(fileref,'');
        %__report;
    run;    
%mend _frewind;

/* 1025 length works */
%_frewind(1025)
/*! 1026 length does not work */
%_frewind(1026)

Kind regards,
Igor

 

 

 

2 REPLIES 2
ChrisNZ
Tourmaline | Level 20

You could contact tech support so that they create a Usage Note and check that all is fine on all 9.4 plaforms.

Tom
Super User Tom
Super User

I cannot get it to fail using SAS 9.4, even if I use a variable defined longer than $4096.

SAS version 9.2 is over 7 years old.  http://blogs.sas.com/content/iml/2013/08/02/how-old-is-your-version-of-sas-release-dates-for-sas-sof...

Perhaps it is time to switch to a more recent version of SAS?

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 2 replies
  • 969 views
  • 0 likes
  • 3 in conversation