summaryrefslogtreecommitdiff
path: root/execute.h
blob: d8073e14b022cbf21ef595ae597f61458715badc (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
176
177
178
/*-*- Mode: C; c-basic-offset: 8 -*-*/

#ifndef fooexecutehfoo
#define fooexecutehfoo

/***
  This file is part of systemd.

  Copyright 2010 Lennart Poettering

  systemd 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 2 of the License, or
  (at your option) any later version.

  systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
***/

typedef struct ExecStatus ExecStatus;
typedef struct ExecCommand ExecCommand;
typedef struct ExecContext ExecContext;

#include <sys/time.h>
#include <sys/resource.h>
#include <sys/capability.h>
#include <stdbool.h>
#include <stdio.h>
#include <sched.h>

#include "list.h"
#include "util.h"

/* Abstract namespace! */
#define LOGGER_SOCKET "/org/freedesktop/systemd1/logger"

typedef enum ExecOutput {
        EXEC_OUTPUT_CONSOLE,
        EXEC_OUTPUT_NULL,
        EXEC_OUTPUT_SYSLOG,
        EXEC_OUTPUT_KERNEL,
        _EXEC_OUTPUT_MAX,
        _EXEC_OUTPUT_INVALID = -1
} ExecOutput;

typedef enum ExecInput {
        EXEC_INPUT_NULL,
        EXEC_INPUT_CONSOLE,
        _EXEC_INPUT_MAX,
        _EXEC_INPUT_INVALID = -1
} ExecInput;

struct ExecStatus {
        pid_t pid;
        usec_t timestamp;
        int code;     /* as in siginfo_t::si_code */
        int status;   /* as in sigingo_t::si_status */
};

struct ExecCommand {
        char *path;
        char **argv;
        ExecStatus exec_status;
        LIST_FIELDS(ExecCommand, command); /* useful for chaining commands */
};

struct ExecContext {
        char **environment;
        mode_t umask;
        struct rlimit *rlimit[RLIMIT_NLIMITS];
        char *working_directory, *root_directory;
        int oom_adjust;
        int nice;
        int ioprio;
        int cpu_sched_policy;
        int cpu_sched_priority;
        cpu_set_t cpu_affinity;
        unsigned long timer_slack_ns;

        bool oom_adjust_set:1;
        bool nice_set:1;
        bool ioprio_set:1;
        bool cpu_sched_set:1;
        bool cpu_affinity_set:1;
        bool timer_slack_ns_set:1;

        bool cpu_sched_reset_on_fork;
        bool non_blocking;

        ExecInput input;
        ExecOutput output;
        int syslog_priority;
        char *syslog_identifier;

        cap_t capabilities;
        int secure_bits;
        uint64_t capability_bounding_set_drop;

        /* Since resolving these names might might involve socket
         * connections and we don't want to deadlock ourselves these
         * names are resolved on execution only and in the child
         * process. */
        char *user;
        char *group;
        char **supplementary_groups;
};

typedef enum ExitStatus {
        /* EXIT_SUCCESS defined by libc */
        /* EXIT_FAILURE defined by libc */
        EXIT_INVALIDARGUMENT = 2,
        EXIT_NOTIMPLEMENTED = 3,
        EXIT_NOPERMISSION = 4,
        EXIT_NOTINSTALLED = 5,
        EXIT_NOTCONFIGURED = 6,
        EXIT_NOTRUNNING = 7,

        /* The LSB suggests that error codes >= 200 are "reserved". We
         * use them here under the assumption that they hence are
         * unused by init scripts.
         *
         * http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html */

        EXIT_CHDIR = 200,
        EXIT_NICE,
        EXIT_FDS,
        EXIT_EXEC,
        EXIT_MEMORY,
        EXIT_LIMITS,
        EXIT_OOM_ADJUST,
        EXIT_SIGNAL_MASK,
        EXIT_INPUT,
        EXIT_OUTPUT,
        EXIT_CHROOT,   /* 210 */
        EXIT_PGID,
        EXIT_IOPRIO,
        EXIT_TIMERSLACK,
        EXIT_SECUREBITS,
        EXIT_SETSCHEDULER,
        EXIT_CPUAFFINITY,
        EXIT_GROUP,
        EXIT_USER,
        EXIT_CAPABILITIES
} ExitStatus;

int exec_spawn(const ExecCommand *command,
               const ExecContext *context,
               int *fds, unsigned n_fds,
               bool apply_permissions,
               bool apply_chroot,
               pid_t *ret);

void exec_command_free_list(ExecCommand *c);
void exec_command_free_array(ExecCommand **c, unsigned n);

char *exec_command_line(ExecCommand *c);
void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix);
void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix);
void exec_command_append_list(ExecCommand **l, ExecCommand *e);

void exec_context_init(ExecContext *c);
void exec_context_done(ExecContext *c);
void exec_context_dump(ExecContext *c, FILE* f, const char *prefix);

void exec_status_fill(ExecStatus *s, pid_t pid, int code, int status);

const char* exec_output_to_string(ExecOutput i);
int exec_output_from_string(const char *s);

const char* exec_input_to_string(ExecInput i);
int exec_input_from_string(const char *s);

#endif