Back to index

courier  0.68.2
Defines | Functions | Variables
fork.c File Reference
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "gpg.h"
#include "gpglib.h"

Go to the source code of this file.

Defines

#define WEXITSTATUS(stat_val)   ((unsigned)(stat_val) >> 8)
#define WIFEXITED(stat_val)   (((stat_val) & 255) == 0)

Functions

pid_t libmail_gpg_fork (int *libmail_gpg_stdin, int *libmail_gpg_stdout, int *libmail_gpg_stderr, const char *gpgdir, char **argvec)
int libmail_gpg_write (const char *p, size_t cnt, int(*stdout_func)(const char *, size_t, void *), int(*stderr_func)(const char *, size_t, void *), int(*timeout_func)(void *), unsigned timeout, void *voidarg)
int libmail_gpg_read (int(*stdout_func)(const char *, size_t, void *), int(*stderr_func)(const char *, size_t, void *), int(*timeout_func)(void *), unsigned timeout, void *voidarg)

Variables

int libmail_gpg_stdin
int libmail_gpg_stdout
int libmail_gpg_stderr
pid_t libmail_gpg_pid

Define Documentation

#define WEXITSTATUS (   stat_val)    ((unsigned)(stat_val) >> 8)

Definition at line 21 of file fork.c.

#define WIFEXITED (   stat_val)    (((stat_val) & 255) == 0)

Definition at line 24 of file fork.c.


Function Documentation

pid_t libmail_gpg_fork ( int *  libmail_gpg_stdin,
int *  libmail_gpg_stdout,
int *  libmail_gpg_stderr,
const char *  gpgdir,
char **  argvec 
)

Definition at line 39 of file fork.c.

{
       int pipein[2], pipeout[2], pipeerr[2];
       pid_t p;
       char *s;

       if (libmail_gpg_stdin && pipe(pipein) < 0)
              return (-1);

       if (libmail_gpg_stdout && pipe(pipeout) < 0)
       {
              if (libmail_gpg_stdin)
              {
                     close(pipein[0]);
                     close(pipein[1]);
              }
              return (-1);
       }

       if (libmail_gpg_stderr && pipe(pipeerr) < 0)
       {
              if (libmail_gpg_stdout)
              {
                     close(pipeout[0]);
                     close(pipeout[1]);
              }

              if (libmail_gpg_stdin)
              {
                     close(pipein[0]);
                     close(pipein[1]);
              }
              return (-1);
       }

       signal(SIGCHLD, SIG_DFL);
       p=libmail_gpg_pid=fork();
       if (p < 0)
       {
              if (libmail_gpg_stderr)
              {
                     close(pipeerr[0]);
                     close(pipeerr[1]);
              }

              if (libmail_gpg_stdout)
              {
                     close(pipeout[0]);
                     close(pipeout[1]);
              }
              if (libmail_gpg_stdin)
              {
                     close(pipein[0]);
                     close(pipein[1]);
              }

              return (-1);
       }

       if (p)
       {
              signal(SIGPIPE, SIG_IGN);

              if (libmail_gpg_stderr)
              {
                     close(pipeerr[1]);
                     *libmail_gpg_stderr=pipeerr[0];
              }

              if (libmail_gpg_stdout)
              {
                     close(pipeout[1]);
                     *libmail_gpg_stdout=pipeout[0];
              }

              if (libmail_gpg_stdin)
              {
                     close(pipein[0]);
                     *libmail_gpg_stdin=pipein[1];
              }
              return (0);
       }

       if (libmail_gpg_stderr)
       {
              dup2(pipeerr[1], 2);
              close(pipeerr[0]);
              close(pipeerr[1]);
       }
       else if (libmail_gpg_stdout)
       {
              dup2(pipeout[1], 2);
       }

       if (libmail_gpg_stdout)
       {
              dup2(pipeout[1], 1);
              close(pipeout[0]);
              close(pipeout[1]);
       }

       if (libmail_gpg_stdin)
       {
              dup2(pipein[0], 0);
              close(pipein[0]);
              close(pipein[1]);
       }

       if (gpgdir)
       {
              s=malloc(sizeof("GNUPGHOME=")+strlen(gpgdir));
              if (!s)
              {
                     perror("malloc");
                     exit(1);
              }
              strcat(strcpy(s, "GNUPGHOME="), gpgdir);
              if (putenv(s) < 0)
              {
                     perror("putenv");
                     exit(1);
              }
       }

       {
              const char *gpg=getenv("GPG");
              if (!gpg || !*gpg)
                     gpg=GPG;

              execv(gpg, argvec);
              perror(gpg);
       }
       _exit(1);
       return (0);
}

Here is the caller graph for this function:

int libmail_gpg_read ( int(*)(const char *, size_t, void *)  stdout_func,
int(*)(const char *, size_t, void *)  stderr_func,
int(*)(void *)  timeout_func,
unsigned  timeout,
void *  voidarg 
)

Definition at line 273 of file fork.c.

