bug-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

pop3d errno assignments and pthreads.


From: Sergey Poznyakoff
Subject: pop3d errno assignments and pthreads.
Date: Sun, 22 Apr 2001 14:43:35 +0300

Many functions of the package assign a value to errno variable. This
is no problem when the package is compiled with --disable-pthread
option. But when compiled with pthreads this causes grief, since
in threaded environment errno location is shared between threads.
For example, in GNU/Linux:

#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT)
extern int*     __errno_location  __P((void));
#define errno   (*__errno_location ())

in Solaris/i86:

#if (defined(_REENTRANT) || defined(_TS_ERRNO) || \
        _POSIX_C_SOURCE - 0 >= 199506L) && !(defined(lint) || defined(__lint))
extern int *___errno();
#define errno (*(___errno()))

, etc. Thus, any assignment to errno made by child process clobbers
its value in the parent also. Consequently, the following fragment
in pop3d.c does not work:

      connfd = accept (listenfd, (struct sockaddr *)&client, &size);
      if (connfd == -1)
        {
          if (errno == EINTR)
            continue;
          syslog (LOG_ERR, "accept: %s", strerror (errno));
          exit (-1);
        }

When accept() gets interrupted by, say SIGCHLD, the value of errno
is not EINTR, so the master daemon just complains and dies after
the first child is finished. Possible solution would be

Index: pop3d/signal.c
===================================================================
RCS file: /cvs/mailutils/pop3d/signal.c,v
retrieving revision 1.2
diff -c -r1.2 signal.c
*** signal.c    2001/01/11 04:46:34     1.2
--- signal.c    2001/04/22 11:39:33
***************
*** 8,14 ****
    pid_t pid;
    int status;
  
-   (void)signo;
    while ( (pid = waitpid(-1, &status, WNOHANG)) > 0)
        --children;
  }
--- 8,15 ----
    pid_t pid;
    int status;
  
    while ( (pid = waitpid(-1, &status, WNOHANG)) > 0)
        --children;
+   signal(signo, pop3_sigchld);
+   errno = EINTR; 
  }


But I fear the problem will manifest itself in other places that rely
on the value of errno. It may be better to use some internal variable
instead of the global errno, how do you think?

Cheers,
Sergey Poznyakoff



reply via email to

[Prev in Thread] Current Thread [Next in Thread]