How Can I call close() for all - Linux

This is a discussion on How Can I call close() for all - Linux ; On Nov 28, 12:40 pm, Joe Pfeiffer wrote: > No... it's more as if somebody asked "can I go trap shooting", and > getting an answer like "no, because you might point the gun at your > head and pull ...

+ Reply to Thread
Page 2 of 2 FirstFirst 1 2
Results 21 to 31 of 31

Thread: How Can I call close() for all

  1. Re: How Can I call close() for all

    On Nov 28, 12:40 pm, Joe Pfeiffer wrote:

    > No... it's more as if somebody asked "can I go trap shooting", and
    > getting an answer like "no, because you might point the gun at your
    > head and pull the trigger".


    Nonsense. You can *never* call 'close' indiscriminately on a whole
    bunch of file descriptors. To avoid bugs of the type I describe, you
    *must* close down the application state on each descriptor, one by
    one, to make sure you want try to access it. At the time you spin them
    down, you would normally close them. It's pointless to cleanly spin
    down a whole bunch of connections, then go back and 'close' them all.

    So, no, it's almost never safe to call 'close' on a whole bunch of
    descriptors. If you haven't cleanly removed the application-level
    state for those descriptors, you can cause the horrible problems I
    describe. If you have, you should have already called 'close'.

    DS

  2. Re: How Can I call close() for all

    "David Schwartz" wrote in message
    news:447e7e01-53e8-46a8-a56f-983fac65b3de@b40g2000prf.googlegroups.com...
    > On Nov 28, 12:40 pm, Joe Pfeiffer wrote:
    >
    >> No... it's more as if somebody asked "can I go trap shooting", and
    >> getting an answer like "no, because you might point the gun at your
    >> head and pull the trigger".

    > Nonsense. You can *never* call 'close' indiscriminately on a whole
    > bunch of file descriptors.

    Well, you can do so between fork() and exec(). And probably should, if you
    depend on any libraries that may have opened file descriptors themselves
    which you don't want to linger in the new process.



  3. Re: How Can I call close() for all

    On Nov 29, 12:57 am, "Arnold Hendriks" wrote:

    > Well, you can do so between fork() and exec(). And probably should, if you
    > depend on any libraries that may have opened file descriptors themselves
    > which you don't want to linger in the new process.


    There are ways even that can screw up, but I think this is the one
    case where the potential problems you solve outweigh the potential
    problems you cause.

    What happens if 'exec' requires one of the file descriptors you
    closed? For example, consider a platform that has a user-space file
    name mapper that is accessed by a socket and all file accesses
    (including 'exec') are passed to the mapper before being passed to the
    OS. The mapper, and hence the exec, will fail because its socket is
    obliterated.

    I think insisting libraries properly set 'close on exec' is a better
    solution. But you might have to work around a broken library.

    The same argument applies to a 'close' loop before calling 'exit' in a
    single-threaded application. Though pointless, you might think this is
    at least safe. Unfortunately, it's not for two reasons. First, 'exit'
    might rely on a descriptor. Second, you might catch a signal and the
    signal handler might rely on a descriptor.

    Of course, these situations have much more minimal risk than the more
    typical case the OP is asking about.

    DS

  4. Re: How Can I call close() for all

    David Schwartz writes:
    > On Nov 28, 12:40 pm, Joe Pfeiffer wrote:


    [...]

    > So, no, it's almost never safe to call 'close' on a whole bunch of
    > descriptors. If you haven't cleanly removed the application-level
    > state for those descriptors, you can cause the horrible problems I
    > describe.


    And it is almost never safe to just open a door and pass thru it into
    the street, because if one didn't dress before doing so, that could
    lead to a prosection for creating a public nuisance.

    This is certainly a nice example of completely nonsensical reasoning,
    but nothing except that.


  5. Re: How Can I call close() for all

    Rainer Weikusat writes:
    > David Schwartz writes:
    >> On Nov 28, 12:40 pm, Joe Pfeiffer wrote:

    >
    > [...]
    >
    >> So, no, it's almost never safe to call 'close' on a whole bunch of
    >> descriptors. If you haven't cleanly removed the application-level
    >> state for those descriptors, you can cause the horrible problems I
    >> describe.

    >
    > And it is almost never safe to just open a door and pass thru it into
    > the street, because if one didn't dress before doing so, that could
    > lead to a prosection for creating a public nuisance.
    >
    > This is certainly a nice example of completely nonsensical reasoning,
    > but nothing except that.


    For the benefit of someone who may be wondering (and because this is a
    common error): The problem lies in the assumption that having no
    information regarding the truth-value of a statements would be
    equivalent to this truth-value being '(probably) false' (instead of
    'possibly false').



  6. Re: How Can I call close() for all

    On Nov 28, 8:53 pm, David Schwartz wrote:
    > On Nov 28, 4:09 am, Rainer Weikusat wrote:
    >
    > > Multithreaded code operating on shared ressources without proper
    > > serialization can behave in unexpected ways. Film at 11. Relevance
    > > regarding the question:

    >
    > > I have a server application that uses a communication loop
    > > with a select to handle multiple clients.

    >
    > > How Can I call close() for all
    > > the sockets currently open? (i.e., all the clients currently
    > > connected)

    >
    > > or wrt the question if close can be used to close a TCP-connection or
    > > under which circumstances (unread data) a shutdown/ close sequence may
    > > be more appropriate: Zero.

    >
    > You are, again, dangerously wrong. I swear, sometimes it seems like
    > you try to give people dangerously bad advice. I warn people about bad
    > things for good reasons, and you always want them to ignore the
    > warnings. What is up with that?!
    >
    > Consider:
    >
    > 1) You call 'select' and get a list of sockets to process.
    >
    > 2) The first socket you process contains a command that tells the
    > server shut down, so you call 'close' on all your connections.
    >
    > 3) You call 'syslog' to log the fact that you are shutting down.
    > Unbeknowst to you, 'syslog' opens a TCP connection to write the log
    > event. (You neither know nor care how 'syslog' works its magic.) The
    > socket is left open in case there are further log entries.
    >
    > 4) You continue processing the list you got from 'select' because you
    > only check for shutdown at the top of the loop. You go to the next
    > socket (whose descriptor now refers to the log socket) and write some
    > sensitive data that should not go in the log to that connection.
    >
    > Same problem. Calling 'close' without logically shutting down the
    > connection in your program logic is dangerous. The OP is asking if he
    > can blindly 'close' sockets and the answer is *NO*, you must "spin
    > them down" in your program logic first.
    >
    > DS

    .................................................. .................................................. .................................................. ......

    I had used taskSpawn for each client connection with socket option.So
    How Can I call close() for all the sockets currently open? (i.e., all
    the clients currently connected).?...

    I wanted to develop a Echo TCP server that can handle 10 clients and
    can able to close server with out affecting...there should be one
    entry point as well one exit.....this is my requirnemnet based on that
    I had develped tcpserver pgm given below:
    Pls give suggestion for this...for graceful shut down of the
    server...echo server...only one entry(instead of sp tcpServer there
    should be some function to spawn server)...10 connection(This I am
    passing as a macro in listen function.?

    /* TcpClient.c - TCP client source
    * This file implements the client-side functionality of the Client-
    Server
    * application.The code demonstrates the usage socket routine calls.
    */

    /* includes */

    #include "vxWorks.h"
    #include "sockLib.h"
    #include "inetLib.h"
    #include "stdioLib.h"
    #include "strLib.h"
    #include "hostLib.h"
    #include "ioLib.h"
    #include "Tcp.h"
    #include "stdlib.h"
    #include "fioLib.h"


    /
    ************************************************** ***************************
    * NAME : tcpClient
    *
    * INPUT : name or IP address of server
    *
    * DESCRIPTION : tcpClient - send requests to server over a TCP socket
    *
    * RETURNS : OK, or ERROR if the message could not be sent to the
    server.
    *

    ************************************************** ****************************/



    STATUS tcpClient
    (
    char * serverName /* name or IP address of server */
    )

    {
    struct sockaddr_in serverAddr; /* server's socket address */
    int sockAddrSize; /* size of socket address structure */
    int sFd; /* socket file descriptor */

    /* char * recv_strng; */
    /* recv_strng = (char *)malloc(50); */

    int nRead;

    /*for non blocking call*/
    const int on = 1;

    static char msg[]="Hello";

    /* create client's socket */

    if ((sFd = socket (AF_INET, SOCK_STREAM, 0)) == ERROR)
    {
    perror ("socket");
    return (ERROR);
    }

    /* bind not required - port number is dynamic */
    /* build server socket address */

    sockAddrSize = sizeof (struct sockaddr_in);
    bzero ((char *) &serverAddr, sockAddrSize);
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_len = (u_char) sockAddrSize;
    serverAddr.sin_port = htons (SERVER_PORT_NUM);

    if (((serverAddr.sin_addr.s_addr = inet_addr (serverName)) == ERROR)
    &&
    ((serverAddr.sin_addr.s_addr = hostGetByName (serverName)) ==
    ERROR))
    {
    perror ("unknown server name");
    close (sFd);
    return (ERROR);
    }

    /* connect to server */

    if (connect (sFd, (struct sockaddr *) &serverAddr, sockAddrSize) ==
    ERROR)
    {
    perror ("connect");
    close (sFd);
    return (ERROR);
    }

    /*To make fd as a non Blocking call*/

    ioctl (sFd, FIONBIO, (int) &on);

    /* Write data to the server and Read back data from server. */
    /* if (write (sFd, (char *)"Test String", sizeof ("Test String")) ==
    ERROR) */

    if (write (sFd, msg, sizeof (msg)) == ERROR)
    {
    perror ("write");
    close (sFd);
    return (ERROR);
    }

    /* while ((nRead = fioRead (sFd, (char *) recv_strng, 50))!= 0) */

    while ((nRead = fioRead (sFd, msg, sizeof(msg)))!= 0)

    {
    msg[11]= '\0';
    printf("\n\rnRead = %d\n\n", nRead);

    printf ("MESSAGE FROM SERVER %s\n\n", msg);

    memset(msg, 0, 50);

    if (nRead == ERROR) /* error from read() */
    perror ("read");
    close (sFd); /* close server socket
    connection */

    /* Terminate the client program gracefully. */
    exit(0);

    }

    return (OK);
    }





  7. Re: How Can I call close() for all

    On Nov 29, 5:05 am, Rainer Weikusat wrote:

    > For the benefit of someone who may be wondering (and because this is a
    > common error): The problem lies in the assumption that having no
    > information regarding the truth-value of a statements would be
    > equivalent to this truth-value being '(probably) false' (instead of
    > 'possibly false').
    >
    >


    Except we don't have no information, we have the OP's post.

    If the OP is not going to continue executing, he should just call
    'exit'. If he is going to continue executing, it's definitely not safe
    to call 'close' on the file descriptors without spinning down their
    application state.

    There is no situation in which it is safe to just call 'close' on a
    whole bunch of file descriptors. *None*.

    Can you name one?

    DS

  8. Re: How Can I call close() for all

    On Nov 29, 10:53 pm, sreyas.j...@wipro.com wrote:

    > I had used taskSpawn for each client connection with socket option.So
    > How Can I call close() for all the sockets currently open? (i.e., all
    > the clients currently connected).?...


    You can't just release a resource while another thread is or might be
    using it. You need some kind of way to coordinate the concurrent use
    of a resource (in this case the socket) between the two threads.

    > I wanted to develop a Echo TCP server that can handle 10 clients and
    > can able to close server with out affecting...there should be one
    > entry point as well one exit.....this is my requirnemnet based on that
    > I had develped tcpserver pgm given below:
    > Pls give suggestion for this...for graceful shut down of the
    > server...echo server...only one entry(instead of sp tcpServer there
    > should be some function to spawn server)...10 connection(This I am
    > passing as a macro in listen function.?


    This is just one of the reasons a "thread per client" architecture is
    discouraged. Your threads may or may not be blocked in socket
    operations, so it's very difficult to coordinate with them.

    For server shutdown purposes only, it should be safe enough to blindly
    call 'shutdown' on every outstanding connection and allow the threads
    to terminate on their own when they discover their connection is dead.

    This has race conditions, but it's hard to imagine how they could
    matter for shutdown.

    DS

  9. Re: How Can I call close() for all

    David Schwartz writes:
    > On Nov 29, 5:05 am, Rainer Weikusat wrote:
    >
    >> For the benefit of someone who may be wondering (and because this is a
    >> common error): The problem lies in the assumption that having no
    >> information regarding the truth-value of a statements would be
    >> equivalent to this truth-value being '(probably) false' (instead of
    >> 'possibly false').
    >>
    >>

    >
    > Except we don't have no information, we have the OP's post.


    Quoting it again:

    ,----
    | I have a server application that uses a communication loop
    | with a select to handle multiple clients.
    |
    | How Can I call close() for all
    | the sockets currently open? (i.e., all the clients currently
    | connected) Will that cause any sort of trouble?
    |
    |
    | What I want/need to do is to implement a mechanism to
    | shutdown the server, so I'm wondering if I can just go
    | through the list of the sockets and close them (well,
    | maybe sending them a message first).
    `----

    This text does not describe any processing except closing the sockets
    and your erronous assumption is that this means there is no such
    processing despite such processing would be required.

    That it would be required is actually the second erronous assumption.

    The text contains no information regarding either of both.

    > There is no situation in which it is safe to just call 'close' on a
    > whole bunch of file descriptors. *None*.


    It is always safe if the application does not contain 'certain
    programming errors', namely, to continue using a descriptor number
    after that descriptor number had been used as an argument to a close
    call, relying on the 'invalidness' of this particular descriptor
    number, although a file descriptor generating system call has been
    executed since the close.

    And that's actually a fairly freaked-out error scenario. Basic rules
    of defensive programming would dictate to always set the value of
    objects which have been invalidated to an invalid value to make
    certain that an eventual occurence of such a coding bug would be
    caught. Not that reuses-after-close would exactly be 'a common
    programming pattern'. Usually, file descriptors are closed as part of
    the 'stop using it' path of something and the same object will usually
    not be reused as argument to a call taking a file descriptor until a
    newly created one has again been stored into it.


  10. Re: How Can I call close() for all

    On Nov 30, 10:31 am, Rainer Weikusat wrote:

    > This text does not describe any processing except closing the sockets
    > and your erronous assumption is that this means there is no such
    > processing despite such processing would be required.


    I'm not sure I follow you. If he's just going to call 'exit' before
    calling 'close' all those times, he should just call 'exit' in the
    first place.

    I'm assuming his reason for calling 'close' is because he wants the
    sockets closed before he calls 'exit', which means there's something
    he's going to do in-between the two.

    If he really thinks he needs to close all his sockets before calling
    'exit', then the right response is, 'just call exit'. In no case does
    it make sense to call 'close' on a large number of file descriptors
    blindly, with *one* exception. (The one exception is server startup,
    to handle the case where the process that 'exec'ed you left a bunch of
    connections you know nothing about.)

    > That it would be required is actually the second erronous assumption.
    >
    > The text contains no information regarding either of both.


    In neither case is the answer "yes, do that". In both cases it's "no,
    don't do that". Just for different reasons.

    > > There is no situation in which it is safe to just call 'close' on a
    > > whole bunch of file descriptors. *None*.


    > It is always safe if the application does not contain 'certain
    > programming errors', namely, to continue using a descriptor number
    > after that descriptor number had been used as an argument to a close
    > call, relying on the 'invalidness' of this particular descriptor
    > number, although a file descriptor generating system call has been
    > executed since the close.


    There is simply no way to avoid that error in any realistic
    application. The 'syslog' function might create a connection and
    'close'ing that connection blindly is not safe, as I explained.

    It is only safe if you know for a fact that it's safe for each
    descriptor you plan to 'close'.

    > And that's actually a fairly freaked-out error scenario. Basic rules
    > of defensive programming would dictate to always set the value of
    > objects which have been invalidated to an invalid value to make
    > certain that an eventual occurence of such a coding bug would be
    > caught. Not that reuses-after-close would exactly be 'a common
    > programming pattern'. Usually, file descriptors are closed as part of
    > the 'stop using it' path of something and the same object will usually
    > not be reused as argument to a call taking a file descriptor until a
    > newly created one has again been stored into it.


    In other words, you must shut down the application state associated
    with each connection before calling 'close', which is precisely what I
    said.

    DS

  11. Re: How Can I call close() for all

    David Schwartz writes:
    > On Nov 30, 10:31 am, Rainer Weikusat wrote:
    >> This text does not describe any processing except closing the sockets
    >> and your erronous assumption is that this means there is no such
    >> processing despite such processing would be required.

    >
    > I'm not sure I follow you.


    It could perhaps help if you would leave enough of the text intact for
    its meaning to still be intelligible, in, lets say, two weeks, when
    active memories have faded to some degree, or if the posting is read
    by someone who found it via Google search.

    > If he's just going to call 'exit' before calling 'close' all those
    > times, he should just call 'exit' in the first place.


    There was no information on this avaible in the text you continue to
    delete while pretending to discuss it.

    [...]

    >> > There is no situation in which it is safe to just call 'close' on a
    >> > whole bunch of file descriptors. *None*.

    >
    >> It is always safe if the application does not contain 'certain
    >> programming errors', namely, to continue using a descriptor number
    >> after that descriptor number had been used as an argument to a close
    >> call, relying on the 'invalidness' of this particular descriptor
    >> number, although a file descriptor generating system call has been
    >> executed since the close.

    >
    > There is simply no way to avoid that error in any realistic
    > application.


    There is the very simple way all application code I have seen so far
    has been written and that is that the code does not continue to use
    the value contained in a variable that had been used to hold a
    descriptor which has been closed.

    [...]

    >> And that's actually a fairly freaked-out error scenario. Basic rules
    >> of defensive programming would dictate to always set the value of
    >> objects which have been invalidated to an invalid value to make
    >> certain that an eventual occurence of such a coding bug would be
    >> caught. Not that reuses-after-close would exactly be 'a common
    >> programming pattern'. Usually, file descriptors are closed as part of
    >> the 'stop using it' path of something and the same object will usually
    >> not be reused as argument to a call taking a file descriptor until a
    >> newly created one has again been stored into it.

    >
    > In other words, you must shut down the application state associated
    > with each connection before calling 'close', which is precisely what I
    > said.


    For the scenario I actually described, this would mean that no
    connections could ever be closed because all close-calls would fail
    with EBADF.


+ Reply to Thread
Page 2 of 2 FirstFirst 1 2