Home > Archive > Unix Programming > November 2005 > Why accept error when there have a fork?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Why accept error when there have a fork?
|
|
| yarco.w@gmail.com 2005-11-16, 3:59 am |
| when doing fork in a loop:
code:
while(1) {
tmp_sd = accept(sd, (struct sockaddr*)&tmp_sin, &len);
if (tmp_sd == -1) {
perror("accept");
exit(0);
}
//check client ip
//fork
pid = fork();
switch(pid) {
case -1:
perror("fork");
break;
case 0:
_exit(0);
}
close(tmp_sd);
}
If there's no fork, the code done well.
But if fork, when telnet, it has error: accept: Invalid argument
Thanks a lot.
| |
| Maxim Yegorushkin 2005-11-16, 7:58 am |
|
yarco.w@gmail.com wrote:
> when doing fork in a loop:
> code:
> while(1) {
> tmp_sd = accept(sd, (struct sockaddr*)&tmp_sin, &len);
> if (tmp_sd == -1) {
> perror("accept");
> exit(0);
> }
>
>
> //check client ip
>
>
> //fork
> pid = fork();
> switch(pid) {
> case -1:
> perror("fork");
> break;
> case 0:
> _exit(0);
> }
>
>
> close(tmp_sd);
> }
>
> If there's no fork, the code done well.
> But if fork, when telnet, it has error: accept: Invalid argument
You might forget to initialize len variable before calling accept.
Forking seems irrelevant here. BTW, you may use exit() rather than
_exit() in the child process, since it has its own copy of file
descriptors.
| |
| David Schwartz 2005-11-16, 7:58 am |
|
"Maxim Yegorushkin" <maxim.yegorushkin@gmail.com> wrote in message
news:1132136513.618293.124880@g14g2000cwa.googlegroups.com...
> You might forget to initialize len variable before calling accept.
> Forking seems irrelevant here. BTW, you may use exit() rather than
> _exit() in the child process, since it has its own copy of file
> descriptors.
No, that's bad advice. Suppose you have a file opened in append mode
with some unflushed data. If you call 'exit' in the child, the data will be
appended to the file twice.
DS
| |
| Alex Fraser 2005-11-16, 7:58 am |
| "Maxim Yegorushkin" <maxim.yegorushkin@gmail.com> wrote in message
news:1132136513.618293.124880@g14g2000cwa.googlegroups.com...
> yarco.w@gmail.com wrote:
[snip]
>
> You might forget to initialize len variable before calling accept.
> Forking seems irrelevant here.
Agreed.
> BTW, you may use exit() rather than _exit() in the child process, since
> it has its own copy of file descriptors.
Bad advice, and nonsensical reasoning. In a C program that uses fork(), at
most one process should call exit() or return from main() (in most cases
that means any child processes should call _exit(), just as the OP had).
Otherwise you end up doing the stuff exit() does - before terminating the
process - more than once, which is typically undesirable. exit() calls
registered atexit() functions, flushes output stdio streams, closes all
stdio streams, removes files created by tmpfile(), and then terminates the
process.
Alex
| |
| Maxim Yegorushkin 2005-11-16, 7:02 pm |
|
Alex Fraser wrote:
[]
>
> Bad advice, and nonsensical reasoning. In a C program that uses fork(), at
> most one process should call exit() or return from main() (in most cases
> that means any child processes should call _exit(), just as the OP had).
> Otherwise you end up doing the stuff exit() does - before terminating the
> process - more than once, which is typically undesirable. exit() calls
> registered atexit() functions, flushes output stdio streams, closes all
> stdio streams, removes files created by tmpfile(), and then terminates the
> process.
I agree with that, my mistake.
| |
| Daniel C. Bastos 2005-11-17, 7:01 pm |
| In article <BNSdnYaWVodmgubeRVnyjA@eclipse.net.uk>,
Alex Fraser wrote:
>
> Bad advice, and nonsensical reasoning. In a C program that uses fork(), at
> most one process should call exit() or return from main() (in most cases
> that means any child processes should call _exit(), just as the OP had).
> Otherwise you end up doing the stuff exit() does - before terminating the
> process - more than once, which is typically undesirable. exit() calls
> registered atexit() functions, flushes output stdio streams, closes all
> stdio streams, removes files created by tmpfile(), and then terminates the
> process.
I see what it seems to be an inconsistency with exit and tmpfile ---
at least in the manual page. The manual page of exit says that it
``unlink[s] all files created with the tmpfile(3) function'' and this
matches what you say.
But the manual page of tmpfile(3) says that the ``created file is
unlinked before tmpfile() returns, causing the file to be
automatically deleted when the last reference to it is closed.''
So I think it can be said that exit removes the files by closing them,
not by unlinking them, since tmpfile already did it --- a second call
would result in ENOENT.
| |
| Daniel C. Bastos 2005-11-18, 7:01 pm |
| In article <1132117579.863065.272310@f14g2000cwb.googlegroups.com>,
yarco.w@gmail.com wrote:
> when doing fork in a loop:
> code:
> while(1) {
> tmp_sd = accept(sd, (struct sockaddr*)&tmp_sin, &len);
> if (tmp_sd == -1) {
> perror("accept");
> exit(0);
> }
>
>
> //check client ip
>
>
> //fork
> pid = fork();
> switch(pid) {
> case -1:
> perror("fork");
> break;
> case 0:
> _exit(0);
> }
>
>
> close(tmp_sd);
> }
>
> If there's no fork, the code done well.
> But if fork, when telnet, it has error: accept: Invalid argument
> Thanks a lot.
Did you bind and listen? The manual page says that EINVAL is returned
case listen has not been called.
[EINVAL] listen(2) has not been called on the socket descriptor.
Make sure you initialize len too.
``The addrlen is a value-result parameter; it should initially contain
the amount of space pointed to by addr; on return it will contain
the actual length (in bytes) of the address returned.''
|
|
|
|
|