<commit_before>/* ------------------------------------------------------------------------- *
 * Copyright (C) 2012 Jolla Ltd.
 * Contact: <NAME> <<EMAIL>>
 * License: LGPLv2
 * ------------------------------------------------------------------------- */

#include "libwakelock.h"

#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>

/** Whether to write debug logging to stderr
 *
 * If not enabled, no diagnostics of any kind gets written.
 */
#ifndef LWL_ENABLE_LOGGING
# define LWL_ENABLE_LOGGING 01
#endif

/** Prefix used for log messages
 */
#define LWL_LOG_PFIX "LWL: "

/** Logging functionality that can be configured out at compile time
 */
#if LWL_ENABLE_LOGGING
# define lwl_debugf(FMT, ARGS...) fprintf(stderr, LWL_LOG_PFIX FMT, ##ARGS)
#else
# define lwl_debugf(FMT, ARGS...) do { } while( 0 )
#endif

/** Paths to wakelock interfaces in sysfs
 */
static const char lwl_lock_path[]   = "/sys/power/wake_lock";
static const char lwl_unlock_path[] = "/sys/power/wake_unlock";

/** Helper for writing to sysfs files
 */
static void lwl_write_file(const char *path, const char *data)
{
	int file;

	lwl_debugf("%s << %s", path, data);

	if( (file = TEMP_FAILURE_RETRY(open(path, O_WRONLY))) == -1 ) {
		lwl_debugf("%s: open: %m\n", path);
	} else {
		int size = strlen(data);
		errno = 0;
		if( TEMP_FAILURE_RETRY(write(file, data, size)) != size ) {
			lwl_debugf("%s: write: %m\n", path);
		}
		TEMP_FAILURE_RETRY(close(file));
	}
}

/** Helper for checking if wakelock interface is supported
 */
static int lwl_enabled(void)
{
	static int checked = 0, enabled = 0;

	if( !checked ) {
		checked = 1, enabled = !access(lwl_lock_path, F_OK);
		lwl_debugf("%s\n", enabled ? "enabled" : "disabled");
	}

	return enabled;
}

/** Use sysfs interface to create and enable a wakelock.
 *
 * @param name The name of the wakelock to obtain
 * @param ns   Time in nanoseconds before the wakelock gets released
 *             automatically, or negative value for no timeout.
 */
void wakelock_lock(const char *name, long long ns)
{
	if( lwl_enabled() ) {
		char tmp[64];
		if( ns < 0 ) {
			snprintf(tmp, sizeof tmp, "%s\n", name);
		} else {
			snprintf(tmp, sizeof tmp, "%s %lld\n", name, ns);
		}
		lwl_write_file(lwl_lock_path, tmp);
	}
}

/** Use sysfs interface to disable a wakelock.
 *
 * @param name The name of the wakelock to release
 *
 * Note: This will not delete the wakelocks.
 */
void wakelock_unlock(const char *name)
{
	if( lwl_enabled() ) {
		char tmp[64];
		snprintf(tmp, sizeof tmp, "%s\n", name);
		lwl_write_file(lwl_unlock_path, tmp);
	}
}

static const char lwl_state_path[] = "/sys/power/state";

static int        lwl_shutting_down = 0;

/** Use sysfs interface to allow automatic entry to suspend
 *
 * After this call the device will enter suspend mode once all
 * the wakelocks have been released.
 *
 * Android kernels will enter early suspend (i.e. display is
 * turned off etc) even if there still are active wakelocks.
 */
void wakelock_allow_suspend(void)
{
	if( lwl_enabled() && !lwl_shutting_down ) {
		lwl_write_file(lwl_state_path, "mem\n");
	}
}

/** Use sysfs interface to block automatic entry to suspend
 *
 * The device will not enter suspend mode with or without<commit_msg>Taking wakelocks blocked on process exit path<commit_after>/* ------------------------------------------------------------------------- *
 * Copyright (C) 2012 Jolla Ltd.
 * Contact: <NAME> <<EMAIL>>
 * License: LGPLv2
 * ------------------------------------------------------------------------- */

