// loopget.cpp Vers. 0.50 adapted from mstun.cpp FAC Jan 18 2012 // Compile: g++ -g -Wall loopget.cpp -o loopget // Usage: loopget // Program mterml_sh2 must be running or no response will be received. // Program attaches two shared memory sections and request change/display cmds from user. // See file shmemoryMap.txt shmemoryMap2.txt for list of whats in the shared memories. // // Copyright (C) 2010 F.A. Conle // This file is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the license, or (at // your option) any later version. // This file is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA- // BILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public // License for more details. // You should have received a copy of the GNU General PUblic License along // with this program; if not, write to the Free Software Foundation, Inc., // 59 Temple Place -Suite 330, Boston, MA 02111-1307, USA. Try also their // web site: http://www.gnu.org/copyleft/gpl.html // Jan 18 2012: Fix bug near line 618. was printing wrong v00min, v01min // Jan 15 2011: Place "nchan" in shmem1 and used it to compute a/d transfer buff size. #include #include #include #include #include #include #include //used for sleep() in Linux. ? #include //Linux for sleep() #include //Linux req. exit() #include //Linux req. for strtol() #define MAX_BFILES 511 //sets the number of rotating binary out file names #define BUF_SIZE 1024 //sets the size of the binary out files in 16bit words // MAX_BFILES and BUF_SIZE are also used by sh mem2 buffer nos. and size // There are actually 512 buffs, but the first is used for control stuff. #define SHMSZ 1024 //size of shared memory1 (bytes in Linux). #define SHMSZ2 1048576 //size of shared memory2 // Assuming 8 bit bytes, each buff is 1024*2 bytes // If we use 512 buffers then 1024*2 *512= 1048576 // According to the "ipcs -m" it appears that the shared mem size is // created as a byte argument. int main(int argc, char ** argv ) //argc and argv are not used here. { FILE *lpout; //ascii output file for this prog. char lpoutname[50]; //for defining name of above file FILE *kpout; //ascii output file for cycle request from mstun char kpoutname[50]; //for defining name of above file FILE *envfile; //Read this initilization file char envname[50]; char sentence[100]; //used to read lines from *.env file char *cfield1Ptr; //used to extract the first field from a sentence char *cfield2Ptr; //used to extract other fields int shmid, shmid2; int iret; key_t key; key_t key2; long int *shm, *s; //shared mem address, with s and s2 used as index short int *shm2, *s2; //shared mem address area 1 short int i; //loop index short int iflag; //used to read buff full/empty flags short int isleep; //return value from fn sleep() short int iwordno; //couter for data word no in a buffer short int ibincount; //no. of data pts extracted from bin buffer long int il_bincount; // " short int iupdown; // =0 at start; =1 tensile ramp; =-1 comp. ramp short int ivoltWindow; //only use to read in short int nchan; //no. of a/d chans. Read out of sh mem 1. short int ioldvolts0, ioldvolts1; //values float along with ramp short int inewvolts0, inewvolts1; //values from a/d short int jsaveflag; // =1 save this loop's data; =0 no save, listed in file short int ksaveflag; // =1 save this loop's data; =0 no save, set in mstun short int ihighpeak0, ihighpeak1; //keep previous pk short int ilowpeak0, ilowpeak1; //keep previous comp. pk long int iln; long int il_workBuff; //number of buff being worked on: 1,2,3...MAX_BFILES long int il_delta; //diff between new volts and old volts (a/d ints) long int il_voltWindow; //used to determine reversals long int il_loopnumber; //used to read in loop list long int nl_wantLoops; // counts long int ilbinstoremax; //largest address in a/d transfer buffer. (somewhere near 1024) // is a function of the no. of a/d channels. long int nl_cycleno; // counts cycles. Is the present cycle no. long int il_needCycle[1024]; //storage for cycle list long int jl_needCyclePtr; // pts to active cyc in il_needCycle[] long int jl_nextCycle; //used to check if next cycle needs to be saved long int il_counter; long int il_nextFreeBuff; //extracted from sh mem1 area float v00max, v01max; float v00min, v01min; float v0, v1; float scale2; //multiplier to convert int to +-10Volts float scale1; // " to convert +-10Volts to int float voltWindow, strainIncrement; scale1 = 3276.7; scale2 = 0.000305185; key = 91810; //number just refers to creation date, is a //name for the shared mem segment 1. key2 = 181110; //name for shared mem segment 2. printf("#loopget: Vers. 0.50 Finding shared mem 1...\n"); // Create (find) the segment based on key if ((shmid = shmget(key, SHMSZ, 0666)) < 0) { perror("shmget"); exit(1); } // Attach the segment to our data space. printf("#loopget: Attaching shared mem 1...\n"); // C++ doesnt like the c line: // if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) if ((shm = (long int *)shmat(shmid, 0, 0)) == (long int *) -1) { perror("shmat"); exit(1); } // Check to see if shared mem is ok: // Special contents in shm+2, +3, +4.....+9 iln=3; s=shm; while(1) { s=shm+iln; if (*s != iln) { printf("#loopget: Shared memory1 not attached properly. Content of Loc %li is %li",iln,*s); exit(-1); } iln=iln+1; if(iln == 9) { printf("#loopget: Shared memory 1 looks ok...\n\n"); break; } } // Set up shared mem 2 (This is the binary data buffer area) printf("#Finding shared mem. segment 2...\n"); if ((shmid2 = shmget(key2, SHMSZ2, 0666)) < 0) { perror("shmget"); exit(1); } printf("#Attaching sh mem 2...\n"); if ((shm2 = ( short int *)shmat(shmid2, 0, 0)) == ( short int *) -1) { perror("shmat"); exit(1); } // shm2 should now point to the 1st loc. in sh. mem. segment2 // Check some words in sh mem2 for correct attachment s2=shm2+1020; i = *s2; if(i != 1020) { printf("#loopget: Shared mem2 not attached properly. Content of Loc %i is %i\n",i,*s2); exit(-1); } s2=shm2+1021; i = *s2; if(i != 1021) { printf("#loopget: Shared mem2 not attached properly. Content of Loc %i is %i\n",i,*s2); exit(-1); } s2=shm2+1022; i = *s2; if(i != 1022) { printf("#loopget: Shared mem2 not attached properly. Content of Loc %i is %i\n",i,*s2); exit(-1); } s2=shm2+1023; i = *s2; if(i != 1023) { printf("#loopget: Shared mem2 not attached properly. Content of Loc %i is %i\n",i,*s2); exit(-1); } printf("#loopget: Shared mem 2 looks ok...\n\n"); //Open the ascii output file for loops and max,min writes strcpy(lpoutname, "rawLoopOut.txt\0"); printf("#\n#loopget: Opening file name: %s\n",lpoutname); if ( (lpout = fopen (lpoutname, "w") ) == NULL) { printf("# Error opening %s file. \n",lpoutname); iret = 0; goto CLOSE; } //Open the ascii output file for loop requested by mstun strcpy(kpoutname, "lastLoopOut.txt\0"); printf("#\n#loopget: Test opening file name: %s\n",kpoutname); if ( (kpout = fopen (kpoutname, "w") ) == NULL) { printf("# Error opening %s file. \n",kpoutname); iret = 0; goto CLOSE; } fclose(kpout); printf("#loopget: Test OK. closing file name: %s\n",kpoutname); //Read in the saveLoopList.env file strcpy(envname, "saveLoopList.env\0"); printf("#\n#loopget: Opening envfile name: %s\n",envname); if ( (envfile = fopen (envname, "r") ) == NULL) { printf("# Error opening %s file. \n",envname); iret = 0; goto CLOSE; } //sentence is a char [100] size while (1) { fgets( sentence, 100, envfile ); // fgets needs \n at end of input printf("#loopget: got: %s \n", sentence); cfield1Ptr = strtok (sentence, " "); //fetch 1st field // Note that strcmp(s1,s2) = 0 when s1=s2 if (strcmp ( cfield1Ptr, "#INCREMENT=\0") == 0) { printf("#loopget: Got #INCREMENT= \n"); cfield2Ptr = strtok (NULL, " "); if (cfield2Ptr == NULL ) //then no 2nd field was found { printf ("#loopget: Error: no 2nd field after #INCREMENT=\n"); goto STOP; } sscanf (cfield2Ptr, "%f", &strainIncrement ); printf ("#loopget: Strain Incm. for Loop plots = %f8.5 \n", strainIncrement); fprintf(lpout, "%s\n", sentence); //print so that massage can read it. continue; } if (strcmp (cfield1Ptr, "#VWINDOW=\0") == 0) { //read and save the size of the moving window that determines when // a reversal has occurred. cfield2Ptr = strtok (NULL, " "); if (cfield2Ptr == NULL ) //then no 2nd field was found { printf ("#loopget: Error: no 2nd field after #VWINDOW=\n"); goto STOP; } sscanf (cfield2Ptr, "%f", &voltWindow ); ivoltWindow = (short)(voltWindow * scale1); //convert to 16bits il_voltWindow = (long)ivoltWindow; if (ivoltWindow <= 0) { printf ("#loopget: Error: VWINDOW is -ve number=%f %d\n",voltWindow,ivoltWindow); goto STOP; } printf ("loopget: VoltWindow = %f %d\n",voltWindow,ivoltWindow); continue; } if (strcmp (cfield1Ptr, "#BEGIN=\0") == 0) // It appears that #BEGIN= 0 must have a "0" or other 2nd field on the line { // end of *.env file lines printf ("#loopget: Recognized #BEGIN= in *.env file\n" ); break; } // ignore any comment lines in *.env file } //end of while() for envfile read // The above "break" should place us here // Found a #BEGIN= // Now look for the loop numbers: il_counter=0; //counter for the number of loop in the list while(1) { fgets( sentence, 100, envfile ); // fgets needs \n at end of input printf("#loopget: got: %s \n", sentence); cfield1Ptr = strtok (sentence, " "); //fetch 1st field // Note that strcmp(s1,s2) = 0 when s1=s2 //last line after data should be "#END=..." if (strcmp (cfield1Ptr, "#END=\0") == 0) { printf ("#loopget: Recognized #END= in *.env file.\n" ); break; //jump out of while loop. } // If not #END= must be data sscanf (sentence, "%li",&il_loopnumber ); il_counter = il_counter+1; // Save in looparray il_needCycle[il_counter] = il_loopnumber ; printf ("#loopget: Save %li cycle no.= %li \n",il_counter,il_loopnumber); } if(il_counter == 0) { printf ("#loopget: Error: There were no loops in the saveLoopList.env file.\n"); goto STOP; } fclose(envfile); nl_wantLoops = il_counter; //save the total no. in the list printf("#loopget: Found %li loops in the wanted list.\n",il_counter); s=shm+9; iln= *s; //fetch the number of a/d chans. It will be used to // compute the boundary of the buffer data nchan= (short)iln; printf ("#loopget: Found no. of a/d chans in shmem1 = %i\n",nchan); ilbinstoremax = (long int) ( ( (short int)((BUF_SIZE-7)/nchan) * nchan ) +6 ); printf ("#loopget: Thus: max Buff data address is = %li\n\n", ilbinstoremax); sleep(2); //Figure out where to start checking on filled buffs. // il_nextFreeBuff points to the next buffer to be written to. // In order to find the first buffer that has been filled with data, // scan down the flag list until you find the first "1" This will be // the first data buff to be read by loopget. s=shm+22; il_nextFreeBuff = *s; //begining point iln =il_nextFreeBuff; printf("#lg: il_nextFreeBuff = %li\n",il_nextFreeBuff); while(1) { iln=iln+1; //Next buff if( iln == ( (iln/100)*100 )) printf("#lg: checking buff no. %li\n",iln); if(iln == (MAX_BFILES+1) ) //check for buff flag wrap { iln=1; printf("#lg: Wrap to 1st buff while hunting for full buff...\n"); } s2 = shm2 + iln; iflag = *s2; if(iflag == 1 ) break; // we have found the 1st full buff //keep looking if(iln == il_nextFreeBuff) //we are back at begin. Nothing was in mem { il_workBuff = 0; s=shm+24; *s = il_workBuff; //keep a copy of working buff no. in sh mem 1 sleep(2); //sleep for 2 secs (linux). } //continue looking for a buffer to read } //we have a buffer to work on printf("#lg: Found buff to read: No.= %li\n",iln); il_workBuff = iln; s=shm+24; *s = il_workBuff; //keep a copy of working buff no. in sh mem 1 //assume that this is the begining of a test and that we // are in a flat spot in voltage prior to cycling begin. iupdown=0; jl_needCyclePtr=1; //points to the first cycle to be saved jl_nextCycle = il_needCycle[ jl_needCyclePtr ]; nl_cycleno = 0; //counts the actual cycles found. Count at tensile pks. jsaveflag=0; //shut down the data save flag until we start ramping. ksaveflag=0; //shut down the data save flag until we start ramping. // mterml_sh2 sets this to 0 in shmem 1 upon startup. //Since we have an actual buffer of data, defined by il_workBuff, fetch // the first data point out of it and set the "old" data to it so // that we can detect when a ramp starts. s2 = shm2 + (il_workBuff*BUF_SIZE) + 6; //the first 6 locs of a buffer contain special stuff ioldvolts0 = *s2; ihighpeak0 = ioldvolts0; ilowpeak0 = ioldvolts0; v0= ( (float)ioldvolts0 ) * scale2; s2=s2+1; ioldvolts1 = *s2; ihighpeak1 = ioldvolts1; ilowpeak1 = ioldvolts1; v1= ( (float)ioldvolts1 ) * scale2; printf("#loopget: starts at v0,v1 = %7.3f %7.3f\n", v0, v1); fprintf(lpout, "\n#cycle= 1\n"); printf("\n#lg: cycle= 1 begins...\n"); WORKBUFF: // We need to get the data out of Buff no. = il_workBuff // Create a loop for the data points in this buffer. If iupdown=0 then we are // still hunting for the test to begin. //Note: The 1st 7 words of buffer are not data // [0] = 32767 marker // [1] = -32767 marker // [2] = 0 2 words for block no. // [3] = 1 // [4] = 0 2 words for buffer no. // [5] = 1 // [6] = nwords in this buffer // [7] = dataPt // s2 = shm2 + (il_workBuff*BUF_SIZE); //debug stuff // i=*s2; // printf("#lg: buff loc0= %i, (should be 32768)\n",i); // s2=s2+1; // i=*s2; // printf("#lg: buff loc1= %i, (should be -32768)\n",i); // s2=s2+1; // i=*s2; // printf("#lg: buff loc2= %i, ( 1st half blk no)\n",i); // s2=s2+1; // i=*s2; // printf("#lg: buff loc3= %i, ( 2nd half blk no)\n",i); // s2=s2+1; // i=*s2; // printf("#lg: buff loc4= %i, ( 1st half buf no)\n",i); // s2=s2+1; // i=*s2; // printf("#lg: buff loc5= %i, ( 2nd half buf no)\n",i); s2 = shm2 + (il_workBuff*BUF_SIZE) +6; i=*s2; printf("#lg: buff loc6= %i (should be no. of words used in buff)\n",i); // ibincount=*s2; // printf("#lg: ibinbcount= %i (1 word)\n",ibincount); //print out the counter that is in buffer // il_bincount=*s2; // printf("#lg: il_binbcount= %li (2 word)\n",il_bincount); //print out the counter that is in buffer s2 = shm2 + (il_workBuff*BUF_SIZE) + 6; iwordno=6; //counts how many words have been used in this buff. Used to find eof buff while(1) { s2=s2+1; iwordno=iwordno+1; inewvolts0 = *s2; s2=s2+1; iwordno=iwordno+1; inewvolts1 = *s2; //printf("lgdebug: iv1, iv2 = %i, %i \n",inewvolts0, inewvolts1); //debug //if(iwordno == 50)exit(0); //debug //Cycle counting is done on Chan 0 only // We probably don't need to convert to long, but just in case of huge voltae diff: il_delta = ( (long)inewvolts0 ) - ( (long)ioldvolts0 ); if(iupdown == 0) // We are in a flat spot at begin of test { // No data is saved in a flat spot unless exit occurs //------------------------------------------------------------------ if( il_delta >= il_voltWindow) { //We have test start upwards iupdown = +1; printf ("#loopget: Test starts upwards...\n"); ilowpeak0 = ioldvolts0; //We will count the begining as a Comp. pk ilowpeak1 = ioldvolts1; ioldvolts0 = inewvolts0; ioldvolts1 = inewvolts1; jsaveflag=1; //The first ramp is always saved. Turn on save flag // THe old pt is now part of loop, save it. v00min= ( (float)ioldvolts0 ) * scale2; v01min= ( (float)ioldvolts1 ) * scale2; nl_cycleno = nl_cycleno + 1; //we are now in the first cycle s=shm+25; *s=nl_cycleno; //save the cycle no in shmem 1 fprintf(lpout, "%7.3f %7.3f\n", v00min,v01min); goto GETNEXTPT; } // if not then < window : ignore pt goto GETNEXTPT; if( -il_delta >= il_voltWindow) { //We have test start downwards iupdown = -1; printf ("#loopget: Test starts downwards...\n"); ihighpeak0 = ioldvolts0; //We will count the begining as a Tens. pk ihighpeak1 = ioldvolts1; ioldvolts0 = inewvolts0; ioldvolts1 = inewvolts1; jsaveflag=1; //The first ramp is always saved. Turn on save flag // THe old pt is now part of loop, save it. v00max= ( (float)ioldvolts0 ) * scale2; v01max= ( (float)ioldvolts1 ) * scale2; nl_cycleno = nl_cycleno + 1; //we are now in the first cycle s=shm+25; *s=nl_cycleno; //save the cycle no in shmem 1 fprintf(lpout, "%7.3f %7.3f\n", v00max, v01max ); goto GETNEXTPT; } // if neither of above two conditions, then must be // within +-window. // No change from flat, ignore pt. goto GETNEXTPT; } if(iupdown == +1) // We are on a ramp upwards ------------------------------------- { if( -il_delta >= il_voltWindow) { //We have a drop from peak. Tensile reversal established PEAK PEAK PEAK PEAK v00max =( (float)ioldvolts0 ) * scale2; v01max =( (float)ioldvolts1 ) * scale2; if(jsaveflag == 1 ) { fprintf(lpout, "%7.3f %7.3f\n", v00max, v01max ); // See if next cycle needs to be saved while(1) { jl_needCyclePtr = jl_needCyclePtr +1; jl_nextCycle = il_needCycle[ jl_needCyclePtr ]; //see if next one is actually in future if( jl_nextCycle > nl_cycleno ) break; // if not keep looking in list } } if(ksaveflag == 1) //check to see if "get next cycle" flag was on { // Yes, cycle and save is done, turn off the flag if(jsaveflag == 0 ) { //save also to the big file (but only here if not saved above) fprintf(lpout, "%7.3f %7.3f\n", v00max, v01max ); } fprintf(kpout, "%7.3f %7.3f\n", v00max, v01max ); //save to last loop file fprintf(kpout, "#m %ld %7.3f %7.3f %7.3f %7.3f\n", nl_cycleno, v00min,v01min, v00max,v01max); iln=0; s=shm+26; *s=iln; ksaveflag=0; printf("#lg: save last cycle %li done \n",nl_cycleno); fclose(kpout); printf("#lg: closing mstun get loop file = %s \n",kpoutname); } //See if mstun has set "get next cycle" flag s=shm+26; iln=*s; if(iln == 1) { printf("#lg: mstun request next cycle save.\n"); ksaveflag=1; //Open a special file to save this cycle. Also saved in regular file if ( (kpout = fopen (kpoutname, "w") ) == NULL) { printf("#lg: Error opening %s file. \n",kpoutname); iret = 0; goto CLOSE; } } // This cycle has ended print out the loop tips fprintf(lpout, "#m %ld %7.3f %7.3f %7.3f %7.3f\n", nl_cycleno, v00min,v01min, v00max,v01max); printf("#m %ld %7.3f %7.3f %7.3f %7.3f\n", nl_cycleno, v00min,v01min, v00max,v01max); //Set the oldvolts to the new values ioldvolts0 = inewvolts0; ioldvolts1 = inewvolts1; iupdown = -1; //we are on a down ramp now nl_cycleno = nl_cycleno + 1; //This is the number of the up-coming cycle s=shm+25; *s=nl_cycleno; //save the cycle no in shmem 1 jsaveflag = 0; if( jl_nextCycle == nl_cycleno ) { jsaveflag = 1; //Yes, the new cycle's data needs to be saved fprintf(lpout, "\n#cycle= %li\n", nl_cycleno ); } if(ksaveflag == 1) { fprintf(kpout, "\n#cycle= %li\n", nl_cycleno ); if(jsaveflag == 0) fprintf(lpout, "\n#cycle= %li\n", nl_cycleno ); } goto GETNEXTPT; } // A reversal has not occurred on this tens. ramp. // Check if updates to floating ioldvolts needs to be made. // Also save data if loop is a save if(jsaveflag == 1) { v00max =( (float)ioldvolts0 ) * scale2; v01max =( (float)ioldvolts1 ) * scale2; fprintf(lpout, "%7.3f %7.3f\n", v00max, v01max ); } if(ksaveflag == 1) { if(jsaveflag == 0) { v00max =( (float)ioldvolts0 ) * scale2; v01max =( (float)ioldvolts1 ) * scale2; fprintf(lpout, "%7.3f %7.3f\n", v00max, v01max ); } fprintf(kpout, "%7.3f %7.3f\n", v00max, v01max ); } if(il_delta >= 0) { // voltage has increased even further, or not changed ioldvolts0 = inewvolts0; ioldvolts1 = inewvolts1; goto GETNEXTPT; } //If we get to here il_delta is negative, but less than window //No need to do anything. goto GETNEXTPT; } //end of if(iupdown == +1 //If we get to here, we must have // iupdown == -1 // We are on a ramp downwards ---------------------------------------- if(iupdown != -1) //check to make sure no bad logic above { printf("#loopget: Error at iupdown=-1\n"); goto STOP; } if( il_delta >= il_voltWindow) { //We have a rise from peak comp. compressive reversal established v00min =( (float)ioldvolts0 ) * scale2; v01min =( (float)ioldvolts1 ) * scale2; //Fixed bug here: Jan18 2012 if(jsaveflag == 1) { fprintf(lpout, "%7.3f %7.3f\n", v00min, v01min ); } if(ksaveflag == 1) { if(jsaveflag == 0 ) { fprintf(lpout, "%7.3f %7.3f\n", v00min, v01min ); } fprintf(kpout, "%7.3f %7.3f\n", v00min, v01min ); } //Set the oldvolts to the new values ioldvolts0 = inewvolts0; ioldvolts1 = inewvolts1; iupdown = +1; //we are on a up ramp now goto GETNEXTPT; } // A reversal has not occurred on this Comp. ramp. // Check if updates to floating ioldvolts needs to be made. // Also save data if loop is a save if(jsaveflag == 1) { v00min =( (float)ioldvolts0 ) * scale2; v01min =( (float)ioldvolts1 ) * scale2; fprintf(lpout, "%7.3f %7.3f \n", v00min, v01min ); } if(ksaveflag == 1) { if(jsaveflag == 0 ) { v00min =( (float)ioldvolts0 ) * scale2; v01min =( (float)ioldvolts1 ) * scale2; fprintf(lpout, "%7.3f %7.3f \n", v00min, v01min ); } fprintf(kpout, "%7.3f %7.3f \n", v00min, v01min ); } if(il_delta <= 0) { // voltage has decreased even further, or not changed ioldvolts0 = inewvolts0; ioldvolts1 = inewvolts1; goto GETNEXTPT; } //If we get to here il_delta is positive, but less than window //No need to do anything. goto GETNEXTPT; //end of ( iupdown == -1 ) GETNEXTPT: if(iwordno >= ( ilbinstoremax) ) { //this buff is at an end s2 = shm2 + (il_workBuff * BUF_SIZE ); i=0; *s2 = i; //make the old buff available in list goto GETNEXTBUFF; } } //end of while() that reads the words in the buff //------------------------------------------------------------------------------------------- GETNEXTBUFF: // Get the next buffer (and its 1st pt) // or // Wait for next buffer to be written il_workBuff = il_workBuff+1; if( il_workBuff == (MAX_BFILES+1) ) il_workBuff =1; //back to begining while(1) { //find when next buff is full. The first 1024 locations of shmem2 contain the flags s2=shm2+ il_workBuff; i=*s2; if( i == 1) { //yes it is full s=shm+24; //this goes into sh mem1 so we can see it from mstun *s = il_workBuff; //keep a copy of working buff no. in sh mem 1 printf("#lg: Reading buff no. %li\n", il_workBuff); // for debug goto WORKBUFF; } // No, the buff flag is still 0. Wait and try again isleep = sleep(1); // 1 sec sleep in Linux } CLOSE: printf("# Closing files: rawLoopOut.txt and saveLoopList.env\n"); fclose(lpout); fclose(envfile); fclose(kpout); STOP: printf("#loopget: exits\n"); exit(1); } //end of main()