Example of z/OS UNIX file system I/O functions

This section contains examples that demonstrate different uses of z/OS® UNIX I/O file system functions

Figure 1 is example code (CCNGHF3) that demonstrates the use of z/OS UNIX stream input/output by writing streams to a file, reading the input lines, and replacing a line.

Figure 1. Example of z/OS UNIX stream input and output functions
/* this example uses HFS stream I/O */

#define _OPEN_SYS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#undef _OPEN_SYS
FILE *stream;

char string1[] = "A line of text.";   /* NOTE: There are actually 16 */
char string2[] = "Find this line.";   /*   characters in each line of */
char string3[] = "Another stream.";   /*   text.  The 16th is a null  */
char string4[16];                     /*   terminator on each string. */
long position, strpos;                /*   Since the null character   */
int i, result, fd;                    /*   is not being written to    */
int rc;                               /*   the file, 15 is used as    */
                                      /*   the data stream length.    */
ssize_t x;
char buffer[16];
int main(void)
{

   /* Write continuous streams to file  */

   if ((stream = fopen("./myfile.data","wb"))==NULL) {
         perror("Error opening file");
         exit(0);
   }

   for(i=0; i<12;i++) {
      int len1 = strlen(string1);
      rc = fwrite(string1, 1, len1, stream);
      if (rc != len1) {
         perror("fwrite failed");
         printf("i = %d\n", i);
         exit(99);
      }
   }
   rc = fwrite(string2,1,sizeof(string2)-1,stream);

   if (rc != sizeof(string2)-1) {
      perror("fwrite failed");
      exit(99);
   }

   for(i=0;i<12;i++) {
      rc = fwrite(string1,1,sizeof(string1)-1,stream);

      if (rc != sizeof(string1)-1) {
         perror("fwrite failed");
         printf("i = %d\n", i);
         exit(99);
      }
   }
   fclose(stream);
   /* Read data stream and search for location of string2.        */
   /* EOF is not set until an attempt is made to read past the    */
   /* end-of-file, thus the fread is at the end of the while loop */

   stream = fopen("./myfile.data", "rb");

   if ((position = ftell(stream)) == -1L)
      perror("Error saving file position.");
   rc = fread(string4, 1, sizeof(string2)-1, stream);
   while(!feof(stream)) {
      if (rc != sizeof(string2)-1) {
         perror("fread failed");
         exit(99);
      }

      if (strstr(string4,string2) != NULL)   /* If string2 is found */
         strpos = position ;                 /* then save position. */

      if ((position=ftell(stream)) == -1L)
         perror("Error saving file position.");
      rc = fread(string4, 1, sizeof(string2)-1, stream);
   }

   fclose(stream);
   /* Replace line containing string2 with string3 */

   fd = open("test.data",O_RDWR);

   if (fd < 0){
     perror("open failed\n");
   }

   x = write(fd,"a record",8);

   if (x < 8){
     perror("write failed\n");
   }

   rc = lseek(fd,0,SEEK_SET);
   x = read(fd,buffer,8);

   if (x < 8){
     perror("read failed\n");
   }
   printf("data read is %.8s\n",buffer);

   close(fd);
}

To use 64-bit offset and file sizes, you must make the following changes in your code:

  1. Change any variables used for offsets in fseek() or ftell() that are int or long to the off_t data type.
  2. Define the _LARGE_FILES 1 feature test macro.
  3. Replace fseek()/ftell() with fseeko()/ftello(). See z/OS XL C/C++ Runtime Library Reference for descriptions of these functions.
  4. Compile with the LANGLVL(LONGLONG) compiler option.
Notes:
  1. These changes are compatible with your older files.
  2. Large Files support (64–bit offset and file sizes) is automatic in the LP64 programming model that is used in 64–bit. The long data type is widened to 64–bits. This enables fseek() and ftell() to work with the larger offsets with no code change. The fseeko() and ftello() functions also work with 64–bit offsets since off_t is typedef'd as a long int.

The example program (CCNGHF4) in Figure 2 provides the same function as CCNGHF3, but it uses 64-bit offsets. The changed lines are marked in a bold font.

Figure 2. Example of HFS stream input and output functions
/* this example uses HFS stream I/O and 64-bit offsets*/

#define _OPEN_SYS
#define _LARGE_FILES 1 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#undef _OPEN_SYS
FILE *stream;

char string1[] = "A line of text.";   /* NOTE: There are actually 16 */
char string2[] = "Find this line.";   /*   characters in each line of */
char string3[] = "Another stream.";   /*   text.  The 16th is a null  */
char string4[16];                     /*   terminator on each string. */
off_t position,strpos;                /*   Since the null character   */
int i, result, fd;                    /*   is not being written to    */
int rc;                               /*   the file, 15 is used as    */
                                      /*   the data stream length.    */
ssize_t x;
char buffer[16];

int main(void)
{

   /* Write continuous streams to file  */

   if ((stream = fopen("./myfile.data","wb"))==NULL) {
         perror("Error opening file");
         exit(0);
   }

   for(i=0; i<12;i++) {
      int len1 = strlen(string1);
      rc = fwrite(string1, 1, len1, stream);
      if (rc != len1) {
         perror("fwrite failed");
         printf("i = %d\n", i);
         exit(99);
      }
   }
   rc = fwrite(string2,1,sizeof(string2)-1,stream);

   if (rc != sizeof(string2)-1) {
      perror("fwrite failed");
      exit(99);
   }

   for(i=0;i<12;i++) {
      rc = fwrite(string1,1,sizeof(string1)-1,stream);

      if (rc != sizeof(string1)-1) {
         perror("fwrite failed");
         printf("i = %d\n", i);
         exit(99);
      }
   }
   fclose(stream);
   /* Read data stream and search for location of string2.        */
   /* EOF is not set until an attempt is made to read past the    */
   /* end-of-file, thus the fread is at the end of the while loop */

   stream = fopen("./myfile.data", "rb");

   if ((position=ftello(stream)) == -1LL)
      perror("Error saving file position.");

   rc = fread(string4, 1, sizeof(string2)-1, stream);

   while(!feof(stream)) {
      if (rc != sizeof(string2)-1) {
         perror("fread failed");
         exit(99);
      }

      if (strstr(string4,string2) != NULL)   /* If string2 is found */
         strpos = position ;                 /* then save position. */

      if ((position=ftello(stream)) == -1LL)
         perror("Error saving file position.");

      rc = fread(string4, 1, sizeof(string2)-1, stream);
   }

   fclose(stream);
   /* Replace line containing string2 with string3 */

   fd = open("test.data",O_RDWR);

   if (fd < 0){
     perror("open failed\n");
   }

   x = write(fd,"a record",8);

   if (x < 8){
     perror("write failed\n");
   }
  strpos = lseek(fd,0LL,SEEK_SET);    /* Note off_t is 64bits with _LARGE_FILES */
                                      /*   set and the off_t variable    */
                                      /*   needs a 64bit constant of 0LL */
   x = read(fd,buffer,8);

   if (x < 8){
     perror("read failed\n");
   }
   printf("data read is %.8s\n",buffer);

   close(fd);
}