Tom Lane writes:

> AFAICS, the only practical way to do this is to have a single process
> collecting the stdout/stderr from the postmaster and all its children.

I think not.  It's a little tricky handling it directly in the child
processes, but it's been done before.

> If someone can offer a better alternative than Andrew's, great, let's
> see it.

How about the attached one, which I floated a while ago but which didn't
generate much interest.

-- 
Peter Eisentraut   [EMAIL PROTECTED]
#include "c.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>

#include "pqsignal.h"

volatile static int hangup_flag = 0;


static void
signalhandler(SIGNAL_ARGS)
{
        hangup_flag = 1;
}


#define BUF_SIZE 8192
#define MAX_ERRORS 200

#define MAX_ERRORS_CHECK() do { errcount++; if (max_errors > 0 && errcount >= 
max_errors) exit(2); } while(0)

int
main(int argc, char *argv[])
{
        const char *filename;
        int fd = -1;
        static char buf[BUF_SIZE];
        unsigned int errcount = 0;
        unsigned int max_errors = MAX_ERRORS;

        if (argc != 2)
        {
                fprintf(stderr, "%s: missing required argument\n", argv[0]);
                fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
                exit(1);
        }

        if (strcmp(argv[1], "--help")==0)
        {
                printf("this should be a help message...\n");
                exit(0);
        }

        filename = argv[1];

        fd = open(filename, O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND, 0666);
        if (fd < 0)
        {
                fprintf(stderr, "%s: could not open file %s: %s\n",
                                argv[0], filename, strerror(errno));
                exit(1);
        }

        pqsignal(SIGUSR1, signalhandler);

        for (;;)
        {
                int read_bytes;
                int written_bytes;
                char * buf_ptr;

                read_bytes = read(0, buf, sizeof(buf));
                if (read_bytes < 0)
                {
                        if (errno == EINTR)
                                continue;
                        else
                        {
                                fprintf(stderr, "*** %s: read error from %s: %s\n",
                                                argv[0], filename, strerror(errno));
                                MAX_ERRORS_CHECK();
                        }
                }
                if (read_bytes == 0)
                {
                        /* end of file, postmaster exited? */
                        close(fd);
                        exit(0);
                }

                if (hangup_flag)
                {
                        int fdnew;

                        fdnew = open(filename, O_WRONLY | O_CREAT | O_NOCTTY | 
O_APPEND, 0666);
                        if (fdnew < 0)
                        {
                                fprintf(stderr, "*** %s: could not open new output 
file %s: %s\n",
                                           argv[0], filename, strerror(errno));
                                MAX_ERRORS_CHECK();
                        }
                        else
                        {
                                close(fd);
                                fd = fdnew;
                        }
                        hangup_flag = 0;
                }

                buf_ptr = buf;
                do
                {
                        written_bytes = write(fd, buf_ptr, read_bytes);
                        if (written_bytes < 0)
                        {
                                if (errno == EINTR)
                                        continue;
                                fprintf(stderr, "*** %s: could not write to file %s: 
%s\n",
                                                argv[0], filename, strerror(errno));
                                MAX_ERRORS_CHECK();

                                break;
                        }
                        if (written_bytes < read_bytes)
                        {
                                buf_ptr += written_bytes;
                                read_bytes -= written_bytes;
                                continue;
                        }
                        break;
                } while(1);
        }

        return 127;
}
---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
    (send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])

Reply via email to