I'm having trouble using read(), write(), and open() to copy a file into a new directory. I'm able to create a new file with open() and I'm able to write to the terminal with write() but I was under the assumption that if I passed my int file descriptor from open to write, write would write to the specified file.
In addition to this, once I open a file the permissions are all funky and I can only open it as root. Each time I create a file, it's completely empty but I can see the entire file I just read be printed out in the terminal.
I've read through the man files for each system call but I'm still not grasping what the issue is here.
Here's my code:
void *scanFile( s_request *request )
{
//TODO Print out all struct variables.
pthread_mutex_lock(&mutex);
int readFileReference;
int writeFileReference;
int bufferSize = request->bufferSize;
int numberOfBytesRead = bufferSize;
int *buffer[bufferSize];
if ((readFileReference = open(request->file, O_RDONLY)) == -1)
{
printf("Failed to open file. Aborting.\n");
exit(EXIT_FAILURE);
}
if ((writeFileReference = open("newfile.txt", O_CREAT | O_APPEND | O_RDWR) == -1))
{
printf("Failed to open write file. Aborting.\n");
exit(EXIT_FAILURE);
}
while ((read(readFileReference, buffer, numberOfBytesRead)) != 0)
{
write(writeFileReference, buffer, bufferSize);
bzero(buffer, bufferSize);
}
pthread_mutex_unlock(&mutex);
}
Fixed the issue:
Updated code:
void *scanFile( s_request *request )
{
//TODO Print out all struct variables.
pthread_mutex_lock(&mutex);
int readFileReference;
int writeFileReference;
int bufferSize = request->bufferSize;
int numberOfBytesRead = bufferSize;
int *buffer[bufferSize];
if ((readFileReference = open(request->file, O_RDONLY)) == -1)
{
printf("Failed to open file. Aborting.\n");
exit(EXIT_FAILURE);
}
if ((writeFileReference = open("newfile.txt", O_CREAT | O_WRONLY, 0777)) == -1)
{
printf("Failed to open write file. Aborting.\n");
exit(EXIT_FAILURE);
}
while ((read(readFileReference, buffer, numberOfBytesRead)) != 0)
{
write(writeFileReference, buffer, bufferSize);
bzero(buffer, bufferSize);
}
close(writeFileReference);
close(readFileReference);
pthread_mutex_unlock(&mutex);
}
if ((writeFileReference = open("newfile.txt", O_CREAT | O_APPEND | O_RDWR) == -1))
You've got the parentheses wrong on this line. (It's correct on the readFileReference line.) What you want is:
if ((writeFileReference = open("newfile.txt", O_CREAT | O_APPEND | O_RDWR)) == -1)
^^^ ^^^
Your original version of that line was calling open(), performing a comparison to -1, then assigning the result of that comparison to writeFileReference.
Additionally:
As noted by Zan Lynx in a comment, you need to pass a permissions value to open() when creating a file. 0666 is typically correct -- it'll create the file as readable/writable. (It's modified by the process umask, so it'll end up creating the file as 0644 under a typical configuration.)
You need to save the return value from read somewhere and pass that as the third argument to write (instead of bufferSize). Otherwise, your program will write more bytes than were read, e.g. when copying small files.
Technically, you should be checking the return value from write(). Just like read(), it's not guaranteed to complete a full write every time it's called. (In practice, when working with regular files, it will always either complete the write or return an error, but there are some esoteric situations where this may not be the case.)
You don't need to bzero() the buffer after writing from it.
Related
I want to redirect the output to a specific file when the program encounters a ">" and for it to get the input from a file if it finds a "<".
This works for the input, but when I try the output to file it doesn't write anything in the actual file nor does it show it in the terminal.
I can't seem to figure out why, can anyone help?
switch(fork()){
case 0:
for(i=0; i<num; i++){
if(strcmp(argv[i], ">") == 0){
if(fd1 = open(argv[i+1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR) < 0){
perror("cant open file");
exit(0);
}
dup2(fd1, 1);
close(fd1);
argv[i] = NULL;
}
if(strcmp(argv[i], "<") == 0){
if(fd0 = open(argv[i+1], O_RDONLY) < 0){
perror("cant open file");
exit(0);
}
dup2(fd0, 0);
close(fd0);
}
}
execvp(argv[0], argv);
The primary problem is that the = operator has lower precedence than the < operator. Thus, in your expression
fd1 = open(argv[i+1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR) < 0
, the return value of open() is compared to 0, and then the result of that comparison -- either 1 or 0 -- is assigned to fd1. The newly-opened file descriptor is lost, and goes unused. The actual result of the comparison is most likely 0 (the file was successfully opened), so your dup2() call a few lines later attempts to dupe file descriptor 0 onto file descriptor 1. In all likelihood that works, but any attempt by the program you exec to write to that file descriptor very likely fails.
You ought to write it as
(fd1 = open(argv[i+1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0
Alternatively, be a little less clever and separate that into two statements, so that the precedence question does not arise in the first place.
You have the same problem when you redirect input, so I'm doubtful of your claim that "This works for the input", but because in that case you'll end up just duping file descriptor 0 onto itself, the problem will manifest simply as the redirection not working as expected -- input will still come from the original program's standard input, not the standard input you designate.
Even that might go unnoticed, however, if you allow the shell to perform the input redirection instead of quoting the redirection operator so as to get it through to the program as an argument.
i've been trying to redirect the output to a file and reading from file instead of stdin by using a function, but it doesnt seem to be working as when i redirect into a file and check to see if a file has been created with the output there is nothing there. what could be wrong with this function.
/* Redirect a standard I/O file descriptor to a file
* Arguments: filename the file to/from which the standard I/O file
* descriptor should be redirected
* flags indicates whether the file should be opened for reading
* or writing
* destfd the standard I/O file descriptor which shall be
* redirected
* Returns: -1 on error, else destfd
*/
int redirect(char *filename, int flags, int destfd){
int ret;
if(flags == 0){
destfd = open(filename,O_RDONLY);
if (destfd < 0){
return -1;
}
ret = dup2(0,destfd);
if(ret < 0){
return -1;
}
close(destfd);
}
if(flags == 1){
destfd = open(filename,O_APPEND|O_WRONLY);
if (destfd < 0){
return -1;
}
ret = dup2(destfd,1);
if(ret < 0){
return -1;
}
close(destfd);
}
return destfd;
}
There are several problems with your code, not least of which the really awful formatting which make it very hard to read.
For example this call to dup2 is backwards - it's replacing the recently opened destfd with a copy of stdin.
ret = dup2(0,destfd);
a then a few lines later you close destfd.
Your if statements could benefit from you learning about else and else if
if(flags == 0) {
// code
} else if(flags == 1) {
// code
}
Really though you could simplify the whole function by treating the flags parameter as the same flags you'd pass to open and have destfd as the file descriptor you want to replace.
int redirect(char *filename,int flags, int destfd)
{
int fd;
fd=open(filename,flags,S_IRUSR|S_IWUSR);
if(fd!=-1)
{
if(dup2(fd,destfd)==-1)
{
close(fd);
fd=-1;
}
else
{
close(fd);
}
}
return fd;
}
Then you could call it like
redirect("output.txt",O_CREAT|O_WRONLY,1); // Redirect stdout
redirect("input.txt",O_RDONLY,0); // Redirect stdin
The os function dup2() should provide what you need (if not references to exactly what you need).
More specifically, you can dup2() the stdin file descriptor to another file descriptor, do other stuff with stdin, and then copy it back when you want.
The dup() function duplicates an open file descriptor. Specifically, it provides an alternate interface to the service provided by the fcntl() function using the F_DUPFD constant command value, with 0 for its third argument. The duplicated file descriptor shares any locks with the original.
On success, dup() returns a new file descriptor that has the following in common with the original:
Same open file (or pipe)
Same file pointer (both file descriptors share one file pointer)
Same access mode (read, write, or read/write)
Everything I said can be found on the manpage of dup
I have been looking int the man 3 tcgetattr (as I want to change the terminal settings in a program) and found this.
int tcgetattr(int fd, struct termios *termios_p);
int tcsetattr(int fd, int optional_actions,
const struct termios *termios_p);
Question:
I would like to know what fd should mean? (it seems to be stdin, yet I do not understand why)?
Background
My comprehension is that terminal is input and output together, as my understanding was that a /dev/tty or /dev/pty yields stdin, stdout and stderr together.
fd stands for file descriptor, which is a reference to an OS file object. Because it is a reference, multiple different file descriptors may refer to the same file object.
stdin, stdout, and stderr are FILE * objects -- actual pointers to stdio FILE datastructures. You can get the file descriptor that refers to the underlying OS object with the fileno function.
So there's two levels of indirection going on here. The FILE * could all refer to the same FILE, but they don't; there are 3 separate FILE objects for stdin, stdout, and stderr. These FILE objects each contain a file descriptor, normally 0, 1 and 2 (I say normally -- the OS/lib sets them up this way and they'll only change if you explicitly change them in your program). The 3 file descriptors will then normally all refer to the same underlying OS object, which is a single terminal object.
Since there's (generally) only one terminal, and all these file descriptors (usually) refer to it, it doesn't matter which fd (0, 1, or 2) you use as the first argument to tcsetaddr.
Note that it is possible for these fds to refer to different objects -- if you start your program with redirections (< or > in the shell) then one or more of them will refer to some other file object and not the terminal.
To simplify Thomas Dickey's and Chris Dodd's answers, the typical code to select which descriptor is used to refer to the terminal is
int ttyfd;
/* Check standard error, output, and input, in that order. */
if (isatty(fileno(stderr)))
ttyfd = fileno(stderr);
else
if (isatty(fileno(stdout)))
ttyfd = fileno(stdout);
else
if (isatty(fileno(stdin)))
ttyfd = fileno(stdin);
else
ttyfd = -1; /* No terminal; redirecting to/from files. */
If your application insists on having access to the controlling terminal (the terminal the user used to execute this process), if there is one, you can use the following new_terminal_descriptor() function. For simplicity, I'll embed it in an example program:
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
int new_terminal_descriptor(void)
{
/* Technically, the size of this buffer should be
* MAX( L_ctermid + 1, sysconf(_SC_TTY_NAME_MAX) )
* but 256 is a safe size in practice. */
char buffer[256], *path;
int fd;
if (isatty(fileno(stderr)))
if (!ttyname_r(fileno(stderr), buffer, sizeof buffer)) {
do {
fd = open(path, O_RDWR | O_NOCTTY);
} while (fd == -1 && errno == EINTR);
if (fd != -1)
return fd;
}
if (isatty(fileno(stdout)))
if (!ttyname_r(fileno(stdout), buffer, sizeof buffer)) {
do {
fd = open(path, O_RDWR | O_NOCTTY);
} while (fd == -1 && errno == EINTR);
if (fd != -1)
return fd;
}
if (isatty(fileno(stdin)))
if (!ttyname_r(fileno(stdin), buffer, sizeof buffer)) {
do {
fd = open(path, O_RDWR | O_NOCTTY);
} while (fd == -1 && errno == EINTR);
if (fd != -1)
return fd;
}
buffer[0] = '\0';
path = ctermid(buffer);
if (path && *path) {
do {
fd = open(path, O_RDWR | O_NOCTTY);
} while (fd == -1 && errno == EINTR);
if (fd != -1)
return fd;
}
/* No terminal. */
errno = ENOTTY;
return -1;
}
static void wrstr(const int fd, const char *const msg)
{
const char *p = msg;
const char *const q = msg + ((msg) ? strlen(msg) : 0);
while (p < q) {
ssize_t n = write(fd, p, (size_t)(q - p));
if (n > (ssize_t)0)
p += n;
else
if (n != (ssize_t)-1)
return;
else
if (errno != EINTR)
return;
}
}
int main(void)
{
int ttyfd;
ttyfd = new_terminal_descriptor();
if (ttyfd == -1)
return EXIT_FAILURE;
/* Let's close the standard streams,
* just to show we're not using them
* for anything anymore. */
fclose(stdin);
fclose(stdout);
fclose(stderr);
/* Print a hello message directly to the terminal. */
wrstr(ttyfd, "\033[1;32mHello!\033[0m\n");
return EXIT_SUCCESS;
}
The wrstr() function is just a helper function, that immediately writes the specified string to the specified file descriptor, without buffering. The string contains ANSI color codes, so that if successful, it will print a light green Hello! to the terminal, even if the standard streams were closed.
If you save the above as example.c, you can compile it using e.g.
gcc -Wall -Wextra -O2 example.c -o example
and run using
./example
Because the new_terminal_descriptor() uses ctermid() function to obtain the name (path) to the controlling terminal as a last resort -- this is not common, but I wanted to show here it is easy to do if you decide it is necessary --, it will print the hello message to the terminal even when all streams are redirected:
./example </dev/null >/dev/null 2>/dev/null
Finally, in case you are wondering, none of this is "special". I am not talking about the console terminal, which is the text-based console interface many Linux distributions provide as an alternative to the graphical environment, and the only local interface most Linux servers provide. All of the above uses just normal POSIX pseudoterminal interfaces, and will work just fine using e.g. xterm or any other normal terminal emulator (or Linux console), in all POSIXy systems -- Linux, Mac OS X, and the BSD variants.
Agreeing with #chris-dodd that the file descriptors corresponding to the streams stdin, stdout and stderr usually refer to the same terminal, some points are needed for the original question:
the fd parameter (file descriptor) for tcgetattr and tcsetattr has to be for a terminal.
you could obtain this for a stream using fileno, e.g., fileno(stdin).
POSIX defines constants for the default assignment of file descriptors to stdin, stdout and stderr as STDIN_FILENO, STDOUT_FILENO and STDERR_FILENO. However, it is possible to reopen any of the streams (or use dup or dup2) and alter the actual file descriptor.
while you can obtain a file descriptor for a stream, if you are doing anything interesting with the terminal attributes, that can interfere with the buffering used for streams. If you have to mix the two (file descriptor and stream), do the changes to terminal attributes before reading or writing the stream.
you can also get a file descriptor using an open on the terminal device. This is useful if the streams are redirected, and your application has to work with the terminal. Password prompts do this.
the terminal device can be read from the program tty (even if stdin, etc., are redirected).
programs can check a file descriptor using isatty to see if it is a terminal. If a stream is redirected to a file or pipe, it is not a terminal.
Further reading:
11. General Terminal Interface (POSIX)
What is the difference between stdin and STDIN_FILENO?
By way of experiment I have found myself the following answer:
Each of the triple stderr,stdout,stdin was able to be used to change the terminal settings via the tcsetattr(fd....) function. Once a change was effectuated reading tcgsetattr(stdin....),tcgsetattr(stdout....), and also tcgsetattr(sterr....) returned the same content in the struct termios.h which could be verified via memcmp(&termios_stdin,&termios_stdout,sizeof(struct termios)) == 0
also maybe the man page stated somewhat indirectly this
tcgetattr() gets the parameters associated with the object referred by
fd and stores them in the termios structure referenced by termios_p.
This function may be invoked from a background process; however, the
terminal attributes may be subsequently changed by a foreground
process.
about fd hence the object referred by fd is always the same terminal
(correct me if im wrong on my terms) So i need to read from a file descriptor, but the read method takes in a int for byte size to read that much OR i can use O_NONBLOCK, but i still have to setup up a buffer size of an unknown size. making it difficult. heres what i have so far
this is my method that handles all the polling and mkfifo. and N is already predefined in main
struct pollfd pfd[N];
int i;
for(i = 0; i < N; i++)
{
char fileName[32];
snprintf (fileName, sizeof(fileName), "%d_%di", pid, i);
mkfifo(fileName, 0666);
pfd[i].fd = open(fileName, O_RDONLY | O_NDELAY);
pfd[i].events = POLLIN;
pfd[i].revents = 0;
snprintf (fileName, sizeof(fileName), "%d_%do", pid, i);
mkfifo(fileName, 0666);
i++;
pfd[i].fd = open(fileName, O_WRONLY | O_NDELAY);
pfd[i].events = POLLOUT;
pfd[i].revents = 0;
i--;
}
while(1)
{
int len, n;
n = poll(pfd, N, 2000);
if( n < 0 )
{
printf("ERROR on poll");
continue;
}
if(n == 0)
{
printf("waiting....\n");
continue;
}
for(i = 0; i < N; i++)
{
char buff[1024]; <---i dont want to do this
if (pfd[i].revents & POLLIN)
{
printf("Processing input....\n");
read(pfd[i].fd, buff, O_NONBLOCK);
readBattlefield(buff);
print_battleField_stats();
pfd[i].fd = 0;
}
}
}
i also read somewhere that once read() reads all the data coming, it empties the pipe, meaning i can use the same again for another incoming data. but it doesnt empty the pipe because i cant use the same pipe again. I asked my professor but all he says was to use something like scanf, but how do use scanf if scanf takes a FILE stream, and the poll.fd is an int? essentially my ultimate question is, how to read the incoming data through the file descriptor using scan or of other sort? using scan will help me more with handling the data.
EDIT:
in another terminal i have to put cat file > (named_file)
and my main program will read the input data. heres what the input data looks like
3 3
1 2 0
0 2 0
3 0 0
first 2 numbers are grid information and player number, and after that is grid, but this a simplified version, ill be dealing with sizes over 100's of players and grids of over 1000's
char buff[1024]; <---i dont want to do this
What would you like to do then? This is how it works. This is not how it works:
read(pfd[i].fd, buff, O_NONBLOCK);
This will compile because O_NONBLOCK is an integer #define, but it is absolutely and unequivocally incorrect. The third argument to read() is a number of bytes to read. Not a flag. Period. It may be zero, but what you've done here is pass an arbitrary number -- whatever the value of O_NONBLOCK is, which could easily be more than 1024, the size of your buffer. This does not set the read non-block. recv() is similar to read() and does take such flags as a forth argument, but you can't use that with a file descriptor. If you want to set non-block on a file descriptor, you must do it with open() or fcntl().
how to read the incoming data through the file descriptor using scan or of other sort?
You can create a FILE* stream from an open descriptor with fdopen().
i also read somewhere that once read() reads all the data coming, it empties the pipe, meaning i can use the same again for another incoming data. but it doesnt empty the pipe because i cant use the same pipe again.
Once you reach EOF (because the writer closed the connection), read() will return 0, and continue to return 0 immediately until someone opens the pipe again.
If you set the descriptor non-block, read() will always return immediately; if there is someone connected and nothing to read, it will return -1 but errno will == EAGAIN. See man 2 read.
man fifo is definitely something you should read; if there's anything you aren't sure about, ask a specific question based on that.
And don't forget: Fix that read() call. It's wrong. W R O N G. Your prof/TA/whoever will not miss that.
Please see below code.
#include < stdio.h >
#include < fcntl.h >
#include < stdlib.h >
#include < string.h >
int main(int argc,char **argv,char **envp)
{
int fd;
size_t sz;
char filebuffer[1024];
int loop;
fd=open("sample",O_RDONLY);
if(fd==-1)
{
perror("");
exit(1);
}
loop=0;
while(++loop<300)
{
lseek(fd,0,SEEK_SET);
memset(filebuffer,0,1024);
sz=read(fd,filebuffer,1024);
printf("%d.sz=%zd\t%s\n",loop,sz,filebuffer);
sleep(1);
}
close(fd);
return 0;
}
In this code, I am able to read file. But when I am changing file (reading file "sample") at the same time during reading. Then I am not able to read the changed file. I tried O_SYNC flag too. but still, it is not working, but O_DIRECT is undefined error is coming up. How can I ensure that I am able to read changes? Second thing, but I observed, if I close and open the file reading, then I am able to read changed file.
Question:
How can I read changed file without closing and opening?
I think that you're asking the following question:
I have a program which opens a file called sample and repeatedly reads the first block of that file. That works fine. However, if I edit the file sample, for example with a text editor, then my program does not see the changes, although it will if it closes and reopens the file. How can I see the changes without closing and reopening the file?
If that's your question, then the answer is:
Sorry, you cannot, because the text editor does not modify the file. It creates a new file with the old name.
In Unix, once you open a file, it will not actually get deleted, even if its name is unlinked. If another program "deletes" the file and then creates a new file with the same name, the file you have open is no longer accessible to any other program, but it is still the same file and it will not get deleted until you close it.
Most Unix text utilities, even the ones which claim to work "in-place" (such as sed -i) really do not modify files. That includes text editors. So your program doesn't see changes in the file because the file is not changing; the name has been given to a new file.
So the only way to deal with this is to close and reopen the file. When you reopen, you will be opening the new file with the old name.
The reason for not getting updated data in file could be sync time in filesystem.
I suggest fflush() after writing in to file. This makes your cache data to be written in file.
Related discussions.
Small file not committed to disk for over a minute
Is fwrite non-blocking?
This is an adaptation of your code. It forks to create two processes. The child contains your code, substantially unchanged (different error message, file name variable, and more care with printing the filebuffer which is not null terminated). The parent writes characters (the same character, over and over) to the file.
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static char const filename[] = "sample";
int main(void)
{
int fd;
size_t sz;
char filebuffer[1024];
int loop;
switch (fork())
{
case -1:
fprintf(stderr, "Failed to fork\n");
break;
case 0:
sleep(1);
fd = open(filename, O_RDONLY);
if (fd == -1)
{
fprintf(stderr, "Failed to open file %s for reading\n", filename);
exit(1);
}
loop = 0;
while (++loop < 300)
{
lseek(fd, 0, SEEK_SET);
memset(filebuffer, 0, 1024);
sz = read(fd, filebuffer, 1024);
printf("%d.sz=%zd\t%.*s\n", loop, sz, (int)sz, filebuffer);
sleep(1);
}
close(fd);
break;
default:
fd = open(filename, O_WRONLY|O_CREAT, 0644);
if (fd == -1)
{
fprintf(stderr, "Failed to create file %s for writing\n", filename);
exit(1);
}
for (loop = 0; loop < 256; loop++)
{
memset(filebuffer, (loop % 64) + 33, sizeof(filebuffer));
lseek(fd, 0L, SEEK_SET);
write(fd, filebuffer, sizeof(filebuffer));
sleep(1);
}
close(fd);
break;
}
return 0;
}
Example output:
1.sz=1024 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2.sz=1024 ################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################
3.sz=1024 ################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################
4.sz=1024 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5.sz=1024 &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
6.sz=1024 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
7.sz=1024 ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
8.sz=1024 ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
9.sz=1024 ****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
As you can see, the processes run asynchronously, so the data in the file does not always change between reads, but the process is seeing the changes.
Try running this on your computer. It should work. (Sample output from Mac OS X 10.8.5.) If it doesn't, you'll need to identify which file system type you have, but I don't think it'll be a problem.