Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
Something went wrong. Try again.
C
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166// SPDX-License-Identifier: GPL-2.0-only/* * 32bit compatibility wrappers for the input subsystem. * * Very heavily based on evdev.c - Copyright (c) 1999-2002 Vojtech Pavlik */
#include <linux/export.h>#include <linux/sprintf.h>#include <linux/uaccess.h>#include "input-compat.h"
#ifdef CONFIG_COMPAT
int input_event_from_user(const char __user *buffer, struct input_event *event){ if (in_compat_syscall() && !COMPAT_USE_64BIT_TIME) { struct input_event_compat compat_event;
if (copy_from_user(&compat_event, buffer, sizeof(struct input_event_compat))) return -EFAULT;
event->input_event_sec = compat_event.sec; event->input_event_usec = compat_event.usec; event->type = compat_event.type; event->code = compat_event.code; event->value = compat_event.value;
} else { if (copy_from_user(event, buffer, sizeof(struct input_event))) return -EFAULT; }
return 0;}
int input_event_to_user(char __user *buffer, const struct input_event *event){ if (in_compat_syscall() && !COMPAT_USE_64BIT_TIME) { struct input_event_compat compat_event;
compat_event.sec = event->input_event_sec; compat_event.usec = event->input_event_usec; compat_event.type = event->type; compat_event.code = event->code; compat_event.value = event->value;
if (copy_to_user(buffer, &compat_event, sizeof(struct input_event_compat))) return -EFAULT;
} else { if (copy_to_user(buffer, event, sizeof(struct input_event))) return -EFAULT; }
return 0;}
int input_ff_effect_from_user(const char __user *buffer, size_t size, struct ff_effect *effect){ if (in_compat_syscall()) { struct ff_effect_compat *compat_effect;
if (size != sizeof(struct ff_effect_compat)) return -EINVAL;
/* * It so happens that the pointer which needs to be changed * is the last field in the structure, so we can retrieve the * whole thing and replace just the pointer. */ compat_effect = (struct ff_effect_compat *)effect;
memset(effect, 0, sizeof(*effect));
if (copy_from_user(compat_effect, buffer, sizeof(struct ff_effect_compat))) return -EFAULT;
if (compat_effect->type == FF_PERIODIC && compat_effect->u.periodic.waveform == FF_CUSTOM) effect->u.periodic.custom_data = compat_ptr(compat_effect->u.periodic.custom_data); } else { if (size != sizeof(struct ff_effect)) return -EINVAL;
if (copy_from_user(effect, buffer, sizeof(struct ff_effect))) return -EFAULT; }
return 0;}
int input_bits_to_string(char *buf, int buf_size, unsigned long bits, bool skip_empty){ int len = 0;
if (in_compat_syscall()) { u32 dword = bits >> 32; if (dword || !skip_empty) len += snprintf(buf, buf_size, "%x ", dword);
dword = bits & 0xffffffffUL; if (dword || !skip_empty || len) len += snprintf(buf + len, max(buf_size - len, 0), "%x", dword); } else { if (bits || !skip_empty) len += snprintf(buf, buf_size, "%lx", bits); }
return len;}
#else
int input_event_from_user(const char __user *buffer, struct input_event *event){ if (copy_from_user(event, buffer, sizeof(struct input_event))) return -EFAULT;
return 0;}
int input_event_to_user(char __user *buffer, const struct input_event *event){ if (copy_to_user(buffer, event, sizeof(struct input_event))) return -EFAULT;
return 0;}
int input_ff_effect_from_user(const char __user *buffer, size_t size, struct ff_effect *effect){ if (size != sizeof(struct ff_effect)) return -EINVAL;
if (copy_from_user(effect, buffer, sizeof(struct ff_effect))) return -EFAULT;
return 0;}
int input_bits_to_string(char *buf, int buf_size, unsigned long bits, bool skip_empty){ return bits || !skip_empty ? snprintf(buf, buf_size, "%lx", bits) : 0;}
#endif /* CONFIG_COMPAT */
EXPORT_SYMBOL_GPL(input_event_from_user);EXPORT_SYMBOL_GPL(input_event_to_user);EXPORT_SYMBOL_GPL(input_ff_effect_from_user);