in speakup/kobjects.c [622:701]
ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count)
{
struct st_var_header *param;
int ret;
int len;
char *cp;
struct var_t *var_data;
long value;
unsigned long flags;
param = spk_var_header_by_name(attr->attr.name);
if (!param)
return -EINVAL;
if (!param->data)
return 0;
ret = 0;
cp = (char *)buf;
string_unescape_any_inplace(cp);
spin_lock_irqsave(&speakup_info.spinlock, flags);
switch (param->var_type) {
case VAR_NUM:
case VAR_TIME:
if (*cp == 'd' || *cp == 'r' || *cp == '\0')
len = E_DEFAULT;
else if (*cp == '+' || *cp == '-')
len = E_INC;
else
len = E_SET;
if (kstrtol(cp, 10, &value) == 0)
ret = spk_set_num_var(value, param, len);
else
pr_warn("overflow or parsing error has occurred");
if (ret == -ERANGE) {
var_data = param->data;
pr_warn("value for %s out of range, expect %d to %d\n",
param->name,
var_data->u.n.low, var_data->u.n.high);
}
/*
* If voice was just changed, we might need to reset our default
* pitch and volume.
*/
if (param->var_id == VOICE && synth &&
(ret == 0 || ret == -ERESTART)) {
var_data = param->data;
value = var_data->u.n.value;
spk_reset_default_value("pitch", synth->default_pitch,
value);
spk_reset_default_value("vol", synth->default_vol,
value);
}
break;
case VAR_STRING:
len = strlen(cp);
if ((len >= 1) && (cp[len - 1] == '\n'))
--len;
if ((len >= 2) && (cp[0] == '"') && (cp[len - 1] == '"')) {
++cp;
len -= 2;
}
cp[len] = '\0';
ret = spk_set_string_var(cp, param, len);
if (ret == -E2BIG)
pr_warn("value too long for %s\n",
param->name);
break;
default:
pr_warn("%s unknown type %d\n",
param->name, (int)param->var_type);
break;
}
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
if (ret == -ERESTART)
pr_info("%s reset to default value\n", param->name);
return count;
}