summaryrefslogtreecommitdiffstats
path: root/src/util/child_common.h
blob: 369de71a13449beb185e5bc682c8871625fe6027 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
    SSSD

    Common helper functions to be used in child processes

    Authors:
        Sumit Bose   <sbose@redhat.com>

    Copyright (C) 2009 Red Hat

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __CHILD_COMMON_H__
#define __CHILD_COMMON_H__

#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <tevent.h>

#include "util/util.h"

#define IN_BUF_SIZE         512
#define CHILD_MSG_CHUNK     256

struct response {
    uint8_t *buf;
    size_t size;
};

struct io_buffer {
    uint8_t *data;
    size_t size;
};

struct child_io_fds {
    int read_from_child_fd;
    int write_to_child_fd;
};

/* COMMON SIGCHLD HANDLING */
typedef void (*sss_child_fn_t)(int pid, int wait_status, void *pvt);

struct sss_sigchild_ctx;
struct sss_child_ctx;

/* Create a new child context to manage callbacks */
errno_t sss_sigchld_init(TALLOC_CTX *mem_ctx,
                         struct tevent_context *ev,
                         struct sss_sigchild_ctx **child_ctx);

errno_t sss_child_register(TALLOC_CTX *mem_ctx,
                           struct sss_sigchild_ctx *sigchld_ctx,
                           pid_t pid,
                           sss_child_fn_t cb,
                           void *pvt,
                           struct sss_child_ctx **child_ctx);

void sss_child_handler(struct tevent_context *ev,
                       struct tevent_signal *se,
                       int signum,
                       int count,
                       void *siginfo,
                       void *private_data);

/* Callback to be invoked when a sigchld handler is called.
 * The tevent_signal * associated with the handler will be
 * freed automatically when this function returns.
 */
typedef void (*sss_child_callback_t)(int child_status,
                                     struct tevent_signal *sige,
                                     void *pvt);

struct sss_child_ctx_old;

/* Set up child termination signal handler */
int child_handler_setup(struct tevent_context *ev, int pid,
                        sss_child_callback_t cb, void *pvt,
                        struct sss_child_ctx_old **_child_ctx);

/* Destroy child termination signal handler */
void child_handler_destroy(struct sss_child_ctx_old *ctx);

/* Async communication with the child process via a pipe */
struct tevent_req *write_pipe_send(TALLOC_CTX *mem_ctx,
                                   struct tevent_context *ev,
                                   uint8_t *buf, size_t len, int fd);
int write_pipe_recv(struct tevent_req *req);

struct tevent_req *read_pipe_send(TALLOC_CTX *mem_ctx,
                                  struct tevent_context *ev, int fd);
int read_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
                   uint8_t **buf, ssize_t *len);

/* The pipes to communicate with the child must be nonblocking */
void fd_nonblocking(int fd);

void child_sig_handler(struct tevent_context *ev,
                       struct tevent_signal *sige, int signum,
                       int count, void *__siginfo, void *pvt);

/* Never returns EOK, ether returns an error, or doesn't return on success */
errno_t exec_child_ex(TALLOC_CTX *mem_ctx,
                      int *pipefd_to_child, int *pipefd_from_child,
                      const char *binary, int debug_fd,
                      const char *extra_argv[],
                      int child_in_fd, int child_out_fd);

/* Same as exec_child_ex() except child_in_fd is set to STDIN_FILENO and
 * child_out_fd is set to STDOUT_FILENO and extra_argv is always NULL.
 */
errno_t exec_child(TALLOC_CTX *mem_ctx,
                   int *pipefd_to_child, int *pipefd_from_child,
                   const char *binary, int debug_fd);

void child_cleanup(int readfd, int writefd);

int child_io_destructor(void *ptr);

errno_t child_debug_init(const char *logfile, int *debug_fd);

#endif /* __CHILD_COMMON_H__ */