Linux: программно получить время выключения системы?

Я получаю время безотказной работы Linux из файла /proc/uptime. Откуда взять время последнего выключения машины. как прочитать его из файла wtmp в "c". Я не хочу анализировать вывод последней команды -x. я могу использовать sysctl?


person Ravi Bhushan    schedule 29.04.2016    source источник
comment
Какой дистрибутив и номер версии вы используете (Ubuntu 14.04, CentOS 7 и т. д.)? Различные системы инициализации могут записывать разную информацию в wtmp.   -  person Mark Plotnick    schedule 29.04.2016


Ответы (1)


В Linux доступ к этим данным осуществляется через вызовы API getutent. Вы можете использовать utmpname, чтобы установить имя файла, и использовать getutent, чтобы получить каждую запись в истории входа.

Подробную информацию о проверке API см. на http://linux.die.net/man/3/getutent

Формат файла описан на странице http://linux.die.net/man/5/utmp

РЕДАКТИРОВАТЬ

Чтобы узнать, как конкретно получить время выключения, проверьте ut_user из struct utmp, возвращаемых API, и сделайте что-нибудь, если это shutdown, например, переберите все записи в файле с помощью этого кода:

struct utmp *u = getutent();
if (strncmp(u>ut_user, "shutdown", 8) == 0) {
    // parse the shutdown time in u->ut_time
}

Следующий код успешно идентифицировал все записи завершения работы в моей системе:

#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <utmp.h>

int main(void)
{
    struct utmp *u;
    int ret;

    ret = utmpname("/var/log/wtmp");
    if (ret < 0) {
            perror("utmpname");
            return 1;
    }
    while (true) {
            u = getutent();
            if (!u) {
                    perror("getutent");
                    break;
            }
            if (strncmp(u->ut_user, "shutdown", 8) == 0) {
                    time_t t = u->ut_time;
                    struct tm *tm = localtime(&t);
                    char timestr[128];

                    strftime(timestr, sizeof timestr, "%a %b %d %T %Y", tm);
                    printf("%s: %s\n", u->ut_user, timestr);
            }
    }
    return 0;
}

Вывод в моей системе:

shutdown: Tue Mar 08 00:13:00 2016
shutdown: Sat Mar 12 08:45:57 2016
shutdown: Sat Mar 19 09:55:49 2016
shutdown: Wed Mar 23 16:24:39 2016
....
person fluter    schedule 29.04.2016
comment
это не обеспечивает время выключения. я могу получить BOOT_TIME, используя getutent API. - person Ravi Bhushan; 29.04.2016
comment
@RaviBhushan У него есть время выключения, см. Мой пост. - person fluter; 29.04.2016
comment
Если условие не удовлетворяет. я напечатал ut.ut_user перед условием if. нет отключения пользователя. я получаю перезагрузку пользователя, уровень запуска и обычного пользователя. - person Ravi Bhushan; 29.04.2016
comment
@RaviBhushan, может быть, опубликуете весь код? это работает для меня, см. мой код. - person fluter; 29.04.2016