attempted to fix various problems related to signals in App
This commit is contained in:
parent
7bfba716f6
commit
9764d448af
@ -39,7 +39,15 @@ QSE_BEGIN_NAMESPACE(QSE)
|
|||||||
class App: public Uncopyable, public Types, public Mmged
|
class App: public Uncopyable, public Types, public Mmged
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef QSE::Bitset<QSE_NSIGS> Sigset;
|
typedef QSE::Bitset<QSE_NSIGS> SignalSet;
|
||||||
|
|
||||||
|
enum SignalState
|
||||||
|
{
|
||||||
|
SIGNAL_UNHANDLED,
|
||||||
|
SIGNAL_ACCEPTED,
|
||||||
|
SIGNAL_IGNORED // handled but ignored
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
App (Mmgr* mmgr) QSE_CPP_NOEXCEPT;
|
App (Mmgr* mmgr) QSE_CPP_NOEXCEPT;
|
||||||
virtual ~App () QSE_CPP_NOEXCEPT;
|
virtual ~App () QSE_CPP_NOEXCEPT;
|
||||||
@ -56,10 +64,18 @@ public:
|
|||||||
|
|
||||||
virtual void on_signal (int sig) { }
|
virtual void on_signal (int sig) { }
|
||||||
|
|
||||||
int subscribeToSignal (int sig, bool accept);
|
SignalState getSignalSubscription (int sig) const;
|
||||||
int subscribeToAllSignals (bool accept);
|
int setSignalSubscription (int sig, SignalState ss);
|
||||||
void unsubscribeFromSignal (int sig);
|
|
||||||
void unsubscribeFromAllSignals ();
|
int subscribeToSignal (int sig, bool accept)
|
||||||
|
{
|
||||||
|
return this->setSignalSubscription (sig, (accept? SIGNAL_ACCEPTED: SIGNAL_IGNORED));
|
||||||
|
}
|
||||||
|
int unsubscribeFromSignal (int sig)
|
||||||
|
{
|
||||||
|
return this->setSignalSubscription (sig, SIGNAL_UNHANDLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef void (*SignalHandler) (int sig);
|
typedef void (*SignalHandler) (int sig);
|
||||||
static qse_size_t _sighrs[2][QSE_NSIGS];
|
static qse_size_t _sighrs[2][QSE_NSIGS];
|
||||||
@ -73,7 +89,7 @@ public:
|
|||||||
static int setSignalHandler (int sig, SignalHandler sighr);
|
static int setSignalHandler (int sig, SignalHandler sighr);
|
||||||
static int unsetSignalHandler (int sig);
|
static int unsetSignalHandler (int sig);
|
||||||
|
|
||||||
int guardProcess (const qse_mchar_t* proc_name, const Sigset& signals);
|
int guardProcess (const qse_mchar_t* proc_name, const SignalSet& signals);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
App* _prev_app;
|
App* _prev_app;
|
||||||
@ -81,17 +97,10 @@ private:
|
|||||||
|
|
||||||
struct _SigLink
|
struct _SigLink
|
||||||
{
|
{
|
||||||
enum State
|
_SigLink(): _prev(QSE_NULL), _next(QSE_NULL), _state(SIGNAL_UNHANDLED) {}
|
||||||
{
|
|
||||||
UNHANDLED,
|
|
||||||
ACCEPTED,
|
|
||||||
IGNORED // handled but ignored
|
|
||||||
};
|
|
||||||
|
|
||||||
_SigLink(): _prev(QSE_NULL), _next(QSE_NULL), _state(UNHANDLED) {}
|
|
||||||
App* _prev;
|
App* _prev;
|
||||||
App* _next;
|
App* _next;
|
||||||
State _state;
|
SignalState _state;
|
||||||
};
|
};
|
||||||
|
|
||||||
_SigLink _sig[QSE_NSIGS];
|
_SigLink _sig[QSE_NSIGS];
|
||||||
@ -101,7 +110,9 @@ protected:
|
|||||||
static int set_signal_handler_no_mutex (int sig, SignalHandler sighr);
|
static int set_signal_handler_no_mutex (int sig, SignalHandler sighr);
|
||||||
static int unset_signal_handler_no_mutex (int sig);
|
static int unset_signal_handler_no_mutex (int sig);
|
||||||
|
|
||||||
int subscribe_to_signal_no_mutex (int sig, _SigLink::State reqstate);
|
int set_signal_subscription_no_mutex (int sig, SignalState reqstate);
|
||||||
|
|
||||||
|
int subscribe_to_signal_no_mutex (int sig, SignalState reqstate);
|
||||||
void unsubscribe_from_signal_no_mutex (int sig);
|
void unsubscribe_from_signal_no_mutex (int sig);
|
||||||
void unsubscribe_from_all_signals_no_mutex ();
|
void unsubscribe_from_all_signals_no_mutex ();
|
||||||
|
|
||||||
|
@ -261,7 +261,11 @@ int App::unset_signal_handler_no_mutex(int sig)
|
|||||||
if (sa.sa_flags & SA_SIGINFO)
|
if (sa.sa_flags & SA_SIGINFO)
|
||||||
sa.sa_sigaction = (void(*)(int,siginfo_t*,void*))App::_sighrs[1][sig];
|
sa.sa_sigaction = (void(*)(int,siginfo_t*,void*))App::_sighrs[1][sig];
|
||||||
else
|
else
|
||||||
|
{
|
||||||
sa.sa_handler = (SignalHandler)App::_sighrs[1][sig];
|
sa.sa_handler = (SignalHandler)App::_sighrs[1][sig];
|
||||||
|
printf ("unset signal handler......\n");
|
||||||
|
sa.sa_handler = SIG_IGN;
|
||||||
|
}
|
||||||
|
|
||||||
if (::sigaction (sig, &sa, QSE_NULL) <= -1) return -1;
|
if (::sigaction (sig, &sa, QSE_NULL) <= -1) return -1;
|
||||||
|
|
||||||
@ -279,13 +283,13 @@ int App::unset_signal_handler_no_mutex(int sig)
|
|||||||
{
|
{
|
||||||
App::_SigLink& sl = app->_sig[sig];
|
App::_SigLink& sl = app->_sig[sig];
|
||||||
App* next = sl._next;
|
App* next = sl._next;
|
||||||
if (sl._state == App::_SigLink::ACCEPTED)
|
if (sl._state == App::SIGNAL_ACCEPTED)
|
||||||
{
|
{
|
||||||
// the actual signal handler is called with the mutex locked.
|
// the actual signal handler is called with the mutex locked.
|
||||||
// it must not call subscribeToSingal() or unsubscribeFromSingal()
|
// it must not call subscribeToSingal() or unsubscribeFromSingal()
|
||||||
// from within the handler.
|
// from within the handler.
|
||||||
if (app->_guarded_child_pid >= 0) app->on_guard_signal (sig);
|
if (app->_guarded_child_pid >= 0) app->on_guard_signal (sig);
|
||||||
else app->on_signal (sig);
|
else app->on_signal (sig);
|
||||||
}
|
}
|
||||||
app = next;
|
app = next;
|
||||||
}
|
}
|
||||||
@ -297,73 +301,68 @@ printf ("relaying %d to %d\n", sig, (int)this->_guarded_child_pid);
|
|||||||
::kill (this->_guarded_child_pid, sig);
|
::kill (this->_guarded_child_pid, sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
int App::subscribeToSignal (int sig, bool accept)
|
|
||||||
|
App::SignalState App::getSignalSubscription (int sig) const
|
||||||
{
|
{
|
||||||
QSE_ASSERT (sig >= 0 && sig < QSE_NSIGS);
|
QSE_ASSERT (sig >= 0 && sig < QSE_NSIGS);
|
||||||
_SigLink::State reqstate = accept? _SigLink::ACCEPTED: _SigLink::IGNORED;
|
return this->_sig[sig]._state;
|
||||||
ScopedMutexLocker sml(g_app_mutex);
|
|
||||||
return this->subscribe_to_signal_no_mutex(sig, reqstate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int App::subscribeToAllSignals (bool accept)
|
int App::setSignalSubscription (int sig, SignalState ss)
|
||||||
{
|
{
|
||||||
_SigLink::State reqstate = accept? _SigLink::ACCEPTED: _SigLink::IGNORED;
|
QSE_ASSERT (sig >= 0 && sig < QSE_NSIGS);
|
||||||
_SigLink::State _old_state[QSE_NSIGS];
|
|
||||||
ScopedMutexLocker sml(g_app_mutex);
|
|
||||||
for (int i = 0; i < QSE_NSIGS; i++)
|
|
||||||
{
|
|
||||||
_old_state[i] = this->_sig[i]._state;
|
|
||||||
if (this->subscribe_to_signal_no_mutex(i, reqstate) <= -1)
|
|
||||||
{
|
|
||||||
// roll back on a best-efforts basis.
|
|
||||||
while (i > 0)
|
|
||||||
{
|
|
||||||
--i;
|
|
||||||
switch (_old_state[i])
|
|
||||||
{
|
|
||||||
case _SigLink::UNHANDLED:
|
|
||||||
this->unsubscribe_from_signal_no_mutex (i);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _SigLink::ACCEPTED:
|
sigset_t sigset;
|
||||||
case _SigLink::IGNORED:
|
::sigemptyset (&sigset);
|
||||||
this->subscribe_to_signal_no_mutex (i, _old_state[i]);
|
::sigaddset (&sigset, sig);
|
||||||
break;
|
::sigprocmask (SIG_BLOCK, &sigset, QSE_NULL);
|
||||||
}
|
|
||||||
}
|
int n;
|
||||||
return -1;
|
{
|
||||||
}
|
ScopedMutexLocker sml(g_app_mutex);
|
||||||
|
n = this->set_signal_subscription_no_mutex(sig, ss);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
::sigprocmask (SIG_UNBLOCK, &sigset, QSE_NULL);
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::unsubscribeFromSignal (int sig)
|
int App::set_signal_subscription_no_mutex (int sig, SignalState reqstate)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (sig >= 0 && sig < QSE_NSIGS);
|
|
||||||
ScopedMutexLocker sml(g_app_mutex);
|
|
||||||
this->unsubscribe_from_signal_no_mutex (sig);
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::unsubscribeFromAllSignals ()
|
|
||||||
{
|
|
||||||
ScopedMutexLocker sml(g_app_mutex);
|
|
||||||
this->unsubscribe_from_all_signals_no_mutex ();
|
|
||||||
}
|
|
||||||
|
|
||||||
int App::subscribe_to_signal_no_mutex (int sig, _SigLink::State reqstate)
|
|
||||||
{
|
|
||||||
if (sig == SIGKILL || sig == SIGSTOP) return 0;
|
|
||||||
|
|
||||||
_SigLink& sl = this->_sig[sig];
|
_SigLink& sl = this->_sig[sig];
|
||||||
if (QSE_LIKELY(sl._state == _SigLink::UNHANDLED))
|
if (QSE_UNLIKELY(sl._state == reqstate)) return 0; // no change
|
||||||
|
|
||||||
|
if (reqstate == SIGNAL_UNHANDLED)
|
||||||
{
|
{
|
||||||
|
// accepted/ignored -> unhandled
|
||||||
|
QSE_ASSERT (g_app_sig[sig] != QSE_NULL);
|
||||||
|
|
||||||
|
if (g_app_sig[sig] == this)
|
||||||
|
{
|
||||||
|
QSE_ASSERT (sl._prev == QSE_NULL);
|
||||||
|
if (!sl._next)
|
||||||
|
{
|
||||||
|
if (App::unset_signal_handler_no_mutex (sig) <= -1) return -1;
|
||||||
|
}
|
||||||
|
g_app_sig[sig] = sl._next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sl._next) sl._next->_sig[sig]._prev = sl._prev;
|
||||||
|
if (sl._prev) sl._prev->_sig[sig]._next = sl._next;
|
||||||
|
sl._prev = QSE_NULL;
|
||||||
|
sl._next = QSE_NULL;
|
||||||
|
sl._state = reqstate;
|
||||||
|
}
|
||||||
|
else if (QSE_LIKELY(sl._state == SIGNAL_UNHANDLED))
|
||||||
|
{
|
||||||
|
// unhandled -> accepted/ignored
|
||||||
QSE_ASSERT (sl._prev == QSE_NULL && sl._next == QSE_NULL);
|
QSE_ASSERT (sl._prev == QSE_NULL && sl._next == QSE_NULL);
|
||||||
|
|
||||||
App* xapp = g_app_sig[sig];
|
App* xapp = g_app_sig[sig];
|
||||||
App* xapp_xprev = QSE_NULL;
|
App* xapp_xprev = QSE_NULL;
|
||||||
|
|
||||||
g_app_sig[sig] = this;
|
g_app_sig[sig] = this;
|
||||||
sl._state = _SigLink::ACCEPTED;
|
sl._state = SIGNAL_ACCEPTED;
|
||||||
sl._next = xapp;
|
sl._next = xapp;
|
||||||
if (xapp)
|
if (xapp)
|
||||||
{
|
{
|
||||||
@ -379,10 +378,58 @@ int App::subscribe_to_signal_no_mutex (int sig, _SigLink::State reqstate)
|
|||||||
// roll back
|
// roll back
|
||||||
g_app_sig[sig] = xapp;
|
g_app_sig[sig] = xapp;
|
||||||
if (xapp) xapp->_sig[sig]._prev = xapp_xprev;
|
if (xapp) xapp->_sig[sig]._prev = xapp_xprev;
|
||||||
sl._state = _SigLink::UNHANDLED;
|
sl._state = SIGNAL_UNHANDLED;
|
||||||
|
sl._next = QSE_NULL;
|
||||||
|
QSE_ASSERT (sl._prev == QSE_NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QSE_ASSERT (sl._prev == QSE_NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// accpeted/ignored -> ignored/accepted
|
||||||
|
QSE_ASSERT (g_app_sig[sig] != QSE_NULL);
|
||||||
|
sl._state = reqstate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reqstate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int App::subscribe_to_signal_no_mutex (int sig, SignalState reqstate)
|
||||||
|
{
|
||||||
|
return this->set_signal_subscription_no_mutex (sig, reqstate);
|
||||||
|
#if 0
|
||||||
|
_SigLink& sl = this->_sig[sig];
|
||||||
|
if (QSE_LIKELY(sl._state == SIGNAL_UNHANDLED))
|
||||||
|
{
|
||||||
|
QSE_ASSERT (sl._prev == QSE_NULL && sl._next == QSE_NULL);
|
||||||
|
|
||||||
|
App* xapp = g_app_sig[sig];
|
||||||
|
App* xapp_xprev = QSE_NULL;
|
||||||
|
|
||||||
|
g_app_sig[sig] = this;
|
||||||
|
sl._state = SIGNAL_ACCEPTED;
|
||||||
|
sl._next = xapp;
|
||||||
|
if (xapp)
|
||||||
|
{
|
||||||
|
xapp_xprev = xapp->_sig[sig]._prev;
|
||||||
|
xapp->_sig[sig]._prev = this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no application is set to accept this signal.
|
||||||
|
// this is the first time to
|
||||||
|
if (App::set_signal_handler_no_mutex(sig, App::handle_signal) <= -1)
|
||||||
|
{
|
||||||
|
// roll back
|
||||||
|
g_app_sig[sig] = xapp;
|
||||||
|
if (xapp) xapp->_sig[sig]._prev = xapp_xprev;
|
||||||
|
sl._state = SIGNAL_UNHANDLED;
|
||||||
sl._next = QSE_NULL;
|
sl._next = QSE_NULL;
|
||||||
QSE_ASSERT (sl._prev == QSE_NULL);
|
QSE_ASSERT (sl._prev == QSE_NULL);
|
||||||
if (errno == EINVAL) return 0; /// dirty hack???
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,14 +444,15 @@ if (errno == EINVAL) return 0; /// dirty hack???
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::unsubscribe_from_signal_no_mutex (int sig)
|
void App::unsubscribe_from_signal_no_mutex (int sig)
|
||||||
{
|
{
|
||||||
if (sig == SIGKILL || sig == SIGSTOP) return;
|
this->set_signal_subscription_no_mutex (sig, SIGNAL_UNHANDLED);
|
||||||
|
#if 0
|
||||||
_SigLink& sl = this->_sig[sig];
|
_SigLink& sl = this->_sig[sig];
|
||||||
if (QSE_UNLIKELY(sl._state == _SigLink::UNHANDLED))
|
if (QSE_UNLIKELY(sl._state == SIGNAL_UNHANDLED))
|
||||||
{
|
{
|
||||||
QSE_ASSERT (g_app_sig[sig] != this);
|
QSE_ASSERT (g_app_sig[sig] != this);
|
||||||
QSE_ASSERT (sl._prev == QSE_NULL && sl._next == QSE_NULL);
|
QSE_ASSERT (sl._prev == QSE_NULL && sl._next == QSE_NULL);
|
||||||
@ -425,8 +473,9 @@ void App::unsubscribe_from_signal_no_mutex (int sig)
|
|||||||
if (sl._prev) sl._prev->_sig[sig]._next = sl._next;
|
if (sl._prev) sl._prev->_sig[sig]._next = sl._next;
|
||||||
sl._prev = QSE_NULL;
|
sl._prev = QSE_NULL;
|
||||||
sl._next = QSE_NULL;
|
sl._next = QSE_NULL;
|
||||||
sl._state = _SigLink::UNHANDLED;
|
sl._state = SIGNAL_UNHANDLED;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::unsubscribe_from_all_signals_no_mutex()
|
void App::unsubscribe_from_all_signals_no_mutex()
|
||||||
@ -437,16 +486,24 @@ void App::unsubscribe_from_all_signals_no_mutex()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int App::guardProcess (const qse_mchar_t* proc_name, const Sigset& signals)
|
int App::guardProcess (const qse_mchar_t* proc_name, const SignalSet& signals)
|
||||||
{
|
{
|
||||||
|
SignalState old_ss[QSE_NSIGS];
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
pid_t pid = ::fork();
|
pid_t pid = ::fork();
|
||||||
if (pid == -1) return -1;
|
if (pid == -1) return -1;
|
||||||
if (pid == 0) break; // child
|
if (pid == 0) break; // child
|
||||||
|
|
||||||
//int _SigLink::State old_sig_states[QSE_NSIGS];
|
for (int i = 0; i < QSE_NSIGS; i++)
|
||||||
//this->subscribeToAllSignals(true);
|
{
|
||||||
|
if (signals.isSet(i))
|
||||||
|
{
|
||||||
|
old_ss[i] = this->getSignalSubscription(i);
|
||||||
|
this->setSignalSubscription (i, SIGNAL_ACCEPTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this->_guarded_child_pid = pid;
|
this->_guarded_child_pid = pid;
|
||||||
|
|
||||||
@ -462,8 +519,12 @@ int App::guardProcess (const qse_mchar_t* proc_name, const Sigset& signals)
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->_guarded_child_pid = -1;
|
this->_guarded_child_pid = -1;
|
||||||
// TODO: restore signal handlers to the previous states
|
for (int i = 0; i < QSE_NSIGS; i++)
|
||||||
|
{
|
||||||
|
if (signals.isSet(i)) this->setSignalSubscription (i, old_ss[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("child exited - exited %d exit status %d\n", WIFEXITED(status), WEXITSTATUS(status));
|
||||||
if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
|
if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -67,7 +67,7 @@ public:
|
|||||||
case SIGINT:
|
case SIGINT:
|
||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
case SIGHUP:
|
case SIGHUP:
|
||||||
qse_printf (QSE_T("requesting to stop server...app %p server %p\n"), this, &this->server);
|
qse_printf (QSE_T("requesting to stop server...app %p server %p - pid %d\n"), this, &this->server, (int)getpid());
|
||||||
this->server.stop();
|
this->server.stop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ public:
|
|||||||
|
|
||||||
int run ()
|
int run ()
|
||||||
{
|
{
|
||||||
QSE::App::Sigset signals;
|
QSE::App::SignalSet signals;
|
||||||
signals.set (SIGINT);
|
signals.set (SIGINT);
|
||||||
signals.set (SIGHUP);
|
signals.set (SIGHUP);
|
||||||
signals.set (SIGTERM);
|
signals.set (SIGTERM);
|
||||||
@ -99,24 +99,26 @@ static int test1()
|
|||||||
QSE::HeapMmgr heap_mmgr (QSE::Mmgr::getDFL(), 30000);
|
QSE::HeapMmgr heap_mmgr (QSE::Mmgr::getDFL(), 30000);
|
||||||
MyApp app (&heap_mmgr);
|
MyApp app (&heap_mmgr);
|
||||||
|
|
||||||
//MyApp app2 (&heap_mmgr);
|
MyApp app2 (&heap_mmgr);
|
||||||
//MyApp app3 (&heap_mmgr);
|
MyApp app3 (&heap_mmgr);
|
||||||
//MyApp app4 (&heap_mmgr);
|
MyApp app4 (&heap_mmgr);
|
||||||
|
|
||||||
app.subscribeToSignal (SIGINT, true);
|
app.subscribeToSignal (SIGINT, true);
|
||||||
app.subscribeToSignal (SIGTERM, true);
|
app.subscribeToSignal (SIGTERM, true);
|
||||||
|
|
||||||
//app4.subscribeToSignal (SIGINT, true);
|
app4.subscribeToSignal (SIGINT, true);
|
||||||
//app3.subscribeToSignal (SIGINT, true);
|
app3.subscribeToSignal (SIGINT, true);
|
||||||
//app2.subscribeToSignal (SIGINT, true);
|
app2.subscribeToSignal (SIGINT, true);
|
||||||
|
|
||||||
int n = app.run();
|
int n = app.run();
|
||||||
app.subscribeToSignal (SIGTERM, false);
|
app.subscribeToSignal (SIGTERM, false);
|
||||||
app.subscribeToSignal (SIGINT, false);
|
app.subscribeToSignal (SIGINT, false);
|
||||||
|
|
||||||
//app4.unsubscribeFromSignal (SIGINT);
|
app4.unsubscribeFromSignal (SIGINT);
|
||||||
//app3.unsubscribeFromSignal (SIGINT);
|
app3.unsubscribeFromSignal (SIGINT);
|
||||||
//app2.unsubscribeFromSignal (SIGINT);
|
app2.unsubscribeFromSignal (SIGINT);
|
||||||
|
qse_printf (QSE_T("END OF %d\n"), (int)getpid());
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +134,7 @@ int main ()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf (locale, ".%u", (unsigned int)codepage);
|
qse_mbsxfmt (locale, QSE_COUNTOF(locale), ".%u", (unsigned int)codepage);
|
||||||
setlocale (LC_ALL, locale);
|
setlocale (LC_ALL, locale);
|
||||||
/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/
|
/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/
|
||||||
}
|
}
|
||||||
@ -141,6 +143,7 @@ int main ()
|
|||||||
/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/
|
/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
qse_open_stdsios ();
|
qse_open_stdsios ();
|
||||||
test1();
|
test1();
|
||||||
qse_close_stdsios ();
|
qse_close_stdsios ();
|
||||||
|
Loading…
Reference in New Issue
Block a user