{
       char buf[BUFSIZ];

       fd_set fdr;
       struct timeval tv;

       if (libmail_gpg_stdin >= 0)
       {
              close(libmail_gpg_stdin);
              libmail_gpg_stdin= -1;
       }

       if (!timeout_func)
              timeout=0;

       while ( libmail_gpg_stdout >= 0 || libmail_gpg_stderr >= 0)
       {
              int maxfd=0;
              int n;

              FD_ZERO(&fdr);

              if (libmail_gpg_stdout >= 0)
              {
                     FD_SET(libmail_gpg_stdout, &fdr);
                     if (libmail_gpg_stdout > maxfd)
                            maxfd=libmail_gpg_stdout;
              }

              if (libmail_gpg_stderr >= 0)
              {
                     FD_SET(libmail_gpg_stderr, &fdr);
                     if (libmail_gpg_stderr > maxfd)
                            maxfd=libmail_gpg_stderr;
              }

              tv.tv_usec=0;
              tv.tv_sec=timeout;
              n=select(maxfd+1, &fdr, NULL, NULL, timeout ? &tv:NULL);

              if (n == 0)
              {
                     n=(*timeout_func)(voidarg);
                     if (n)
                            return(n);
                     continue;
              }
              if (n < 0)
                     continue;

              if (libmail_gpg_stdout >= 0 &&
                  FD_ISSET(libmail_gpg_stdout, &fdr))
              {
                     int n=read(libmail_gpg_stdout, buf, sizeof(buf));

                     if (n <= 0)
                     {
                            close(libmail_gpg_stdout);
                            libmail_gpg_stdout= -1;
                     }
                     else if (stdout_func &&
                             (n=(*stdout_func)(buf, n, voidarg)) != 0)
                            return (n);
              }

              if (libmail_gpg_stderr >= 0 &&
                  FD_ISSET(libmail_gpg_stderr, &fdr))
              {
                     int n=read(libmail_gpg_stderr, buf, sizeof(buf));

                     if (n <= 0)
                     {
                            close(libmail_gpg_stderr);
                            libmail_gpg_stderr= -1;
                     }
                     else if (stderr_func &&
                             (n=(*stderr_func)(buf, n, voidarg)) != 0)
                            return (n);
              }
       }
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int libmail_gpg_write ( const char *  p,
size_t  cnt,
int(*)(const char *, size_t, void *)  stdout_func,
int(*)(const char *, size_t, void *)  stderr_func,
int(*)(void *)  timeout_func,
unsigned  timeout,
void *  voidarg 
)

Definition at line 178 of file fork.c.

{
       char buf[BUFSIZ];

       fd_set fdr, fdw;
       struct timeval tv;

       if (!timeout_func)
              timeout=0;
       while (cnt)
       {
              int maxfd=0;
              int n;

              FD_ZERO(&fdr);
              FD_ZERO(&fdw);

              FD_SET(libmail_gpg_stdin, &fdw);

              if (libmail_gpg_stdout >= 0)
              {
                     FD_SET(libmail_gpg_stdout, &fdr);
                     if (libmail_gpg_stdout > maxfd)
                            maxfd=libmail_gpg_stdout;
              }

              if (libmail_gpg_stderr >= 0)
              {
                     FD_SET(libmail_gpg_stderr, &fdr);
                     if (libmail_gpg_stderr > maxfd)
                            maxfd=libmail_gpg_stderr;
              }

              tv.tv_usec=0;
              tv.tv_sec=timeout;
              n=select(maxfd+1, &fdr, &fdw, NULL, timeout ? &tv:NULL);
              if (n == 0)
              {
                     n=(*timeout_func)(voidarg);
                     if (n)
                            return(n);
                     continue;
              }
              if (n < 0)
                     continue;

              if (FD_ISSET(libmail_gpg_stdin, &fdw))
              {
                     int n=write(libmail_gpg_stdin, p, cnt);

                     if (n <= 0)
                            return (-1);

                     p += n;
                     cnt -= n;
              }

              if (libmail_gpg_stdout >= 0 &&
                  FD_ISSET(libmail_gpg_stdout, &fdr))
              {
                     int n=read(libmail_gpg_stdout, buf, sizeof(buf));

                     if (n <= 0)
                     {
                            close(libmail_gpg_stdout);
                            libmail_gpg_stdout= -1;
                     }
                     else if (stdout_func &&
                             (n=(*stdout_func)(buf, n, voidarg)) != 0)
                            return (n);
              }

              if (libmail_gpg_stderr >= 0 &&
                  FD_ISSET(libmail_gpg_stderr, &fdr))
              {
                     int n=read(libmail_gpg_stderr, buf, sizeof(buf));

                     if (n <= 0)
                     {
                            close(libmail_gpg_stderr);
                            libmail_gpg_stderr= -1;
                     }
                     else if (stderr_func &&
                             (n=(*stderr_func)(buf, n, voidarg)) != 0)
                            return (n);
              }
       }
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 34 of file libgpg.c.

Definition at line 33 of file libgpg.c.

Definition at line 32 of file libgpg.c.

Definition at line 32 of file libgpg.c.