diff --git a/configure.ac b/configure.ac
index 9111d06..7bab961 100644
--- a/configure.ac
+++ b/configure.ac
@@ -39,17 +39,6 @@ AS_IF([test "x$enable_runlevel" != xno],
[AC_DEFINE([DSME_WANT_LIBRUNLEVEL], [1], [Enable runlevel plugin])])
AM_CONDITIONAL([WANT_RUNLEVEL], [test x$enable_runlevel != xno])
-#
-# upstart
-#
-AC_ARG_ENABLE([upstart],
- [AS_HELP_STRING([--disable-upstart],
- [disable upstart plugin (libupstart)])])
-
-AS_IF([test "x$enable_upstart" != xno],
- [AC_DEFINE([DSME_WANT_LIBUPSTART], [1])])
-AM_CONDITIONAL([WANT_UPSTART], [test x$enable_upstart != xno])
-
#
# systemd
#
diff --git a/dsme/dsme-server.c b/dsme/dsme-server.c
index d26f54d..8ef3b02 100644
--- a/dsme/dsme-server.c
+++ b/dsme/dsme-server.c
@@ -78,7 +78,7 @@ static void usage(const char * progname)
fprintf(stderr, "Valid options:\n");
#ifdef DSME_LOG_ENABLE
fprintf(stderr, " -l --logging "
- "Logging type (syslog, sti, stderr, stdout, none)\n");
+ "Logging type (syslog, stderr, stdout, none)\n");
fprintf(stderr, " -v --verbosity Log verbosity (3..7)\n");
#endif
#ifdef DSME_SYSTEMD_ENABLE
@@ -149,7 +149,6 @@ static void parse_options(int argc, /* in */
{
const char *log_method_name[] = {
"none", /* LOG_METHOD_NONE */
- "sti", /* LOG_METHOD_STI */
"stdout", /* LOG_METHOD_STDOUT */
"stderr", /* LOG_METHOD_STDERR */
"syslog", /* LOG_METHOD_SYSLOG */
diff --git a/dsme/dsme-wdd.c b/dsme/dsme-wdd.c
index 8693282..dc1d466 100644
--- a/dsme/dsme-wdd.c
+++ b/dsme/dsme-wdd.c
@@ -130,8 +130,9 @@ static int daemonize(void)
i = open("/dev/null", O_RDWR);
i = open("/dev/console", O_RDWR);
- if (dup(i) == -1) {
+ if (i > 0 && dup(i) == -1) {
fprintf(stderr, ME "daemonize: dup failed: %s\n", strerror(errno));
+ close(i);
return -1;
}
diff --git a/dsme/dsmesock.c b/dsme/dsmesock.c
index 3b802c4..5caa18d 100644
--- a/dsme/dsmesock.c
+++ b/dsme/dsmesock.c
@@ -119,7 +119,6 @@ int dsmesock_listen(dsmesock_callback* read_and_queue)
g_io_channel_shutdown(as_chan, FALSE, 0);
g_io_channel_unref(as_chan);
as_chan = 0;
- goto fail;
close_and_fail:
close(fd);
diff --git a/dsme/logging.c b/dsme/logging.c
index 6d3dd47..785c23f 100644
--- a/dsme/logging.c
+++ b/dsme/logging.c
@@ -145,59 +145,6 @@ static void log_to_null(int prio, const char* message)
{
}
-
-/*
- * This routine is used when STI logging method is set
- */
-static void log_to_sti(int prio, const char* message)
-{
- if (logopt.sock != -1) {
- if (logopt.verbosity >= prio) {
- char buf[256];
- int len;
- struct nlmsghdr nlh;
- struct sockaddr_nl snl;
-
- if (prio >= 0) {
- snprintf(buf,
- sizeof(buf),
- "%s %s: ",
- logopt.prefix,
- log_prio_str(prio));
- }
- len = strlen(buf);
- snprintf(buf+len, sizeof(buf)-len, "%s", message);
- len = strlen(buf);
-
- struct iovec iov[2];
- iov[0].iov_base = &nlh;
- iov[0].iov_len = sizeof(struct nlmsghdr);
- iov[1].iov_base = buf;
- iov[1].iov_len = len;
-
- struct msghdr msg;
- msg.msg_name = (void *)&snl;
- msg.msg_namelen = sizeof(struct sockaddr_nl);
- msg.msg_iov = iov;
- msg.msg_iovlen = sizeof(iov)/sizeof(*iov);
- msg.msg_flags = 0;
-
- memset(&snl, 0, sizeof(struct sockaddr_nl));
-
- snl.nl_family = AF_NETLINK;
- nlh.nlmsg_len = NLMSG_LENGTH(len);
- nlh.nlmsg_type = (0xC0 << 8) | (1 << 0); /* STI Write */
- nlh.nlmsg_flags = (logopt.channel << 8);
-
- sendmsg(logopt.sock, &msg, 0);
- }
- } else {
- fprintf(stderr, "dsme trace: ");
- fprintf(stderr, "%s", message);
- }
-}
-
-
/*
* This routine is used when stdout logging method is set
*/
@@ -377,34 +324,6 @@ bool dsme_log_open(log_method method,
dsme_log_routine = log_to_null;
break;
- case LOG_METHOD_STI:
- {
- struct sockaddr_nl snl;
- int ret;
-
- memset(&snl, 0, sizeof(struct sockaddr_nl));
- snl.nl_family = AF_NETLINK;
- snl.nl_pid = getpid();
-
- logopt.sock = ret = socket(PF_NETLINK,
- SOCK_RAW,
- NETLINK_USERSOCK);
- if (ret < 0)
- goto out;
-
- ret = bind(logopt.sock, (struct sockaddr *)&snl,
- sizeof(struct sockaddr_nl));
- if (ret < 0)
- goto out;
-
- logopt.channel = DSME_STI_CHANNEL;
- dsme_log_routine = log_to_sti;
- break;
-out:
- fprintf(stderr,
- "STI init failed, will fall back to stderr method\n");
- dsme_log_routine = log_to_stderr;
- }
case LOG_METHOD_STDOUT:
dsme_log_routine = log_to_stdout;
break;
@@ -498,9 +417,6 @@ void dsme_log_close(void)
case LOG_METHOD_FILE:
fclose(logopt.filep);
break;
- case LOG_METHOD_STI:
- close(logopt.sock);
- break;
default:
return;
}
diff --git a/include/dsme/logging.h b/include/dsme/logging.h
index be31594..eda03f4 100644
--- a/include/dsme/logging.h
+++ b/include/dsme/logging.h
@@ -38,7 +38,6 @@ extern "C" {
/* Logging methods */
typedef enum {
LOG_METHOD_NONE, /* Suppress all the messages */
- LOG_METHOD_STI, /* Serial trace interface */
LOG_METHOD_STDOUT, /* Print messages to stdout */
LOG_METHOD_STDERR, /* Print messages to stderr */
LOG_METHOD_SYSLOG, /* Use syslog(3) */
diff --git a/modules/Makefile.am b/modules/Makefile.am
index 04864f8..d0489db 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -46,10 +46,6 @@ if WANT_RUNLEVEL
pkglib_LTLIBRARIES += runlevel.la
endif
-if WANT_UPSTART
-pkglib_LTLIBRARIES += upstart.la
-endif
-
if WANT_VALIDATOR_LISTENER
pkglib_LTLIBRARIES += validatorlistener.la
endif
@@ -99,12 +95,6 @@ if WANT_RUNLEVEL
runlevel_la_SOURCES = runlevel.c
endif
-if WANT_UPSTART
-upstart_la_SOURCES = upstart.c
-upstart_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
-upstart_la_LIBADD = $(DBUS_LIBS)
-endif
-
if WANT_VALIDATOR_LISTENER
runlevel_la_SOURCES = validatorlistener.c
validatorlistener_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS)
diff --git a/modules/state.c b/modules/state.c
index eab9b9c..1358f69 100644
--- a/modules/state.c
+++ b/modules/state.c
@@ -214,7 +214,7 @@ static dsme_runlevel_t state2runlevel(dsme_state_t state)
case DSME_STATE_SHUTDOWN: runlevel = DSME_RUNLEVEL_SHUTDOWN; break;
case DSME_STATE_TEST: runlevel = DSME_RUNLEVEL_TEST; break;
case DSME_STATE_USER: runlevel = DSME_RUNLEVEL_USER; break;
- case DSME_STATE_LOCAL: runlevel = DSME_RUNLEVEL_LOCAL;
+ case DSME_STATE_LOCAL: runlevel = DSME_RUNLEVEL_LOCAL; break;
case DSME_STATE_ACTDEAD: runlevel = DSME_RUNLEVEL_ACTDEAD; break;
case DSME_STATE_REBOOT: runlevel = DSME_RUNLEVEL_REBOOT; break;
diff --git a/modules/upstart.c b/modules/upstart.c
deleted file mode 100644
index 5a39b96..0000000
--- a/modules/upstart.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/**
- @file upstart.c
-
- DSME internal runlevel control using upstart D-Bus i/f
-
- Copyright (C) 2010 Nokia Corporation.
-
- @author Semi Malinen
-
- This file is part of Dsme.
-
- Dsme is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License
- version 2.1 as published by the Free Software Foundation.
-
- Dsme 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with Dsme. If not, see .
-*/
-
-#ifndef __cplusplus
-#define _GNU_SOURCE
-#endif
-
-#include "runlevel.h"
-#include "../include/dsme/modules.h"
-#include "../include/dsme/logging.h"
-#include "../include/dsme/modulebase.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-
-static bool save_state_for_getbootstate(dsme_runlevel_t runlevel);
-static bool telinit_internal(dsme_runlevel_t runlevel);
-static void shutdown_internal(dsme_runlevel_t runlevel);
-static bool remount_mmc_readonly(void);
-
-
-static int current_runlevel_in_utmp()
-{
- int runlevel = 0;
- struct utmpx utmp;
- struct utmpx* utmp_runlevel;
-
- memset(&utmp, 0, sizeof utmp);
- utmp.ut_type = RUN_LVL;
-
- utmpxname(_PATH_UTMPX);
- setutxent();
- utmp_runlevel = getutxid(&utmp);
- if (utmp_runlevel) {
- runlevel = utmp_runlevel->ut_pid % 256;
- int prevlevel = utmp_runlevel->ut_pid / 256;
- dsme_log(LOG_DEBUG,
- "read from utmp: %c (%d), %c (%d)",
- prevlevel, prevlevel, runlevel, runlevel);
- } else {
- dsme_log(LOG_DEBUG, "could not read from utmp");
- }
- endutxent();
-
- return runlevel > 0 ? runlevel : 'N';
-}
-
-/*
- * since we are bypassing upstart's telinit,
- * we have to update utmp & wtmp by hand.
- * Notice that this is much simplified from
- * how upstart does it -- perhaps too much?
- */
-static bool save_state_in_utmp_and_wtmp(dsme_runlevel_t runlevel)
-{
- bool saved = false;
- struct utmpx utmp;
- int prevlevel = current_runlevel_in_utmp();
-
- runlevel += '0';
-
- // first populate the utmpx struct
- memset(&utmp, 0, sizeof utmp);
- utmp.ut_type = RUN_LVL;
- utmp.ut_pid = runlevel + prevlevel * 256;
- strncpy(utmp.ut_line, "~", sizeof utmp.ut_line);
- strncpy(utmp.ut_id, "~~", sizeof utmp.ut_id);
- strncpy(utmp.ut_user, "runlevel", sizeof utmp.ut_user);
-
- struct utsname uts;
- if (uname(&uts) == 0) {
- strncpy(utmp.ut_host, uts.release, sizeof utmp.ut_host);
- }
-
- struct timeval tv;
- gettimeofday(&tv, 0);
- utmp.ut_tv.tv_sec = tv.tv_sec;
- utmp.ut_tv.tv_usec = tv.tv_usec;
-
- // then write the utmpx struct to both utmp & wtmp
- utmpxname(_PATH_UTMPX);
- setutxent();
- if (pututxline(&utmp)) {
- saved = true;
- dsme_log(LOG_DEBUG,
- "saved to utmp: %c (%d), %c (%d)",
- prevlevel, prevlevel, runlevel, runlevel);
- }
- endutxent();
-
- updwtmpx(_PATH_WTMPX, &utmp);
-
- return saved;
-}
-
-
-static bool save_state_for_getbootstate(dsme_runlevel_t runlevel)
-{
- const char* state;
- int fd;
-
- /* Write out saved state for getbootstate.
- * Prefer USER over ACT_DEAD over others. The order matters in case many
- * DSME states are mapped to the same runlevel. This really shouldn't be
- * the case when upstart is used, but still, be prepared for it.
- */
- if (runlevel == DSME_RUNLEVEL_USER) {
- state = "USER";
- }
- else if (runlevel == DSME_RUNLEVEL_ACTDEAD) {
- state = "ACT_DEAD";
- }
- else if (runlevel == DSME_RUNLEVEL_TEST) {
- state = "TEST";
- }
- else if (runlevel == DSME_RUNLEVEL_LOCAL) {
- state = "LOCAL";
- }
- else {
- state = 0;
- }
-
- if (state) {
-#define SAVED_STATE_FILE "/var/lib/dsme/saved_state"
- (void)unlink (SAVED_STATE_FILE);
-
- while ((fd = open (SAVED_STATE_FILE, O_CREAT|O_WRONLY|O_SYNC, 00600))
- == -1 && errno == EINTR)
- {
- /* EMPTY LOOP */
- }
- if (fd < 0) {
- return false;
- }
-
- int res;
- while (*state) {
- while ((res = write (fd, state, strlen(state)))
- == -1 && errno == EINTR)
- {
- /* EMPTY LOOP */
- }
- if (res == -1) {
- /* don't leave partial state files behind */
- (void)unlink (SAVED_STATE_FILE);
- return false;
- } else {
- state += res;
- }
- }
-
- while ((res = close (fd)) == -1 && errno == EINTR) {
- /* EMPTY LOOP */
- }
- if (res == -1) {
- /* don't leave partial state files behind */
- (void)unlink (SAVED_STATE_FILE);
- return false;
- }
- }
-
- return true;
-}
-
-/**
- This function is used to tell init to change to new runlevel.
- @param new_state State corresponding to the new runlevel
- @return true on success, false on failure
- @todo Make sure that the runlevel change takes place
-*/
-// TODO: D-Bus marshalling is way ugly; needs to be abstracted
-static bool telinit_internal(dsme_runlevel_t runlevel)
-{
- bool runlevel_changed = false;
- DBusError error;
- DBusConnection* conn = 0;
- DBusMessage* call = 0;
- DBusMessageIter iter;
- DBusMessageIter env_iter;
-
- dbus_error_init(&error);
-
- conn = dbus_connection_open_private("unix:abstract=/com/ubuntu/upstart", &error);
- if (!conn) {
- dsme_log(LOG_CRIT, "Cannot connect to upstart");
- goto done;
- }
- call = dbus_message_new_method_call(0,
- "/com/ubuntu/Upstart",
- "com.ubuntu.Upstart0_6",
- "EmitEvent");
- dbus_message_set_auto_start(call, false); // TODO: needed?
-
- dbus_message_iter_init_append(call, &iter);
-
- // marshal message name
- const char* name = "runlevel";
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name)) {
- dsme_log(LOG_CRIT, "Cannot append to message");
- goto done;
- }
-
- // marshal environment, which includes the target runlevel
- if (!dbus_message_iter_open_container(&iter,
- DBUS_TYPE_ARRAY,
- "s",
- &env_iter))
- {
- dsme_log(LOG_CRIT, "Cannot append to message");
- goto done;
- } else {
- char* s = 0;
- if (asprintf(&s, "RUNLEVEL=%c", '0'+runlevel) == -1) {
- dsme_log(LOG_CRIT, "asprintf failed");
- dbus_message_iter_abandon_container(&iter, &env_iter);
- goto done;
- }
- if (!dbus_message_iter_append_basic(&env_iter, DBUS_TYPE_STRING, &s)) {
- dsme_log(LOG_CRIT, "Cannot append to message");
- dbus_message_iter_abandon_container(&iter, &env_iter);
- goto done;
- }
- free(s); // TODO: needed?
- s = 0; // TODO: needed?
- if (asprintf(&s, "HABA=tsuh") == -1) {
- dsme_log(LOG_CRIT, "asprintf failed");
- dbus_message_iter_abandon_container(&iter, &env_iter);
- goto done;
- }
- if (!dbus_message_iter_append_basic(&env_iter, DBUS_TYPE_STRING, &s)) {
- dsme_log(LOG_CRIT, "Cannot append to message");
- dbus_message_iter_abandon_container(&iter, &env_iter);
- goto done;
- }
- free(s); // TODO: needed?
- s = 0; // TODO: needed?
- }
- if (!dbus_message_iter_close_container(&iter, &env_iter)) {
- dsme_log(LOG_CRIT, "Cannot close container");
- goto done;
- }
-
- // marshal 'wait'
- int wait = false;
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &wait)) {
- dsme_log(LOG_CRIT, "Cannot append to message");
- goto done;
- }
-
- if (!save_state_in_utmp_and_wtmp(runlevel))
- {
- dsme_log(LOG_CRIT, "Error saving state in utmp");
- goto done;
- }
-
- if (!save_state_for_getbootstate(runlevel)) {
- dsme_log(LOG_CRIT, "Error saving state for getbootstate");
- goto done;
- }
-
-
- // make the call
- // TODO: do not block!
- DBusMessage* reply;
- reply = dbus_connection_send_with_reply_and_block(conn, call, -1, &error);
- if (dbus_error_is_set(&error)) {
- dsme_log(LOG_CRIT, "D-Bus sending failed: %s", error.message);
- goto done;
- }
-
- // inspect the response
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
- dsme_log(LOG_CRIT, "Got an error reply");
- dbus_message_unref(reply);
- goto done;
- }
- if (dbus_message_get_type(reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN) {
- dsme_log(LOG_CRIT, "Got an unknown reply type");
- dbus_message_unref(reply);
- goto done;
- }
-
- // TODO: huh? should we check the reply?
- runlevel_changed = true;
-
- if (reply) dbus_message_unref(reply);
-
-
-done:
- if (call) dbus_message_unref(call);
- if (conn) {
- dbus_connection_close(conn);
- dbus_connection_unref(conn);
- }
- dbus_error_free(&error);
-
- return runlevel_changed;
-}
-
-
-/*
- * This function will do the shutdown or reboot (based on desired runlevel).
- * In case of failure, function will shutdown/reboot by itself.
- */
-static void shutdown_internal(dsme_runlevel_t runlevel)
-{
- if ((runlevel != DSME_RUNLEVEL_REBOOT) &&
- (runlevel != DSME_RUNLEVEL_SHUTDOWN) &&
- (runlevel != DSME_RUNLEVEL_MALF))
- {
- dsme_log(LOG_DEBUG, "Shutdown request to bad runlevel (%d)", runlevel);
- return;
- }
- dsme_log(LOG_CRIT,
- runlevel == DSME_RUNLEVEL_SHUTDOWN ? "Shutdown" :
- runlevel == DSME_RUNLEVEL_REBOOT ? "Reboot" :
- "Malf");
-
- /* If runlevel change fails, handle the shutdown/reboot by DSME */
- if (!telinit_internal(runlevel))
- {
- dsme_log(LOG_CRIT, "Doing forced shutdown/reboot");
- sync();
-
- (void)remount_mmc_readonly();
-
- if (runlevel == DSME_RUNLEVEL_SHUTDOWN ||
- runlevel == DSME_RUNLEVEL_MALF)
- {
- dsme_log(LOG_CRIT, "Issuing poweroff");
- if (system("/sbin/poweroff") != 0) {
- dsme_log(LOG_ERR, "/sbin/poweroff failed, trying again in 3s");
- sleep(3);
- if (system("/sbin/poweroff") != 0) {
- dsme_log(LOG_ERR, "/sbin/poweroff failed again");
- goto fail_and_exit;
- }
- }
- } else {
- dsme_log(LOG_CRIT, "Issuing reboot");
- if (system("/sbin/reboot") != 0) {
- dsme_log(LOG_ERR, "/sbin/reboot failed, trying again in 3s");
- sleep(3);
- if (system("/sbin/reboot") != 0) {
- dsme_log(LOG_ERR, "/sbin/reboot failed again");
- goto fail_and_exit;
- }
- }
- }
-
- }
-
- return;
-
-fail_and_exit:
- dsme_log(LOG_CRIT, "Closing to clean-up!");
- dsme_exit(EXIT_FAILURE);
-}
-
-
-/*
- * This function tries to find mounted MMC (mmcblk) and remount it
- * read-only if mounted.
- * @return true on success, false on failure
- */
-static bool remount_mmc_readonly(void)
-{
- bool mounted = false;
- char* args[] = { (char*)"mount", NULL, NULL, (char*)"-o", (char*)"remount,ro", 0 };
- char device[256];
- char mntpoint[256];
- char* line = NULL;
- size_t len = 0;
- FILE* mounts_file = NULL;
-
- /* Let's try to find the MMC in /proc/mounts */
- mounts_file = fopen("/proc/mounts", "r");
- if (!mounts_file) {
- dsme_log(LOG_WARNING, "Can't open /proc/mounts. Leaving MMC as is");
- return false;
- }
-
- while (getline(&line, &len, mounts_file) != -1) {
- if (strstr(line, "mmcblk")) {
- sscanf(line, "%s %s", device, mntpoint);
- mounted = true;
- }
- }
-
- if (line) {
- free(line);
- line = NULL;
- }
- fclose(mounts_file);
-
- /* If mmc was found, try to umount it */
- if (mounted) {
- int status = -1;
- pid_t pid;
- pid_t rc;
-
- dsme_log(LOG_WARNING, "MMC seems to be mounted, trying to mount read-only (%s %s).", device, mntpoint);
-
- args[1] = (char*)&device;
- args[2] = (char*)&mntpoint;
- /* try to remount read-only */
- if ((pid = fork()) < 0) {
- dsme_log(LOG_CRIT, "fork failed, no way to remount");
- return false;
- } else if (pid == 0) {
- execv("/bin/mount", args);
- execv("/sbin/mount", args);
-
- dsme_log(LOG_ERR, "remount failed, no mount cmd found");
- return false;
- }
- while ((rc = wait(&status)) != pid)
- if (rc < 0 && errno == ECHILD)
- break;
- if (rc != pid || WEXITSTATUS(status) != 0) {
- dsme_log(LOG_ERR, "mount return value != 0, no can do.");
- return false;
- }
-
- dsme_log(LOG_NOTICE, "MMC remounted read-only");
- return true;
-
- } else {
- dsme_log(LOG_NOTICE, "MMC not mounted");
- return true;
- }
-}
-
-
-DSME_HANDLER(DSM_MSGTYPE_CHANGE_RUNLEVEL, conn, msg)
-{
- (void)telinit_internal(msg->runlevel);
-}
-
-DSME_HANDLER(DSM_MSGTYPE_SHUTDOWN, conn, msg)
-{
- shutdown_internal(msg->runlevel);
-}
-
-
-module_fn_info_t message_handlers[] = {
- DSME_HANDLER_BINDING(DSM_MSGTYPE_CHANGE_RUNLEVEL),
- DSME_HANDLER_BINDING(DSM_MSGTYPE_SHUTDOWN),
- { 0 }
-};
-
-
-void module_init(module_t* module)
-{
- dsme_log(LOG_DEBUG, "upstart.so loaded");
-}
-
-void module_fini(void)
-{
- dsme_log(LOG_DEBUG, "upstart.so unloaded");
-}
diff --git a/test/testmod_alarmtracker.c b/test/testmod_alarmtracker.c
index 90f5dbc..764ade6 100644
--- a/test/testmod_alarmtracker.c
+++ b/test/testmod_alarmtracker.c
@@ -78,6 +78,7 @@ time_t time(time_t *tloc)
time_t (*realtime)(time_t *tloc) = dlsym(RTLD_NEXT, "time");
if (dlerror()) {
rval = (time_t)-1;
+ goto out;
}
rval = realtime(tloc);
} else {
@@ -86,7 +87,7 @@ time_t time(time_t *tloc)
}
rval = faketime;
}
-
+out:
return rval;
}