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
135
136
137
138
139
140
141
142
143
144
145
|
/*
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 2048
#define CHILD_MSG_CHUNK 1024
#define SIGTERM_TO_SIGKILL_TIME 2
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;
pid_t pid;
bool child_exited;
bool in_use;
};
/* 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);
/* 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);
errno_t read_pipe_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
uint8_t **_buf,
ssize_t *_len);
/* Include buffer length in a message header, read does not wait for EOF. */
struct tevent_req *write_pipe_safe_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
uint8_t *buf,
size_t len,
int fd);
int write_pipe_safe_recv(struct tevent_req *req);
struct tevent_req *read_pipe_safe_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
int fd);
errno_t read_pipe_safe_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);
/* Never returns EOK, ether returns an error, or doesn't return on success */
void exec_child_ex(TALLOC_CTX *mem_ctx,
int *pipefd_to_child, int *pipefd_from_child,
const char *binary, const char *logfile,
const char *extra_argv[], bool extra_args_only,
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.
*/
void exec_child(TALLOC_CTX *mem_ctx,
int *pipefd_to_child, int *pipefd_from_child,
const char *binary, const char *logfile);
int child_io_destructor(void *ptr);
#endif /* __CHILD_COMMON_H__ */
|