ch2-tempfile

Chapter_2     client assert







tempfile.c     ALP, p. 36-37


#include <stdio.h> // for printf(), fprintf(), stderr, NULL, FILE,
// fread(), fwrite(), SEEK_SET, fseek(), fclose(), tmpfile(), size_t
/*
stdio.h includes stddef.h, which defines size_t:
/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h:
#define __SIZE_TYPE__ long unsigned int
typedef __SIZE_TYPE__ size_t
typedef long ssize_t
*/
// stdlib.h, string.h, and unistd.h also include stddef.h
#include <stdlib.h> // for malloc(), free(), mkstemp(), exit()
#include <string.h> // for strlen()
#include <unistd.h> // for read(), write(), lseek(), close(), unlink()

#define MAXWORD 100 // max word length

// high level operations
FILE * fwrite_tempfile (char *buffer, size_t length);
char * fread_tempfile (FILE *fp, size_t *length);

// low level operations
int write_tempfile (char *buffer, size_t length);
char * read_tempfile (int fd, size_t *length);

int main()
{
char word[MAXWORD];
size_t len; // word length

printf("Type a word: ");
scanf("%s", word);
len = strlen(word);

FILE *fp;
char *buf; // buffer
size_t length; // returned length
fp = fwrite_tempfile(word, len+1); // +1 for ending '\0'
buf = fread_tempfile(fp, &length);
printf("You typed: \"%s\", length: %lu\n", buf, length-1);

int fd; // file descriptor for temporary file
fd = write_tempfile(word, len+1); // +1 for ending '\0'
buf = read_tempfile(fd, &length);
printf("You typed: \"%s\", length: %lu\n", buf, length-1);

free(buf);

return 0;
}
/* Writes `length' bytes from `buffer' into a temporary file.
The temporary file will be deleted automatically at the end
of the program. Returns a handle (FILE *) to the temporary file. */
FILE * fwrite_tempfile (char* buffer, size_t length)
{
FILE *fp = tmpfile();
/* Write the number of bytes to the file first: */
fwrite (&length, sizeof(length), 1, fp); // sizeof(byte) == 1 byte
/* Now write the data itself: */
fwrite (buffer, length, sizeof(char), fp);
/* Use the file pointer as the handle for the temporary file: */
return fp;
}
/* Reads the contents of a temporary file with file pointer `fp'
created with write_tempfile(). The return value is a newly allocated
buffer of those contents, which the caller must deallocate with free.
*length is set to the size of the contents, in bytes.
The temporary file is removed at the end. */
char * fread_tempfile (FILE *fp, size_t *length)
{ // should check if fp != NULL
char *buffer;
/* Rewind to the beginning of the file: */
fseek (fp, 0, SEEK_SET);
/* Read the size of the data from the temporary file: */
fread (length, sizeof(*length), 1, fp); // sizeof(byte) == 1 byte
/* Allocate a buffer and read the data. */
buffer = (char*) malloc (*length);
if (buffer == NULL)
{
fprintf(stderr, "fread_tempfile: could not allocate buffer\n");
exit(1); // end program, signalling error
}
// else
fread (buffer, *length, sizeof(char), fp);
/* Close the file, which will cause the temporary file to go away: */
fclose(fp); // temporary file will be deleted automatically
// at the end of the program
return buffer;
}

/* Writes `length' bytes from `buffer' into a temporary file.
The temporary file is immediately unlinked.
Returns a handle (file descriptor) to the temporary file. */
int write_tempfile (char *buffer, size_t length)
{
/* Create the filename and file. The XXXXXX will be replaced with
characters that make the filename unique. */
char temp_filename[] = "/tmp/temp_file.XXXXXX";
int fd = mkstemp(temp_filename);
/* Unlink the file immediately, so that it will be removed when the
file descriptor is closed: */
unlink (temp_filename);
/* Write the number of bytes to the file first: */
write (fd, &length, sizeof(length));
/* Now write the data itself: */
write (fd, buffer, length);
/* Use the file descriptor as the handle for the temporary file: */
return fd;
}
/* Reads the contents of a temporary file with file descriptor `fd'
created with write_tempfile(). The return value is a newly allocated
buffer of those contents, which the caller must deallocate with free().
*length is set to the size of the contents, in bytes.
The temporary file is removed at the end. */
char * read_tempfile (int fd, size_t *length)
{ // should check if fd >= 0
char* buffer;
lseek (fd, 0, SEEK_SET); // Rewind to the beginning of the file
/* Read the size (length) of the data from the temporary file: */
read (fd, length, sizeof(*length));
/* Allocate a buffer and read the data: */
buffer = (char*) malloc(*length);
if (buffer == NULL)
{
fprintf(stderr, "read_tempfile: could not allocate buffer\n");
exit(1); // end program, signalling error
}
// else
read(fd, buffer, *length);
close(fd); // close file descriptor, removing temporary file

return buffer;
}

/*
gcc tempfile.c -o tempfile
./tempfile
Type a word: Hello!
You typed: "Hello!", length: 6
You typed: "Hello!", length: 6
*/









Chapter_2     client BACK_TO_TOP assert



Comments

Popular posts from this blog

Contents