ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/Spectre2/Spectre2.cpp
(Generate patch)

Comparing Spectre2/Spectre2.cpp (file contents):
Revision 402 by douglas, 2004-12-29T22:38:37-08:00 vs.
Revision 428 by douglas, 2005-03-24T17:38:00-08:00

# Line 4 | Line 4
4   //
5   // $Id$
6  
7 #include "SignalHandler.hpp"
7   #include "Mounter.hpp"
8   #include "Unmounter.hpp"
10 #include "Matcher/Matcher.hpp"
9  
10   #include <menes-api/exename.hpp>
11 < #include <menes-api/files.hpp>
14 < #include <menes-app/application.hpp>
11 > #include <menes-app/simple.hpp>
12  
16 extern "C"
17 {
13   #include <sys/types.h>
14 < #include <unistd.h>
20 < }
14 > #include <signal.h>
15  
16 < struct Spectre2Command : public app::Application
16 > int Main(const app::Options& options)
17   {
18 <        virtual int Run(const app::ArgumentList& args)
18 >        api::Path config(Spectre2::prefix + "/etc/spectre.xml");
19 >        enum Mode { none, pid = 1, fork } mode(none);
20 >
21 >        _foreach (const app::ArgumentList, arg, app::GetArguments())
22          {
23 <                ext::String config("spectre.xml"), pid("spectre.pid");
27 <                bool fork(false);
23 >                Matcher matcher;
24  
25 <                _foreach (app::ArgumentList, arg, args)
25 >                if (*arg == matcher("^-config=(.*)$"))
26 >                        config = matcher[1];
27 >                else if (*arg == "-pid")
28 >                        mode = pid;
29 >                else if (*arg == "-fork")
30 >                        mode = fork;
31 >                else if (*arg == "-D")
32 >                        Spectre2::debug = true;
33 >                else
34                  {
35 <                        Matcher matcher;
32 <
33 <                        if (*arg == matcher("^-config=(.*)$")) config = matcher[1];
34 <                        else if (*arg == "-fork") fork = true;
35 <                        else if (*arg == matcher("^-pid=(.*)$")) pid = matcher[1];
36 <                        else if (*arg == "-D") Spectre2::debug = true;
37 <                        else
38 <                        {
39 <                                api::Cerr << "Usage: " << Spectre2::program << " [-config=config] [-fork] [-pid=pid] [-D]" << ios::NewLine;
35 >                        api::Cerr << "Usage: " << Spectre2::program << " [-config=config] [-pid|-fork] [-D]" << ios::NewLine;
36  
37 <                                return 1;
42 <                        }
37 >                        return 1;
38                  }
39 +        }
40  
41 <                if (fork && api::Posix::CheckError(::fork())) return 0;
41 >        if (!config.Exists())
42 >        {
43 >                api::Cerr << Spectre2::program << ": configuration file " << config.GetPath() << " does not exist." << ios::NewLine;
44 >
45 >                return 2;
46 >        }
47  
48 <                Spectre2(config, pid);
48 >        switch (mode)
49 >        {
50 >        case pid:
51 >                try
52 >                {
53 >                        _H<xml::Document> document(xml::Parse(config.GetPath()));
54 >                        api::FileReader in(*document/"spectre"/"pid");
55  
56 <                return 0;
56 >                        ios::ReadToWrite(in, api::Cout);
57 >                }
58 >                catch (const api::Error&)
59 >                {
60 >                        return 1;
61 >                }
62 >                break;
63 >        case fork:
64 >                if (api::Posix::CheckError(::fork()))
65 >                        return 0;
66 >        default:
67 >                {
68 >                        Spectre2 spectre(config);
69 >                }
70          }
51 } spectre;
71  
72 < Spectre2::Spectre2(const ext::String& config, const ext::String& pid) : pid(pid)
72 >        return 0;
73 > }
74 >
75 > extern "C"
76   {
77 +        void reload(int signal, ::siginfo_t* info, void* uap);
78 +        void stop(int signal, ::siginfo_t* info, void* uap);
79 + }
80 +
81 + Spectre2::Spectre2(const api::Path& config)
82 + {
83 +        {
84 +                _H<xml::Document> document(xml::Parse(config.GetPath()));
85 +                _H<xml::Node> spectre(*document/"spectre");
86 +
87 +                pid = *spectre/"pid";
88 +                
89 +                if (!(*spectre/"prefix").IsEmpty())
90 +                        prefix = *spectre/"prefix";
91 +
92 +                if (!(*spectre/"root").IsEmpty())
93 +                        root = *spectre/"root";
94 +
95 +                if (!(*spectre/"mount").IsEmpty())
96 +                        mount = *spectre/"mount";
97 +        }
98 +
99          {
100                  api::FileWriter out(pid);
101                  ios::FormatWriter fout(out);
# Line 61 | Line 105 | Spectre2::Spectre2(const ext::String& co
105  
106          Mounter mounter(config);
107          Unmounter unmounter(config);
108 <        Daemon* daemons[] = { static_cast<Daemon*>(&mounter), static_cast<Daemon*>(&unmounter) };
109 <        SignalHandler handler(daemons, sizeof (daemons) / sizeof (*daemons));
108 >
109 >        daemons.InsertLast(dynamic_cast<Daemon*>(&mounter));
110 >        daemons.InsertLast(dynamic_cast<Daemon*>(&unmounter));
111 >
112 >        {
113 >                struct ::sigaction action;
114 >
115 >                action.sa_sigaction = reload;
116 >                action.sa_flags = SA_SIGINFO;
117 >
118 >                api::Posix::CheckError(::sigemptyset(&action.sa_mask));
119 >                api::Posix::CheckError(::sigaction(SIGUSR1, &action, NULL));
120 >
121 >                action.sa_sigaction = stop;
122 >
123 >                api::Posix::CheckError(::sigaction(SIGINT, &action, NULL));
124 >                api::Posix::CheckError(::sigaction(SIGTERM, &action, NULL));
125 >        }
126 >
127 >        _foreach (ext::Vector<Daemon*>, daemon, daemons) (*daemon)->start();
128 >        _foreach (ext::Vector<Daemon*>, daemon, daemons) (*daemon)->wait();
129   }
130  
131   Spectre2::~Spectre2()
# Line 70 | Line 133 | Spectre2::~Spectre2()
133          api::Posix::CheckError(::unlink(pid.NullTerminate()));
134   }
135  
136 < ext::String Spectre2::program(api::GetExecutablePath().GetName());
136 > ext::String Spectre2::program(api::GetExecutablePath().GetName()), Spectre2::prefix(_Spectre2_prefix_), Spectre2::root(_Spectre2_root_), Spectre2::mount(_Spectre2_mount_);
137   bool Spectre2::debug(false);
138 + ext::Vector<Daemon*> Spectre2::daemons;
139 + ext::RedBlackSet<Share> Spectre2::shares;
140 + api::ThreadMutex Spectre2::sharesLock;
141 +
142 + extern "C"
143 + {
144 +        void reload(int signal, ::siginfo_t* info, void* uap)
145 +        {
146 +                _foreach (ext::Vector<Daemon*>, daemon, Spectre2::daemons) (*daemon)->reload();
147 +        }
148 +
149 +        void stop(int signal, ::siginfo_t* info, void* uap)
150 +        {
151 +                _foreach (ext::Vector<Daemon*>, daemon, Spectre2::daemons) (*daemon)->stop();
152 +        }
153 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines