OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.6/] [tools/] [src/] [librutiltpp/] [RtclSystem.cpp] - Blame information for rev 40

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 22 wfjm
// $Id: RtclSystem.cpp 521 2013-05-20 22:16:45Z mueller $
2
//
3
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
//
5
// This program is free software; you may redistribute and/or modify it under
6
// the terms of the GNU General Public License as published by the Free
7
// Software Foundation, either version 2, or at your option any later version.
8
//
9
// This program is distributed in the hope that it will be useful, but
10
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
// for complete details.
13
// 
14
// Revision History: 
15
// Date         Rev Version  Comment
16
// 2013-05-17   521   1.0    Initial version
17
// ---------------------------------------------------------------------------
18
 
19
/*!
20
  \file
21
  \version $Id: RtclSystem.cpp 521 2013-05-20 22:16:45Z mueller $
22
  \brief   Implemenation of RtclSystem.
23
*/
24
 
25
#include <unistd.h>
26
#include <errno.h>
27
#include <string.h>
28
#include <sys/types.h>
29
#include <sys/wait.h>
30
 
31
#include <iostream>
32
#include <string>
33
#include <algorithm>
34
 
35
#include "librtools/RerrMsg.hpp"
36
#include "librtcltools/RtclArgs.hpp"
37
 
38
#include "RtclSignalAction.hpp"
39
 
40
#include "RtclSystem.hpp"
41
 
42
using namespace std;
43
 
44
/*!
45
  \class Retro::RtclSystem
46
  \brief FIXME_docs
47
*/
48
 
49
// all method definitions in namespace Retro
50
namespace Retro {
51
 
52
static const int kOK  = TCL_OK;
53
static const int kERR = TCL_ERROR;
54
 
55
//------------------------------------------+-----------------------------------
56
//! FIXME_docs
57
 
58
void RtclSystem::CreateCmds(Tcl_Interp* interp)
59
{
60
  Tcl_CreateObjCommand(interp, "rutil::isatty", Isatty,
61
                       (ClientData) 0, NULL);
62
  Tcl_CreateObjCommand(interp, "rutil::sigaction", SignalAction,
63
                       (ClientData) 0, NULL);
64
  Tcl_CreateObjCommand(interp, "rutil::waitpid", WaitPid,
65
                       (ClientData) 0, NULL);
66
  return;
67
}
68
 
69
//------------------------------------------+-----------------------------------
70
//! FIXME_docs
71
 
72
int RtclSystem::Isatty(ClientData cdata, Tcl_Interp* interp,
73
                       int objc, Tcl_Obj* const objv[])
74
{
75
  RtclArgs args(interp, objc, objv);
76
  string file = "stdin";
77
  if (!args.GetArg("?file", file)) return kERR;
78
  if (!args.AllDone()) return kERR;
79
 
80
  transform(file.begin(), file.end(), file.begin(), ::tolower);
81
  int fileno = -1;
82
  if (file == "stdin")  fileno = STDIN_FILENO;
83
  if (file == "stdout") fileno = STDOUT_FILENO;
84
  if (file == "stderr") fileno = STDERR_FILENO;
85
  if (fileno == -1) return args.Quit("file must be stdin, stdout, or stderr");
86
 
87
  args.SetResult(bool(::isatty(fileno)));
88
 
89
  return kOK;
90
}
91
 
92
//------------------------------------------+-----------------------------------
93
 
94
static int signam2num(const std::string& signam)
95
{
96
  string sn = signam;
97
  transform(sn.begin(), sn.end(), sn.begin(), ::toupper);
98
  if (sn == "SIGHUP")  return SIGHUP;
99
  if (sn == "SIGINT")  return SIGINT;
100
  if (sn == "SIGTERM") return SIGTERM;
101
  if (sn == "SIGUSR1") return SIGUSR1;
102
  if (sn == "SIGUSR2") return SIGUSR2;
103
  return -1;
104
}
105
 
106
static const char* signum2nam(int signum)
107
{
108
  if (signum == SIGHUP)  return "SIGHUP";
109
  if (signum == SIGINT)  return "SIGINT";
110
  if (signum == SIGTERM) return "SIGTERM";
111
  if (signum == SIGUSR1) return "SIGUSR1";
112
  if (signum == SIGUSR2) return "SIGUSR2";
113
  return "???";
114
}
115
 
116
//------------------------------------------+-----------------------------------
117
//! FIXME_docs
118
 
119
int RtclSystem::SignalAction(ClientData cdata, Tcl_Interp* interp,
120
                             int objc, Tcl_Obj* const objv[])
121
{
122
  RtclArgs args(interp, objc, objv);
123
  RerrMsg emsg;
124
 
125
  // check if initialized, if not, do it
126
  if (!RtclSignalAction::Obj()) {
127
    RerrMsg emsg;
128
    if (!RtclSignalAction::Init(interp, emsg)) return args.Quit(emsg);
129
  }
130
  RtclSignalAction* pact = RtclSignalAction::Obj();
131
 
132
  // blank 'sigaction' is a noop (initialize as side effect)
133
  if (objc == 1) return kOK;
134
 
135
  // handle cases with only options (no signal name first)
136
 
137
  if (args.PeekArgString(0)[0] == '-') {
138
    static RtclNameSet optset("-init|-info");
139
    string opt;
140
    if (args.NextOpt(opt, optset)) {
141
 
142
      if        (opt == "-init") {          // -init
143
        if (!args.AllDone()) return kERR;
144
        return kOK;
145
 
146
      } else if (opt == "-info") {          // -info
147
        RtclOPtr pres(Tcl_NewListObj(0,0));
148
        int siglist[] = {SIGHUP,SIGINT,SIGTERM,SIGUSR1,SIGUSR2};
149
        for (size_t i=0; i<sizeof(siglist)/sizeof(int); i++) {
150
          Tcl_Obj* pobj;
151
          if (pact->GetAction(siglist[i], pobj, emsg)) {
152
            RtclOPtr pele(Tcl_NewListObj(0,0));
153
            Tcl_ListObjAppendElement(NULL, pele,
154
                     Tcl_NewStringObj(signum2nam(siglist[i]),-1));
155
            if (pobj) {
156
              Tcl_ListObjAppendElement(NULL, pele, pobj);
157
            } else {
158
              Tcl_ListObjAppendElement(NULL, pele, Tcl_NewStringObj("{}",-1));
159
            }
160
            Tcl_ListObjAppendElement(NULL, pres, pele);
161
          }
162
        }
163
        args.SetResult(pres);
164
        return kOK;
165
      }
166
    }
167
    if (!args.OptValid()) return kERR;
168
    if (!args.AllDone()) return kERR;
169
    return kERR;
170
  }
171
 
172
  // handle cases which start with a signal name
173
 
174
  string signam;
175
  if (!args.GetArg("signam", signam)) return kERR;
176
  int signum = signam2num(signam);
177
  if (signum < 0) return args.Quit("invalid signal name");
178
 
179
  static RtclNameSet optset("-action|-revert");
180
  string opt;
181
  if (args.NextOpt(opt, optset)) {
182
    if        (opt == "-action") {          // signam -action script
183
      string script;
184
      if (!args.GetArg("script", script)) return kERR;
185
      if (!args.AllDone()) return kERR;
186
      RtclOPtr pobj(Tcl_NewStringObj(script.c_str(), -1));
187
      if (!pact->SetAction(signum, pobj, emsg))
188
        return args.Quit(emsg);
189
 
190
    } else if (opt == "-revert") {          // signam -revert
191
      if (!args.AllDone()) return kERR;
192
      if (!pact->ClearAction(signum, emsg))
193
        return args.Quit(emsg);
194
    }
195
 
196
  } else {                                  // signam
197
    if (!args.OptValid()) return kERR;
198
    if (!args.AllDone()) return kERR;
199
    Tcl_Obj* pobj;
200
    if (!pact->GetAction(signum, pobj, emsg))
201
      return args.Quit("no handler defined");
202
    if (pobj == 0) pobj = Tcl_NewStringObj("{}",-1);
203
    args.SetResult(pobj);
204
  }
205
 
206
  return kOK;
207
}
208
 
209
//------------------------------------------+-----------------------------------
210
//! FIXME_docs
211
 
212
int RtclSystem::WaitPid(ClientData cdata, Tcl_Interp* interp,
213
                        int objc, Tcl_Obj* const objv[])
214
{
215
  RtclArgs args(interp, objc, objv);
216
  int pid;
217
  if (!args.GetArg("pid", pid)) return kERR;
218
  if (!args.AllDone()) return kERR;
219
 
220
  int status;
221
  int irc = ::waitpid(pid, &status, WNOHANG);
222
  if (irc < 0) {
223
    RerrMsg emsg("RtclSystem::WaitPid", "waitpid() failed: ", errno);
224
    return args.Quit(emsg);
225
  }
226
  args.SetResult(status);
227
  return kOK;
228
}
229
 
230
 
231
} // end namespace Retro

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.