1 /****************************************************************************
2  * bfs                                                                      *
3  * Copyright (C) 2018-2019 Tavian Barnes <tavianator@tavianator.com>        *
4  *                                                                          *
5  * Permission to use, copy, modify, and/or distribute this software for any *
6  * purpose with or without fee is hereby granted.                           *
7  *                                                                          *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES *
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF         *
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR  *
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   *
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN    *
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  *
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.           *
15  ****************************************************************************/
16 
17 /**
18  * A process-spawning library inspired by posix_spawn().
19  */
20 
21 #ifndef BFS_SPAWN_H
22 #define BFS_SPAWN_H
23 
24 #include <sys/resource.h>
25 #include <sys/types.h>
26 
27 /**
28  * bfs_spawn() flags.
29  */
30 enum bfs_spawn_flags {
31 	/** Use the PATH variable to resolve the executable (like execvp()). */
32 	BFS_SPAWN_USEPATH = 1 << 0,
33 };
34 
35 /**
36  * bfs_spawn() attributes, controlling the context of the new process.
37  */
38 struct bfs_spawn {
39 	enum bfs_spawn_flags flags;
40 	struct bfs_spawn_action *actions;
41 	struct bfs_spawn_action **tail;
42 };
43 
44 /**
45  * Create a new bfs_spawn() context.
46  *
47  * @return 0 on success, -1 on failure.
48  */
49 int bfs_spawn_init(struct bfs_spawn *ctx);
50 
51 /**
52  * Destroy a bfs_spawn() context.
53  *
54  * @return 0 on success, -1 on failure.
55  */
56 int bfs_spawn_destroy(struct bfs_spawn *ctx);
57 
58 /**
59  * Set the flags for a bfs_spawn() context.
60  *
61  * @return 0 on success, -1 on failure.
62  */
63 int bfs_spawn_setflags(struct bfs_spawn *ctx, enum bfs_spawn_flags flags);
64 
65 /**
66  * Add a close() action to a bfs_spawn() context.
67  *
68  * @return 0 on success, -1 on failure.
69  */
70 int bfs_spawn_addclose(struct bfs_spawn *ctx, int fd);
71 
72 /**
73  * Add a dup2() action to a bfs_spawn() context.
74  *
75  * @return 0 on success, -1 on failure.
76  */
77 int bfs_spawn_adddup2(struct bfs_spawn *ctx, int oldfd, int newfd);
78 
79 /**
80  * Add an fchdir() action to a bfs_spawn() context.
81  *
82  * @return 0 on success, -1 on failure.
83  */
84 int bfs_spawn_addfchdir(struct bfs_spawn *ctx, int fd);
85 
86 /**
87  * Add a setrlimit() action to a bfs_spawn() context.
88  *
89  * @return 0 on success, -1 on failure.
90  */
91 int bfs_spawn_addsetrlimit(struct bfs_spawn *ctx, int resource, const struct rlimit *rl);
92 
93 /**
94  * Spawn a new process.
95  *
96  * @param exe
97  *         The executable to run.
98  * @param ctx
99  *         The context for the new process.
100  * @param argv
101  *         The arguments for the new process.
102  * @param envp
103  *         The environment variables for the new process (NULL for the current
104  *         environment).
105  * @return
106  *         The PID of the new process, or -1 on error.
107  */
108 pid_t bfs_spawn(const char *exe, const struct bfs_spawn *ctx, char **argv, char **envp);
109 
110 /**
111  * Look up an executable in the current PATH, as BFS_SPAWN_USEPATH or execvp()
112  * would do.
113  *
114  * @param exe
115  *         The name of the binary to execute.  Bare names without a '/' will be
116  *         searched on the provided PATH.
117  * @return
118  *         The full path to the executable, which should be free()'d, or NULL on
119  *         failure.
120  */
121 char *bfs_spawn_resolve(const char *exe);
122 
123 #endif // BFS_SPAWN_H
124