I believe this is the wrong way of fixing this problem. To prove this,
consider the race condition betweens stat(), connect() and bind().

Have you tried the documented method?

Window 1:
$ perl -e 'use Socket; socket($s, PF_UNIX, SOCK_STREAM, 0) || die "socket: $!\n"; 
bind($s, sockaddr_un("/tmp/fun")) || die "bind: $!\n"; select(undef, undef, undef, 
undef)'
... does not return ...

Window 2:
$ perl -e 'use Socket; socket($s, PF_UNIX, SOCK_STREAM, 0) || die "socket: $!\n"; 
bind($s, sockaddr_un("/tmp/fun")) || die "bind: $!\n"; select(undef, undef, undef, 
undef)'
bind: Address already in use

This method is much easier, cleaner, contains no race conditions, etc.

Cheers,
mark



On Sun, Aug 24, 2003 at 07:38:16PM +0200, Thomas Lamy wrote:
> Tomasz Kojm wrote:
> >On Fri, 22 Aug 2003 22:23:00 +0200
> >Thomas Lamy <[EMAIL PROTECTED]> wrote:
> >
> >
> >>Tomasz Kojm wrote:
> >>
> >>>On Thu, 21 Aug 2003 11:40:29 -0400
> >>>"Travis Robertson" <[EMAIL PROTECTED]> wrote:
> >>>
> >>>
> >>>
> >>>>I have tried running clamd in local socket mode.  The first time it
> >>>>runs everything is ok, it creates the /var/run/clamd/clamd.socket. 
> >>>>Whenever I reboot the server and it trys to build the socket, I get
> >>>>the error "ERROR:
> >>>
> >>>
> >>>You should stop clamd cleanly - eg. by sending the SIGTERM signal.
> >>>
> >>>Best regards,
> >>>Tomasz Kojm
> >>
> >>What about the following pseudo-code at startup of clamd (instead of 
> >>failing):
> >>
> >>if (file exists(UNIX_SOCKET)) {
> >>  if (connect(UNIX_SOCKET) != ERROR) {
> >>     die ("Socket already exists");
> >>  }
> >>  warn ("Socket already exists but is not connected - unclean
> >>  shutdown?"); unlink (UNIX_SOCKET);
> >>}
> >
> >
> >OK, but this will be an option (something like FixSocket or so) in
> >clamav.conf.
> >
> Ok, the diff against snapshot 20030823 is attached. The new option is 
> named "FixStaleSocket".
> 
> Have fun
>   Thomas
> 

> diff -u -r clamav-devel-20030823.ORIG/clamd/cfgfile.c 
> clamav-devel-20030823/clamd/cfgfile.c
> --- clamav-devel-20030823.ORIG/clamd/cfgfile.c        2003-08-06 05:05:51.000000000 
> +0200
> +++ clamav-devel-20030823/clamd/cfgfile.c     2003-08-24 19:25:00.000000000 +0200
> @@ -63,6 +63,7 @@
>           {"FollowFileSymlinks", OPT_NOARG},
>           {"Foreground", OPT_NOARG},
>           {"Debug", OPT_NOARG},
> +         {"FixStaleSocket", OPT_NOARG},
>           {"User", OPT_STR},
>           {"AllowSupplementaryGroups", OPT_NOARG},
>           {"SelfCheck", OPT_NUM},
> diff -u -r clamav-devel-20030823.ORIG/clamd/localserver.c 
> clamav-devel-20030823/clamd/localserver.c
> --- clamav-devel-20030823.ORIG/clamd/localserver.c    2003-07-29 17:48:08.000000000 
> +0200
> +++ clamav-devel-20030823/clamd/localserver.c 2003-08-24 19:31:01.000000000 +0200
> @@ -50,13 +50,24 @@
>       exit(1);
>      }
>  
> -    if(bind(sockfd, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) == -1) 
> {
> -     if(stat(server.sun_path, &foo) != -1) {
> -         //fprintf(stderr, "ERROR: Socket file %s already exists. Please remove it 
> or use another one.\n", server.sun_path);
> -         logg("!Socket file %s already exists. Please remove it or use another 
> one.\n", server.sun_path);
> +    if (stat(server.sun_path, &foo) != -1) {
> +     logg("Warning: Socket file %s already exists\n", server.sun_path);
> +        if((cpt = cfgopt(copt, "FixStaleSocket"))) {
> +         if(connect(sockfd, (struct sockaddr *) &server, sizeof(struct 
> sockaddr_un)) >= 0) {
> +             logg("Fatal: another instance of clamd seems to listen on %s; 
> exiting.\n", server.sun_path);
> +             close(sockfd);
> +             exit(1);
> +         } else {
> +             logg("Warning: unclean shutdown, removing %s\n", server.sun_path);
> +             unlink (server.sun_path);
> +         }
> +     } else {
> +         logg("Please remove it or use another one.\n");
>           exit(1);
>       }
> +    }
>  
> +    if(bind(sockfd, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) == -1) 
> {
>       estr = strerror(errno);
>       //fprintf(stderr, "ERROR: can't bind(): %s\n", estr);
>       logg("!bind() error: %s\n", estr);


-- 
[EMAIL PROTECTED]/[EMAIL PROTECTED]/[EMAIL PROTECTED] __________________________
.  .  _  ._  . .   .__    .  . ._. .__ .   . . .__  | Neighbourhood Coder
|\/| |_| |_| |/    |_     |\/|  |  |_  |   |/  |_   | 
|  | | | | \ | \   |__ .  |  | .|. |__ |__ | \ |__  | Ottawa, Ontario, Canada

  One ring to rule them all, one ring to find them, one ring to bring them all
                       and in the darkness bind them...

                           http://mark.mielke.cc/



-------------------------------------------------------
This SF.net email is sponsored by: VM Ware
With VMware you can run multiple operating systems on a single machine.
WITHOUT REBOOTING! Mix Linux / Windows / Novell virtual machines
at the same time. Free trial click here:http://www.vmware.com/wl/offer/358/0
_______________________________________________
Clamav-users mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/clamav-users

Reply via email to