1bac3299720623f4226bca103b26260052732ad30Tom Cherry/*
2bac3299720623f4226bca103b26260052732ad30Tom Cherry * Copyright (C) 2015 The Android Open Source Project
3bac3299720623f4226bca103b26260052732ad30Tom Cherry *
4bac3299720623f4226bca103b26260052732ad30Tom Cherry * Licensed under the Apache License, Version 2.0 (the "License");
5bac3299720623f4226bca103b26260052732ad30Tom Cherry * you may not use this file except in compliance with the License.
6bac3299720623f4226bca103b26260052732ad30Tom Cherry * You may obtain a copy of the License at
7bac3299720623f4226bca103b26260052732ad30Tom Cherry *
8bac3299720623f4226bca103b26260052732ad30Tom Cherry *      http://www.apache.org/licenses/LICENSE-2.0
9bac3299720623f4226bca103b26260052732ad30Tom Cherry *
10bac3299720623f4226bca103b26260052732ad30Tom Cherry * Unless required by applicable law or agreed to in writing, software
11bac3299720623f4226bca103b26260052732ad30Tom Cherry * distributed under the License is distributed on an "AS IS" BASIS,
12bac3299720623f4226bca103b26260052732ad30Tom Cherry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bac3299720623f4226bca103b26260052732ad30Tom Cherry * See the License for the specific language governing permissions and
14bac3299720623f4226bca103b26260052732ad30Tom Cherry * limitations under the License.
15bac3299720623f4226bca103b26260052732ad30Tom Cherry */
16bac3299720623f4226bca103b26260052732ad30Tom Cherry
17bac3299720623f4226bca103b26260052732ad30Tom Cherry#ifndef _INIT_SERVICE_H
18bac3299720623f4226bca103b26260052732ad30Tom Cherry#define _INIT_SERVICE_H
19bac3299720623f4226bca103b26260052732ad30Tom Cherry
20bac3299720623f4226bca103b26260052732ad30Tom Cherry#include <sys/types.h>
21bac3299720623f4226bca103b26260052732ad30Tom Cherry
22bac3299720623f4226bca103b26260052732ad30Tom Cherry#include <cutils/iosched_policy.h>
23bac3299720623f4226bca103b26260052732ad30Tom Cherry
24bac3299720623f4226bca103b26260052732ad30Tom Cherry#include <memory>
25641ff0a4d8d05349d9c22f726a035a2936a2a94dWei Wang#include <set>
26bac3299720623f4226bca103b26260052732ad30Tom Cherry#include <string>
27bac3299720623f4226bca103b26260052732ad30Tom Cherry#include <vector>
28bac3299720623f4226bca103b26260052732ad30Tom Cherry
29bac3299720623f4226bca103b26260052732ad30Tom Cherry#include "action.h"
3024b29132a017f7fbfd009c3e6aec499d1b815dbfJorge Lucangeli Obes#include "capabilities.h"
3162767fe29f8aaf62470781a3cf419ba11187d178Mark Salyzyn#include "descriptors.h"
32b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry#include "init_parser.h"
33b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry#include "keyword_map.h"
349605a945f7a497c0307b512b9cd762f2d23973caElliott Hughes#include "util.h"
35bac3299720623f4226bca103b26260052732ad30Tom Cherry
368d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park#define SVC_DISABLED 0x001        // do not autostart with class
378d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park#define SVC_ONESHOT 0x002         // do not restart on exit
388d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park#define SVC_RUNNING 0x004         // currently active
398d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park#define SVC_RESTARTING 0x008      // waiting to restart
408d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park#define SVC_CONSOLE 0x010         // requires console
418d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park#define SVC_CRITICAL 0x020        // will reboot into recovery if keeps crashing
428d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park#define SVC_RESET 0x040           // Use when stopping a process,
43bac3299720623f4226bca103b26260052732ad30Tom Cherry                                  // but not disabling so it can be restarted with its class.
448d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park#define SVC_RC_DISABLED 0x080     // Remember if the disabled flag was set in the rc script.
458d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park#define SVC_RESTART 0x100         // Use to safely restart (stop, wait, start) a service.
46bac3299720623f4226bca103b26260052732ad30Tom Cherry#define SVC_DISABLED_START 0x200  // A start was requested but it was disabled at the time.
472d80467165f831f86a01e7970d67840a264e2bd8Tom Cherry#define SVC_EXEC 0x400  // This service was started by either 'exec' or 'exec_start' and stops
482d80467165f831f86a01e7970d67840a264e2bd8Tom Cherry                        // init from processing more commands until it completes
498d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park
508d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park#define SVC_SHUTDOWN_CRITICAL 0x800  // This service is critical for shutdown and
518d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park                                     // should not be killed during shutdown
522d80467165f831f86a01e7970d67840a264e2bd8Tom Cherry#define SVC_TEMPORARY 0x1000  // This service was started by 'exec' and should be removed from the
532d80467165f831f86a01e7970d67840a264e2bd8Tom Cherry                              // service list once it is reaped.
54bac3299720623f4226bca103b26260052732ad30Tom Cherry
55bac3299720623f4226bca103b26260052732ad30Tom Cherry#define NR_SVC_SUPP_GIDS 12    // twelve supplementary groups
56bac3299720623f4226bca103b26260052732ad30Tom Cherry
57bac3299720623f4226bca103b26260052732ad30Tom Cherryclass Action;
58bac3299720623f4226bca103b26260052732ad30Tom Cherryclass ServiceManager;
59bac3299720623f4226bca103b26260052732ad30Tom Cherry
60bac3299720623f4226bca103b26260052732ad30Tom Cherrystruct ServiceEnvironmentInfo {
61bac3299720623f4226bca103b26260052732ad30Tom Cherry    ServiceEnvironmentInfo();
62bac3299720623f4226bca103b26260052732ad30Tom Cherry    ServiceEnvironmentInfo(const std::string& name, const std::string& value);
63bac3299720623f4226bca103b26260052732ad30Tom Cherry    std::string name;
64bac3299720623f4226bca103b26260052732ad30Tom Cherry    std::string value;
65bac3299720623f4226bca103b26260052732ad30Tom Cherry};
66bac3299720623f4226bca103b26260052732ad30Tom Cherry
67bac3299720623f4226bca103b26260052732ad30Tom Cherryclass Service {
68641ff0a4d8d05349d9c22f726a035a2936a2a94dWei Wang  public:
69641ff0a4d8d05349d9c22f726a035a2936a2a94dWei Wang    Service(const std::string& name, const std::vector<std::string>& args);
70bac3299720623f4226bca103b26260052732ad30Tom Cherry
71641ff0a4d8d05349d9c22f726a035a2936a2a94dWei Wang    Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
7224b29132a017f7fbfd009c3e6aec499d1b815dbfJorge Lucangeli Obes            const std::vector<gid_t>& supp_gids, const CapSet& capabilities,
7324b29132a017f7fbfd009c3e6aec499d1b815dbfJorge Lucangeli Obes            unsigned namespace_flags, const std::string& seclabel,
7424b29132a017f7fbfd009c3e6aec499d1b815dbfJorge Lucangeli Obes            const std::vector<std::string>& args);
75bac3299720623f4226bca103b26260052732ad30Tom Cherry
768d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park    bool IsRunning() { return (flags_ & SVC_RUNNING) != 0; }
77177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseLine(const std::vector<std::string>& args, std::string* err);
782d80467165f831f86a01e7970d67840a264e2bd8Tom Cherry    bool ExecStart(std::unique_ptr<Timer>* exec_waiter);
79bac3299720623f4226bca103b26260052732ad30Tom Cherry    bool Start();
80bac3299720623f4226bca103b26260052732ad30Tom Cherry    bool StartIfNotDisabled();
81bac3299720623f4226bca103b26260052732ad30Tom Cherry    bool Enable();
82bac3299720623f4226bca103b26260052732ad30Tom Cherry    void Reset();
83bac3299720623f4226bca103b26260052732ad30Tom Cherry    void Stop();
84b7e03e82b89a30b09fea88eaf2a5638df1017cf6Bertrand SIMONNET    void Terminate();
85bac3299720623f4226bca103b26260052732ad30Tom Cherry    void Restart();
869605a945f7a497c0307b512b9cd762f2d23973caElliott Hughes    void RestartIfNeeded(time_t* process_needs_restart_at);
872d80467165f831f86a01e7970d67840a264e2bd8Tom Cherry    void Reap();
88bac3299720623f4226bca103b26260052732ad30Tom Cherry    void DumpState() const;
898d01f63f50fb001f41835a0dab636981f2ba76ddKeun-young Park    void SetShutdownCritical() { flags_ |= SVC_SHUTDOWN_CRITICAL; }
90641ff0a4d8d05349d9c22f726a035a2936a2a94dWei Wang    bool IsShutdownCritical() const { return (flags_ & SVC_SHUTDOWN_CRITICAL) != 0; }
91bac3299720623f4226bca103b26260052732ad30Tom Cherry
92bac3299720623f4226bca103b26260052732ad30Tom Cherry    const std::string& name() const { return name_; }
93641ff0a4d8d05349d9c22f726a035a2936a2a94dWei Wang    const std::set<std::string>& classnames() const { return classnames_; }
94bac3299720623f4226bca103b26260052732ad30Tom Cherry    unsigned flags() const { return flags_; }
95bac3299720623f4226bca103b26260052732ad30Tom Cherry    pid_t pid() const { return pid_; }
963ac3c02b258ac9f9fb794506b519c1beed075bd5Tom Cherry    int crash_count() const { return crash_count_; }
97bac3299720623f4226bca103b26260052732ad30Tom Cherry    uid_t uid() const { return uid_; }
98bac3299720623f4226bca103b26260052732ad30Tom Cherry    gid_t gid() const { return gid_; }
993ac3c02b258ac9f9fb794506b519c1beed075bd5Tom Cherry    unsigned namespace_flags() const { return namespace_flags_; }
100bac3299720623f4226bca103b26260052732ad30Tom Cherry    const std::vector<gid_t>& supp_gids() const { return supp_gids_; }
101bac3299720623f4226bca103b26260052732ad30Tom Cherry    const std::string& seclabel() const { return seclabel_; }
102bac3299720623f4226bca103b26260052732ad30Tom Cherry    const std::vector<int>& keycodes() const { return keycodes_; }
103bac3299720623f4226bca103b26260052732ad30Tom Cherry    int keychord_id() const { return keychord_id_; }
104bac3299720623f4226bca103b26260052732ad30Tom Cherry    void set_keychord_id(int keychord_id) { keychord_id_ = keychord_id; }
1053ac3c02b258ac9f9fb794506b519c1beed075bd5Tom Cherry    IoSchedClass ioprio_class() const { return ioprio_class_; }
1063ac3c02b258ac9f9fb794506b519c1beed075bd5Tom Cherry    int ioprio_pri() const { return ioprio_pri_; }
1073ac3c02b258ac9f9fb794506b519c1beed075bd5Tom Cherry    int priority() const { return priority_; }
1083ac3c02b258ac9f9fb794506b519c1beed075bd5Tom Cherry    int oom_score_adjust() const { return oom_score_adjust_; }
109bac3299720623f4226bca103b26260052732ad30Tom Cherry    const std::vector<std::string>& args() const { return args_; }
110bac3299720623f4226bca103b26260052732ad30Tom Cherry
111641ff0a4d8d05349d9c22f726a035a2936a2a94dWei Wang  private:
112177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    using OptionParser = bool (Service::*) (const std::vector<std::string>& args,
113177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes                                            std::string* err);
114177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    class OptionParserMap;
115b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry
116bac3299720623f4226bca103b26260052732ad30Tom Cherry    void NotifyStateChange(const std::string& new_state) const;
117bac3299720623f4226bca103b26260052732ad30Tom Cherry    void StopOrReset(int how);
118bac3299720623f4226bca103b26260052732ad30Tom Cherry    void ZapStdio() const;
119bac3299720623f4226bca103b26260052732ad30Tom Cherry    void OpenConsole() const;
120ad8e94e017173471e90c704eb7d8de5a14712aa7Elliott Hughes    void KillProcessGroup(int signal);
121344d01f99f6049565e4342b4c4202bd9ab96340bJorge Lucangeli Obes    void SetProcessAttributes();
122bac3299720623f4226bca103b26260052732ad30Tom Cherry
12324b29132a017f7fbfd009c3e6aec499d1b815dbfJorge Lucangeli Obes    bool ParseCapabilities(const std::vector<std::string>& args, std::string *err);
124177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseClass(const std::vector<std::string>& args, std::string* err);
125177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseConsole(const std::vector<std::string>& args, std::string* err);
126177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseCritical(const std::vector<std::string>& args, std::string* err);
127177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseDisabled(const std::vector<std::string>& args, std::string* err);
128177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseGroup(const std::vector<std::string>& args, std::string* err);
129177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParsePriority(const std::vector<std::string>& args, std::string* err);
130177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseIoprio(const std::vector<std::string>& args, std::string* err);
131177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseKeycodes(const std::vector<std::string>& args, std::string* err);
132177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseOneshot(const std::vector<std::string>& args, std::string* err);
133177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseOnrestart(const std::vector<std::string>& args, std::string* err);
134310f6704d0dfe9ca4cfb153ce8e4212cc7596190Marco Nelissen    bool ParseOomScoreAdjust(const std::vector<std::string>& args, std::string* err);
135177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseNamespace(const std::vector<std::string>& args, std::string* err);
136177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseSeclabel(const std::vector<std::string>& args, std::string* err);
137177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseSetenv(const std::vector<std::string>& args, std::string* err);
138177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseSocket(const std::vector<std::string>& args, std::string* err);
13962767fe29f8aaf62470781a3cf419ba11187d178Mark Salyzyn    bool ParseFile(const std::vector<std::string>& args, std::string* err);
140177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseUser(const std::vector<std::string>& args, std::string* err);
141177b27d4f5bfa498cc46aad24d9375d65630bea0Jorge Lucangeli Obes    bool ParseWritepid(const std::vector<std::string>& args, std::string* err);
142b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry
14362767fe29f8aaf62470781a3cf419ba11187d178Mark Salyzyn    template <typename T>
14462767fe29f8aaf62470781a3cf419ba11187d178Mark Salyzyn    bool AddDescriptor(const std::vector<std::string>& args, std::string* err);
14562767fe29f8aaf62470781a3cf419ba11187d178Mark Salyzyn
146bac3299720623f4226bca103b26260052732ad30Tom Cherry    std::string name_;
147641ff0a4d8d05349d9c22f726a035a2936a2a94dWei Wang    std::set<std::string> classnames_;
14870daa67062c016eea1a30be2e1de0dcba1d23a13Viorel Suman    std::string console_;
149bac3299720623f4226bca103b26260052732ad30Tom Cherry
150bac3299720623f4226bca103b26260052732ad30Tom Cherry    unsigned flags_;
151bac3299720623f4226bca103b26260052732ad30Tom Cherry    pid_t pid_;
152c8ac0677734270f0b12d85ecf23b1de49054890cJames Hawkins    boot_clock::time_point time_started_; // time of last start
153c8ac0677734270f0b12d85ecf23b1de49054890cJames Hawkins    boot_clock::time_point time_crashed_; // first crash within inspection window
1549605a945f7a497c0307b512b9cd762f2d23973caElliott Hughes    int crash_count_;                     // number of times crashed within window
155bac3299720623f4226bca103b26260052732ad30Tom Cherry
156bac3299720623f4226bca103b26260052732ad30Tom Cherry    uid_t uid_;
157bac3299720623f4226bca103b26260052732ad30Tom Cherry    gid_t gid_;
158bac3299720623f4226bca103b26260052732ad30Tom Cherry    std::vector<gid_t> supp_gids_;
15924b29132a017f7fbfd009c3e6aec499d1b815dbfJorge Lucangeli Obes    CapSet capabilities_;
1601b3fa3d6506d04570aab60147b0ec743e38c8796Jorge Lucangeli Obes    unsigned namespace_flags_;
161bac3299720623f4226bca103b26260052732ad30Tom Cherry
162bac3299720623f4226bca103b26260052732ad30Tom Cherry    std::string seclabel_;
163bac3299720623f4226bca103b26260052732ad30Tom Cherry
16462767fe29f8aaf62470781a3cf419ba11187d178Mark Salyzyn    std::vector<std::unique_ptr<DescriptorInfo>> descriptors_;
165bac3299720623f4226bca103b26260052732ad30Tom Cherry    std::vector<ServiceEnvironmentInfo> envvars_;
166bac3299720623f4226bca103b26260052732ad30Tom Cherry
167bac3299720623f4226bca103b26260052732ad30Tom Cherry    Action onrestart_;  // Commands to execute on restart.
168bac3299720623f4226bca103b26260052732ad30Tom Cherry
169bac3299720623f4226bca103b26260052732ad30Tom Cherry    std::vector<std::string> writepid_files_;
170bac3299720623f4226bca103b26260052732ad30Tom Cherry
171bac3299720623f4226bca103b26260052732ad30Tom Cherry    // keycodes for triggering this service via /dev/keychord
172bac3299720623f4226bca103b26260052732ad30Tom Cherry    std::vector<int> keycodes_;
173bac3299720623f4226bca103b26260052732ad30Tom Cherry    int keychord_id_;
174bac3299720623f4226bca103b26260052732ad30Tom Cherry
175bac3299720623f4226bca103b26260052732ad30Tom Cherry    IoSchedClass ioprio_class_;
176bac3299720623f4226bca103b26260052732ad30Tom Cherry    int ioprio_pri_;
177081705c258efbe938d71c2022528d809fa6d42c5Vitalii Tomkiv    int priority_;
178bac3299720623f4226bca103b26260052732ad30Tom Cherry
179310f6704d0dfe9ca4cfb153ce8e4212cc7596190Marco Nelissen    int oom_score_adjust_;
180310f6704d0dfe9ca4cfb153ce8e4212cc7596190Marco Nelissen
181bac3299720623f4226bca103b26260052732ad30Tom Cherry    std::vector<std::string> args_;
182bac3299720623f4226bca103b26260052732ad30Tom Cherry};
183bac3299720623f4226bca103b26260052732ad30Tom Cherry
184bac3299720623f4226bca103b26260052732ad30Tom Cherryclass ServiceManager {
185bac3299720623f4226bca103b26260052732ad30Tom Cherrypublic:
186bac3299720623f4226bca103b26260052732ad30Tom Cherry    static ServiceManager& GetInstance();
187bac3299720623f4226bca103b26260052732ad30Tom Cherry
1883ac3c02b258ac9f9fb794506b519c1beed075bd5Tom Cherry    // Exposed for testing
1893ac3c02b258ac9f9fb794506b519c1beed075bd5Tom Cherry    ServiceManager();
1903ac3c02b258ac9f9fb794506b519c1beed075bd5Tom Cherry
191b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    void AddService(std::unique_ptr<Service> service);
192bac3299720623f4226bca103b26260052732ad30Tom Cherry    Service* MakeExecOneshotService(const std::vector<std::string>& args);
1932d80467165f831f86a01e7970d67840a264e2bd8Tom Cherry    bool Exec(const std::vector<std::string>& args);
1942d80467165f831f86a01e7970d67840a264e2bd8Tom Cherry    bool ExecStart(const std::string& name);
1952d80467165f831f86a01e7970d67840a264e2bd8Tom Cherry    bool IsWaitingForExec() const;
196bac3299720623f4226bca103b26260052732ad30Tom Cherry    Service* FindServiceByName(const std::string& name) const;
197bac3299720623f4226bca103b26260052732ad30Tom Cherry    Service* FindServiceByPid(pid_t pid) const;
198bac3299720623f4226bca103b26260052732ad30Tom Cherry    Service* FindServiceByKeychord(int keychord_id) const;
1998f7b9e3d39cdae8363816aa7bcbab0d79fd70ceaChih-Hung Hsieh    void ForEachService(const std::function<void(Service*)>& callback) const;
200bac3299720623f4226bca103b26260052732ad30Tom Cherry    void ForEachServiceInClass(const std::string& classname,
201bac3299720623f4226bca103b26260052732ad30Tom Cherry                               void (*func)(Service* svc)) const;
202bac3299720623f4226bca103b26260052732ad30Tom Cherry    void ForEachServiceWithFlags(unsigned matchflags,
203bac3299720623f4226bca103b26260052732ad30Tom Cherry                             void (*func)(Service* svc)) const;
204b7e03e82b89a30b09fea88eaf2a5638df1017cf6Bertrand SIMONNET    void ReapAnyOutstandingChildren();
205bac3299720623f4226bca103b26260052732ad30Tom Cherry    void RemoveService(const Service& svc);
206bac3299720623f4226bca103b26260052732ad30Tom Cherry    void DumpState() const;
207b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry
208bac3299720623f4226bca103b26260052732ad30Tom Cherryprivate:
209b7e03e82b89a30b09fea88eaf2a5638df1017cf6Bertrand SIMONNET    // Cleans up a child process that exited.
210b7e03e82b89a30b09fea88eaf2a5638df1017cf6Bertrand SIMONNET    // Returns true iff a children was cleaned up.
211b7e03e82b89a30b09fea88eaf2a5638df1017cf6Bertrand SIMONNET    bool ReapOneProcess();
212b7e03e82b89a30b09fea88eaf2a5638df1017cf6Bertrand SIMONNET
213bac3299720623f4226bca103b26260052732ad30Tom Cherry    static int exec_count_; // Every service needs a unique name.
2142d80467165f831f86a01e7970d67840a264e2bd8Tom Cherry    std::unique_ptr<Timer> exec_waiter_;
2152d80467165f831f86a01e7970d67840a264e2bd8Tom Cherry
216bac3299720623f4226bca103b26260052732ad30Tom Cherry    std::vector<std::unique_ptr<Service>> services_;
217bac3299720623f4226bca103b26260052732ad30Tom Cherry};
218bac3299720623f4226bca103b26260052732ad30Tom Cherry
219b7349902a945903f9e36a569051f5131beb0bc24Tom Cherryclass ServiceParser : public SectionParser {
220b7349902a945903f9e36a569051f5131beb0bc24Tom Cherrypublic:
221b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    ServiceParser() : service_(nullptr) {
222b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    }
223b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    bool ParseSection(const std::vector<std::string>& args,
224b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry                      std::string* err) override;
225b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    bool ParseLineSection(const std::vector<std::string>& args,
226b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry                          const std::string& filename, int line,
227b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry                          std::string* err) const override;
228b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    void EndSection() override;
229b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    void EndFile(const std::string&) override {
230b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    }
231b7349902a945903f9e36a569051f5131beb0bc24Tom Cherryprivate:
232b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    bool IsValidName(const std::string& name) const;
233b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry
234b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    std::unique_ptr<Service> service_;
235b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry};
236b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry
237bac3299720623f4226bca103b26260052732ad30Tom Cherry#endif
238