+ char *data;
+ audio_buf_info abi;
+
+ ret = task_get_notification(wn->task);
+ if (ret < 0)
+ goto out;
+ ret = btr_node_status(btrn, wn->min_iqs, BTR_NT_LEAF);
+ if (ret <= 0)
+ goto out;
+ if (!powd) {
+ int32_t rate, ch, format;
+
+ if (sound_device_is_busy())
+ return 0;
+ get_btr_sample_rate(btrn, &rate);
+ get_btr_channels(btrn, &ch);
+ get_btr_sample_format(btrn, &format);
+ ret = oss_init(wn, rate, ch, format);
+ if (ret < 0)
+ goto out;
+ set_sound_device_busy();
+ return 0;
+ }
+ btr_merge(btrn, wn->min_iqs);
+ bytes = btr_next_buffer(btrn, &data);
+ frames = bytes / powd->bytes_per_frame;
+ if (!frames) { /* eof and less than a single frame available */
+ ret = -E_WRITE_COMMON_EOF;
+ goto out;
+ }
+ ret = 0;
+ if (!FD_ISSET(powd->fd, &s->wfds))
+ goto out;
+ /* get maximal number of bytes that can be written */
+ ret = ioctl(powd->fd, SNDCTL_DSP_GETOSPACE, &abi);
+ if (ret >= 0) {
+ size_t max_frames = abi.bytes / powd->bytes_per_frame;
+ if (max_frames == 0)
+ goto out;
+ /* cap number of frames to avoid sound artefacts */
+ frames = PARA_MIN(frames, max_frames);
+ }
+ ret = xwrite(powd->fd, data, frames * powd->bytes_per_frame);
+ if (ret < 0)
+ goto out;
+ btr_consume(btrn, ret);
+ ret = 0;
+out:
+ if (ret < 0)
+ btr_remove_node(&wn->btrn);
+ return ret;
+}
+
+__malloc static void *oss_parse_config_or_die(int argc, char **argv)
+{