problem implementing fork

Hi,
I was honing my linux programming skill when this nuisance started bugging me. I wanted to create an empty file creator program. While creating a large file it must print # for progress bar. But the output shows it happening reverse way. ie. first it copies file and shows the progress bar(although the bar is filled completely thus showing that parent process is working correctly). Kindly help me in putting these progress # simultaneously to file copying. Thanks in advance.
Code:

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

static int status = 0;
void ding()
{
status =1;
}
int main(int argc, char* argv[])
{
int rc=0,fd,i,tem=0;
char c=' ';
int size= atoi(argv[1])*1024;
char *add=argv[2];

pid_t pid;
pid = fork();
switch(pid){
case -1:
perror("Error creating fork\n");
exit(1);

case 0:
/*child process*/
{
fd = open(add,O_WRONLY|O_CREAT,0666);
if (fd<0)
{
printf("Error creating file\n");
exit(1);
}
for(i=1;i<=size;i++)
{
tem = write(fd, &c, 1);
rc += tem;
}
printf("rc: %d\n",rc);
if(rc!=size)
perror("Error allocating size.\n");
else
kill(getppid(),SIGALRM);

close(fd);
exit(0);
}
/*child process ends*/
}
/*parent process*/
(void) signal(SIGALRM,ding);
while(1){
printf("#");
sleep(1);
if(status)
{
printf("\ndone.\n");
exit(1);
}
}
}

Output:

dheeraj@dheeraj-machine:~/linux_pro$ ./a.out 1000 temp

hangs for some time. then:

rc: 1024000
###########################
done.

Clearly these # should have been printed along with file copy process. But don't know why its not.

It only actually does the output when it has an end of record indicator. Unless you tell it to flush it. I wish I could remember more of my c programming better but this will work.

Replace:

printf("#");

with:

putchar('#');
fflush(stdout);

This force the output of the character.

###rc: 1024000

done.

Great! Worked like charm:). Thanks jp2542a.:b:

I can see some improvements in your code.

  • In case the child process his a error, this will exiting without sending SIGALRM to parent, which will make parent to keep on printing the "#", even if child has died, so parent will keep on printing the #.
  • #'s are relative to the size of the file you are creating. (they should).not to the time. For a small sized file, their will be 1-2 hashes. but for big, their can be 20-30 hashes. This doesn't tells the user real progress.

May be you can try without using fork.

-Dheeraj

Since the #'s are probably( :wink: ) intended for human reading and not as output for another process, you should print them to standard error instead of standard output to kill two birds with one stone. stderr is unbuffered by convention.

// always unbuffered, fflush not needed
fputc('#', stderr);

Thanks for your kind reply.
I really missed the time factor . Can you give some code to implement the same. A brief pseudo code will suffice. Also why many are telling me not to use fork(in other forums too.:confused:) whereas its the default multitasking facility in *nix system.

Thanks to you also ! Never knew that fact about stderr:o

Does this program even need multitasking? You could make printing "#" part of the writing loop, or kludge something with alarm(). A fork() is overkill.

A couple of things come to mnd....

  1. I'd use something other than SIGALRM to signal the parent. Perhaps SIGCHLD or SIGUSR1
  2. Forking gives the parent the opportunity to do something useful if the kid hangs. For instance, if the I/O subsystem were to be unable to complete an i/o and fail to return an error on a Solaris (or any system using DMA for I/O) , the kid will be unkillable and hang. This is because you might remove the process memory, reallocate it to another process only to have the DMA device complete the physical i/o. It might be useful to tell someone about the i/o issue via a timeout mechanism.
  3. Is forking all that expensive in a Linux system? Most everything except for the LWP stuff will be created with either model. The forking model makes expansion of the code to handle multiple tasks saner..

sorry about the late reply...