summaryrefslogtreecommitdiffstats
path: root/common/exechelp.h
blob: 0370b23a4f34d0508f324380a15d35641490caf7 (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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* exechelp.h - Definitions for the fork and exec helpers
 * Copyright (C) 2004, 2009, 2010 Free Software Foundation, Inc.
 * Copyright (C) 2004, 2006-2012, 2014-2017 g10 Code GmbH
 *
 * This file is part of GnuPG.
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of either
 *
 *   - the GNU Lesser General Public License as published by the Free
 *     Software Foundation; either version 3 of the License, or (at
 *     your option) any later version.
 *
 * or
 *
 *   - the GNU General Public License as published by the Free
 *     Software Foundation; either version 2 of the License, or (at
 *     your option) any later version.
 *
 * or both in parallel, as here.
 *
 * This file 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 <https://www.gnu.org/licenses/>.
 * SPDX-License-Identifier: (LGPL-3.0+ OR GPL-2.0+)
 */

#ifndef GNUPG_COMMON_EXECHELP_H
#define GNUPG_COMMON_EXECHELP_H


/* Return the maximum number of currently allowed file descriptors.
   Only useful on POSIX systems.  */
int get_max_fds (void);


/* Close all file descriptors starting with descriptor FIRST.  If
   EXCEPT is not NULL, it is expected to be a list of file descriptors
   which are not to close.  This list shall be sorted in ascending
   order with its end marked by -1.  */
void close_all_fds (int first, int *except);


/* Returns an array with all currently open file descriptors.  The end
   of the array is marked by -1.  The caller needs to release this
   array using the *standard free* and not with xfree.  This allow the
   use of this function right at startup even before libgcrypt has
   been initialized.  Returns NULL on error and sets ERRNO accordingly.  */
int *get_all_open_fds (void);


/* Portable function to create a pipe.  Under Windows the write end is
   inheritable.  If R_FP is not NULL, an estream is created for the
   write end and stored at R_FP.  */
gpg_error_t gnupg_create_inbound_pipe (int filedes[2],
                                       estream_t *r_fp, int nonblock);

/* Portable function to create a pipe.  Under Windows the read end is
   inheritable.  If R_FP is not NULL, an estream is created for the
   write end and stored at R_FP.  */
gpg_error_t gnupg_create_outbound_pipe (int filedes[2],
                                        estream_t *r_fp, int nonblock);

/* Portable function to create a pipe.  Under Windows both ends are
   inheritable.  */
gpg_error_t gnupg_create_pipe (int filedes[2]);

/* Close the end of a pipe.  */
void gnupg_close_pipe (int fd);


/* The opaque type for a subprocess.  */
typedef struct gnupg_process *gnupg_process_t;
#ifdef HAVE_W32_SYSTEM
struct spawn_cb_arg;
#ifdef NEED_STRUCT_SPAWN_CB_ARG
struct spawn_cb_arg {
  HANDLE hd[3];
  HANDLE *inherit_hds;
  BOOL allow_foreground_window;
  void *arg;
};
#endif
#else
struct spawn_cb_arg {
  int fds[3];
  int *except_fds;
  void *arg;
};
#endif

#define GNUPG_PROCESS_DETACHED            (1 << 1)

/* Specify how to keep/connect standard fds.  */
#define GNUPG_PROCESS_STDIN_PIPE          (1 << 8)
#define GNUPG_PROCESS_STDOUT_PIPE         (1 << 9)
#define GNUPG_PROCESS_STDERR_PIPE         (1 << 10)
#define GNUPG_PROCESS_STDINOUT_SOCKETPAIR (1 << 11)
#define GNUPG_PROCESS_STDIN_KEEP          (1 << 12)
#define GNUPG_PROCESS_STDOUT_KEEP         (1 << 13)
#define GNUPG_PROCESS_STDERR_KEEP         (1 << 14)
#define GNUPG_PROCESS_STDFDS_SETTING  ( GNUPG_PROCESS_STDIN_PIPE  \
  | GNUPG_PROCESS_STDOUT_PIPE         | GNUPG_PROCESS_STDERR_PIPE \
  | GNUPG_PROCESS_STDINOUT_SOCKETPAIR | GNUPG_PROCESS_STDIN_KEEP  \
  | GNUPG_PROCESS_STDOUT_KEEP         | GNUPG_PROCESS_STDERR_KEEP)

#define GNUPG_PROCESS_STREAM_NONBLOCK     (1 << 16)

/* Spawn helper.  */
void gnupg_spawn_helper (struct spawn_cb_arg *sca);

/* Spawn PGMNAME.  */
gpg_err_code_t gnupg_process_spawn (const char *pgmname, const char *argv[],
                                    unsigned int flags,
                                    void (*spawn_cb) (struct spawn_cb_arg *),
                                    void *spawn_cb_arg,
                                    gnupg_process_t *r_process);

/* Get FDs for subprocess I/O.  It is the caller which should care
   FDs (closing FDs).  */
gpg_err_code_t gnupg_process_get_fds (gnupg_process_t process,
                                      unsigned int flags,
                                      int *r_fd_in, int *r_fd_out,
                                      int *r_fd_err);

/* Get STREAMs for subprocess I/O.  It is the caller which should care
   STREAMs (closing STREAMs).  */
gpg_err_code_t gnupg_process_get_streams (gnupg_process_t process,
                                          unsigned int flags,
                                          gpgrt_stream_t *r_fp_in,
                                          gpgrt_stream_t *r_fp_out,
                                          gpgrt_stream_t *r_fp_err);

enum gnupg_process_requests
  {
    /* Portable requests */
    GNUPG_PROCESS_NOP           = 0,
    GNUPG_PROCESS_GET_PROC_ID   = 1,
    GNUPG_PROCESS_GET_EXIT_ID   = 2,

    /* POSIX only */
    GNUPG_PROCESS_GET_PID       = 16,
    GNUPG_PROCESS_GET_WSTATUS   = 17,
    GNUPG_PROCESS_KILL          = 18,

    /* Windows only */
    GNUPG_PROCESS_GET_P_HANDLE  = 32,
    GNUPG_PROCESS_GET_HANDLES   = 33,
    GNUPG_PROCESS_GET_EXIT_CODE = 34,
    GNUPG_PROCESS_KILL_WITH_EC  = 35
  };

/* Control of a process.  */
gpg_err_code_t gnupg_process_ctl (gnupg_process_t process,
                                  unsigned int request, ...);

/* Wait for a single PROCESS.  */
gpg_err_code_t gnupg_process_wait (gnupg_process_t process, int hang);

/* Terminate a PROCESS.  */
gpg_err_code_t gnupg_process_terminate (gnupg_process_t process);

/* Release PROCESS resources.  */
void gnupg_process_release (gnupg_process_t process);

/* Wait for a multiple processes.  */
gpg_err_code_t gnupg_process_wait_list (gnupg_process_t *process_list,
                                        int count, int hang);


#endif /*GNUPG_COMMON_EXECHELP_H*/