# problem implementing fork

**URL:** <https://community.unix.com/t/problem-implementing-fork/250033>\
**Category:** Programming\
**Created:** [September 24, 2009, 7:14pm UTC](https://community.unix.com/t/problem-implementing-fork/250033 "2009-09-24T19:14:12Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![dheerajsuthar](https://community.unix.com/letter_avatar/dheerajsuthar/32/6_22734026db12803ebb3e059622ac3534.png) [@dheerajsuthar](https://community.unix.com/u/dheerajsuthar)\
**Post date:** [September 24, 2009, 7:14pm UTC](https://community.unix.com/t/problem-implementing-fork/250033/1 "2009-09-24T19:14:12Z")

</div>

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:

```nohighlight
#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:

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

```

hangs for some time. then:

```nohighlight
rc: 1024000
###########################
done.

```

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

---

<div class="post-metadata">

**Author:** ![jp2542a](https://community.unix.com/letter_avatar/jp2542a/32/6_22734026db12803ebb3e059622ac3534.png) [@jp2542a](https://community.unix.com/u/jp2542a)\
**Post date:** [September 24, 2009, 11:14pm UTC](https://community.unix.com/t/problem-implementing-fork/250033/2 "2009-09-24T23:14:41Z")

</div>

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:

```nohighlight
printf("#");

```

with:

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

```

This force the output of the character.

```nohighlight
###rc: 1024000

done.

```

---

<div class="post-metadata">

**Author:** ![dheerajsuthar](https://community.unix.com/letter_avatar/dheerajsuthar/32/6_22734026db12803ebb3e059622ac3534.png) [@dheerajsuthar](https://community.unix.com/u/dheerajsuthar)\
**Post date:** [September 25, 2009, 1:04am UTC](https://community.unix.com/t/problem-implementing-fork/250033/3 "2009-09-25T01:04:21Z")

</div>

> [@jp2542a](#):
>
> 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:
> 
> ```plaintext
> printf("#");
> 
> ```
> 
> with:
> 
> ```plaintext
> putchar('#');
> fflush(stdout);
> 
> ```
> 
> This force the output of the character.
> 
> ```plaintext
> ###rc: 1024000
> 
> done.
> 
> ```

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

---

<div class="post-metadata">

**Author:** ![gautamdheeraj](https://community.unix.com/letter_avatar/gautamdheeraj/32/6_22734026db12803ebb3e059622ac3534.png) [@gautamdheeraj](https://community.unix.com/u/gautamdheeraj)\
**Post date:** [September 25, 2009, 1:58am UTC](https://community.unix.com/t/problem-implementing-fork/250033/4 "2009-09-25T01:58:38Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Corona688](https://community.unix.com/letter_avatar/corona688/32/6_22734026db12803ebb3e059622ac3534.png) [@Corona688](https://community.unix.com/u/Corona688)\
**Post date:** [September 25, 2009, 11:04am UTC](https://community.unix.com/t/problem-implementing-fork/250033/5 "2009-09-25T11:04:02Z")

</div>

Since the #'s are probably( 😉 ) 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.

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

```

---

<div class="post-metadata">

**Author:** ![dheerajsuthar](https://community.unix.com/letter_avatar/dheerajsuthar/32/6_22734026db12803ebb3e059622ac3534.png) [@dheerajsuthar](https://community.unix.com/u/dheerajsuthar)\
**Post date:** [September 25, 2009, 2:14pm UTC](https://community.unix.com/t/problem-implementing-fork/250033/6 "2009-09-25T14:14:46Z")

</div>

> [@gautamdheeraj](#):
>
> 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

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.😕) whereas its the default multitasking facility in \*nix system.

> [@corona688](#):
>
> Since the #'s are probably( 😉 ) 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.
> 
> ```plaintext
> // always unbuffered, fflush not needed
> fputc('#', stderr);
> 
> ```

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

---

<div class="post-metadata">

**Author:** ![Corona688](https://community.unix.com/letter_avatar/corona688/32/6_22734026db12803ebb3e059622ac3534.png) [@Corona688](https://community.unix.com/u/Corona688)\
**Post date:** [September 25, 2009, 5:03pm UTC](https://community.unix.com/t/problem-implementing-fork/250033/7 "2009-09-25T17:03:49Z")

</div>

> [@dheerajsuthar](#):
>
> Also why many are telling me not to use fork(in other forums too.😕) whereas its the default multitasking facility in \*nix system.

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

---

<div class="post-metadata">

**Author:** ![jp2542a](https://community.unix.com/letter_avatar/jp2542a/32/6_22734026db12803ebb3e059622ac3534.png) [@jp2542a](https://community.unix.com/u/jp2542a)\
**Post date:** [October 11, 2009, 10:20pm UTC](https://community.unix.com/t/problem-implementing-fork/250033/8 "2009-10-11T22:20:51Z")

</div>

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...