#include "libwakelock.h"

#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>

/** Whether to write debug logging to stderr
 *
 * If not enabled, no diagnostics of any kind gets written.
 */
#ifndef LWL_ENABLE_LOGGING
# define LWL_ENABLE_LOGGING 01
#endif

/** Prefix used for log messages
 */
#define LWL_LOG_PFIX "LWL: "

/** Logging functionality that can be configured out at compile time
 */
#if LWL_ENABLE_LOGGING
# define lwl_debugf(FMT, ARGS...) fprintf(stderr, LWL_LOG_PFIX FMT, ##ARGS)
#else
# define lwl_debugf(FMT, ARGS...) do { } while( 0 )
#endif

/** Flag that gets set once the process is about to exit */
static int        lwl_shutting_down = 0;

/** Sysfs entry for acquiring wakelocks */
static const char lwl_lock_path[]   = "/sys/power/wake_lock";

/** Sysfs entry for releasing wakelocks */
static const char lwl_unlock_path[] = "/sys/power/wake_unlock";

/** Sysfs entry for allow/block suspend */
static const char lwl_state_path[] = "/sys/power/state";

/** Helper for writing to sysfs files
 */
static void lwl_write_file(const char *path, const char *data)
{
	int file;

	lwl_debugf("%s << %s", path, data);

	if( (file = TEMP_FAILURE_RETRY(open(path, O_WRONLY))) == -1 ) {
		lwl_debugf("%s: open: %m\n", path);
	} else {
		int size = strlen(data);
		errno = 0;
		if( TEMP_FAILURE_RETRY(write(file, data, size)) != size ) {
			lwl_debugf("%s: write: %m\n", path);
		}
		TEMP_FAILURE_RETRY(close(file));
	}
}

/** Helper for checking if wakelock interface is supported
 */
static int lwl_enabled(void)
{
	static int checked = 0, enabled = 0;

	if( !checked ) {
		checked = 1, enabled = !access(lwl_lock_path, F_OK);
		lwl_debugf("%s\n", enabled ? "enabled" : "disabled");
	}

	return enabled;
}

/** Use sysfs interface to create and enable a wakelock.
 *
 * @param name The name of the wakelock to obtain
 * @param ns   Time in nanoseconds before the wakelock gets released
 *             automatically, or negative value for no timeout.
 */
void wakelock_lock(const char *name, long long ns)
{
	if( lwl_enabled() && !lwl_shutting_down ) {
		char tmp[64];
		if( ns < 0 ) {
			snprintf(tmp, sizeof tmp, "%s\n", name);
		} else {
			snprintf(tmp, sizeof tmp, "%s %lld\n", name, ns);
		}
		lwl_write_file(lwl_lock_path, tmp);
	}
}

/** Use sysfs interface to disable a wakelock.
 *
 * @param name The name of the wakelock to release
 *
 * Note: This will not delete the wakelocks.
 */
void wakelock_unlock(const char *name)
{
	if( lwl_enabled() ) {
		char tmp[64];
		snprintf(tmp, sizeof tmp, "%s\n", name);
		lwl_write_file(lwl_unlock_path, tmp);
	}
}

/** Use sysfs interface to allow automatic entry to suspend
 *
 * After this call the device will enter suspend mode once all
 * the wakelocks have been released.
 *
 * Android kernels will enter early suspend (i.e. display is
 * turned off etc) even if there still are active wakelocks.
 */
void wakelock_allow_suspend(void)
{
	if( lwl_enabled() && !lwl_shutting_down ) {
		lwl_write_file(lwl_state_path, "mem\n");
	}
}

/** Use sysfs interface to block automatic entry to suspend
 *
 * The device will not enter suspend mode with or without
{'fraction_non_alphanumeric': 0.166815210932858, 'fraction_numerical': 0.00564468211527035, 'mean_word_length': 3.135749385749386, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2677637', 'n_tokens_mistral': 2411, 'n_tokens_neox': 2323, 'n_words': 732}