static int retrievePeerCredentials (PeerCredentials *credentials, int fd) { if (getpeereid(fd, &credentials->euid, &credentials->egid) != -1) return 1; logSystemError("getpeereid"); return 0; }
int usbReadDeviceDescriptor (UsbDevice *device) { errno = ENOSYS; logSystemError("USB device descriptor read"); return 0; }
int runCommand ( int *result, const char *const *command, HostCommandStream *streams, int asynchronous ) { int ok = 0; sigset_t newMask, oldMask; pid_t pid; sigemptyset(&newMask); sigaddset(&newMask, SIGCHLD); sigprocmask(SIG_BLOCK, &newMask, &oldMask); switch ((pid = fork())) { case -1: /* error */ logSystemError("fork"); break; case 0: /* child */ sigprocmask(SIG_SETMASK, &oldMask, NULL); if (processHostCommandStreams(childHostCommandStream, streams)) { execvp(command[0], (char *const*)command); logSystemError("execvp"); } _exit(1); default: /* parent */ if (processHostCommandStreams(parentHostCommandStream, streams)) { ok = 1; if (asynchronous) { *result = 0; } else { int status; if (waitpid(pid, &status, 0) == -1) { logSystemError("waitpid"); } else if (WIFEXITED(status)) { *result = WEXITSTATUS(status); logMessage(LOG_DEBUG, "host command exit status: %d: %s", *result, command[0]); } else if (WIFSIGNALED(status)) { *result = WTERMSIG(status); logMessage(LOG_DEBUG, "host command termination signal: %d: %s", *result, command[0]); *result += 0X80; } else if (WIFSTOPPED(status)) { *result = WSTOPSIG(status); logMessage(LOG_DEBUG, "host command stop signal: %d: %s", *result, command[0]); *result += 0X80; } else { logMessage(LOG_DEBUG, "unknown host command status: 0X%X: %s", status, command[0]); } } } break; } sigprocmask(SIG_SETMASK, &oldMask, NULL); return ok; }
static int readPacket (BrailleDisplay *brl, Packet *packet) { while (1) { int size = sizeof(PacketHeader); int hasPayload = 0; if (brl->data->inputCount >= sizeof(PacketHeader)) { if (brl->data->inputBuffer.packet.header.type & 0X80) { hasPayload = 1; size += brl->data->inputBuffer.packet.header.arg1 + 1; } } if (size <= brl->data->inputCount) { logInputPacket(brl->data->inputBuffer.bytes, size); if (hasPayload) { unsigned char checksum = 0; int index; for (index=0; index<size; index+=1) checksum -= brl->data->inputBuffer.bytes[index]; if (checksum) logMessage(LOG_WARNING, "Input packet checksum error."); } memcpy(packet, &brl->data->inputBuffer, size); memmove(&brl->data->inputBuffer.bytes[0], &brl->data->inputBuffer.bytes[size], brl->data->inputCount -= size); return size; } retry: { int count = gioReadData(brl->data->gioEndpoint, &brl->data->inputBuffer.bytes[brl->data->inputCount], size - brl->data->inputCount, 0); if (count < 1) { if (count == -1) { logSystemError("read"); } else if ((count == 0) && (brl->data->inputCount > 0)) { if (gioAwaitInput(brl->data->gioEndpoint, 1000)) goto retry; if (errno != EAGAIN) count = -1; logPartialPacket(brl->data->inputBuffer.bytes, brl->data->inputCount); brl->data->inputCount = 0; } return count; } brl->data->acknowledgementsMissing = 0; if (!brl->data->inputCount) { static const unsigned char packets[] = { PKT_ACK, PKT_NAK, PKT_KEY, PKT_EXTKEY, PKT_BUTTON, PKT_WHEEL, PKT_INFO }; int first; for (first=0; first<count; first+=1) if (memchr(packets, brl->data->inputBuffer.bytes[first], sizeof(packets))) break; if (first) { logDiscardedBytes(brl->data->inputBuffer.bytes, first); memmove(&brl->data->inputBuffer.bytes[0], &brl->data->inputBuffer.bytes[first], count-=first); } } brl->data->inputCount += count; } } }
UsbDevice * usbFindDevice (UsbDeviceChooser chooser, void *data) { UsbDevice *device = NULL; int result; { static int initialized = 0; if (!initialized) { usb_init(); initialized = 1; } } if ((result = usb_find_busses()) >= 0) { if ((result = usb_find_devices()) >= 0) { struct usb_bus *bus = usb_get_busses(); if (bus) { struct usb_bus *bus0 = bus; do { struct usb_device *dev = bus->devices; if (dev) { struct usb_device *dev0 = dev; do { UsbDeviceExtension *devx; if ((devx = malloc(sizeof(*devx)))) { if ((devx->handle = usb_open(dev))) { if ((device = usbTestDevice(devx, chooser, data))) return device; usb_close(devx->handle); } else { logMessage(LOG_ERR, "USB open error: vendor=%X product=%X", getLittleEndian16(dev->descriptor.idVendor), getLittleEndian16(dev->descriptor.idProduct)); } free(devx); } else { logSystemError("USB device extension allocate"); } if ((dev = dev->next) == dev0) dev = NULL; } while (dev); } if ((bus = bus->next) == bus0) bus = NULL; } while (bus); } } else { errno = -result; logSystemError("USB devices find"); } } else { errno = -result; logSystemError("USB busses find"); } return device; }
int usbDisableAutosuspend (UsbDevice *device) { errno = ENOSYS; logSystemError("USB device autosuspend disable"); return 0; }
static int writeBrailleCells (BrailleDisplay *brl, const unsigned char *cells, size_t count) { if (write(brl->data->brailleDevice, cells, count) != -1) return 1; logSystemError("write"); return 0; }
static int clearBrailleCells (BrailleDisplay *brl) { if (ioctl(brl->data->brailleDevice, METEC_FLAT20_CLEAR_DISPLAY, 0) != -1) return 1; logSystemError("ioctl[METEC_FLAT20_CLEAR_DISPLAY]"); return 0; }
PcmDevice * openPcmDevice (int errorLevel, const char *device) { PcmDevice *pcm; if ((pcm = malloc(sizeof(*pcm)))) { int code; if (*device) { { int ok = 0; long number; char *end; const char *component = device; number = strtol(component, &end, 0); if ((*end && (*end != ':')) || (number < 0) || (number > 0XFF)) { logMessage(errorLevel, "Invalid QSA card number: %s", device); } else if (end == component) { logMessage(errorLevel, "Missing QSA card number: %s", device); } else { pcm->card = number; if (*end) { component = end + 1; number = strtol(component, &end, 0); if (*end || (number < 0) || (number > 0XFF)) { logMessage(errorLevel, "Invalid QSA device number: %s", device); } else if (end == component) { logMessage(errorLevel, "Missing QSA device number: %s", device); } else { pcm->device = number; ok = 1; } } else { pcm->device = 0; ok = 1; } } if (!ok) goto openError; } if ((code = snd_pcm_open(&pcm->handle, pcm->card, pcm->device, SND_PCM_OPEN_PLAYBACK)) < 0) { logPcmError(errorLevel, "open", code); goto openError; } } else if ((code = snd_pcm_open_preferred(&pcm->handle, &pcm->card, &pcm->device, SND_PCM_OPEN_PLAYBACK)) < 0) { logPcmError(errorLevel, "preferred open", code); goto openError; } logMessage(LOG_DEBUG, "QSA PCM device opened: %d:%d", pcm->card, pcm->device); { snd_pcm_channel_info_t info; info.channel = SND_PCM_CHANNEL_PLAYBACK; if ((code = snd_pcm_channel_info(pcm->handle, &info)) >= 0) { logMessage(LOG_DEBUG, "QSA PCM Info: Frag=%d-%d Rate=%d-%d Chan=%d-%d", info.min_fragment_size, info.max_fragment_size, info.min_rate, info.max_rate, info.min_voices, info.max_voices); memset(&pcm->parameters, 0, sizeof(pcm->parameters)); pcm->parameters.channel = info.channel; pcm->parameters.start_mode = SND_PCM_START_DATA; pcm->parameters.stop_mode = SND_PCM_STOP_ROLLOVER; switch (pcm->parameters.mode = SND_PCM_MODE_BLOCK) { case SND_PCM_MODE_BLOCK: pcm->parameters.buf.block.frag_size = MIN(MAX(0X400, info.min_fragment_size), info.max_fragment_size); pcm->parameters.buf.block.frags_min = 1; pcm->parameters.buf.block.frags_max = 0X40; break; default: logMessage(LOG_WARNING, "Unsupported QSA PCM mode: %d", pcm->parameters.mode); goto openError; } pcm->parameters.format.interleave = 1; pcm->parameters.format.rate = info.max_rate; pcm->parameters.format.voices = MIN(MAX(1, info.min_voices), info.max_voices); pcm->parameters.format.format = SND_PCM_SFMT_S16; if (reconfigurePcmChannel(pcm, errorLevel)) { if ((code = snd_pcm_channel_prepare(pcm->handle, pcm->parameters.channel)) >= 0) { return pcm; } else { logPcmError(errorLevel, "prepare channel", code); } } } else { logPcmError(errorLevel, "get channel information", code); } } openError: free(pcm); } else { logSystemError("PCM device allocation"); } return NULL; }
PcmDevice * openPcmDevice (int errorLevel, const char *device) { PcmDevice *pcm; if (!pcmAlsaLibrary) { if (!(pcmAlsaLibrary = loadSharedObject("libasound.so.2"))) { logMessage(LOG_ERR, "Unable to load ALSA PCM library."); return NULL; } PCM_ALSA_LOCATE(strerror); PCM_ALSA_LOCATE(pcm_open); PCM_ALSA_LOCATE(pcm_close); PCM_ALSA_LOCATE(pcm_nonblock); PCM_ALSA_LOCATE(pcm_hw_params_malloc); PCM_ALSA_LOCATE(pcm_hw_params_any); PCM_ALSA_LOCATE(pcm_hw_params_set_access); PCM_ALSA_LOCATE(pcm_hw_params_get_channels); PCM_ALSA_LOCATE(pcm_hw_params_get_channels_min); PCM_ALSA_LOCATE(pcm_hw_params_get_channels_max); PCM_ALSA_LOCATE(pcm_hw_params_set_channels_near); PCM_ALSA_LOCATE(pcm_hw_params_get_format); PCM_ALSA_LOCATE(pcm_hw_params_set_format); PCM_ALSA_LOCATE(pcm_hw_params_get_rate); PCM_ALSA_LOCATE(pcm_hw_params_get_sbits); PCM_ALSA_LOCATE(pcm_hw_params_get_rate_min); PCM_ALSA_LOCATE(pcm_hw_params_get_rate_max); PCM_ALSA_LOCATE(pcm_hw_params_get_period_size); PCM_ALSA_LOCATE(pcm_hw_params_set_rate_near); PCM_ALSA_LOCATE(pcm_hw_params_set_buffer_time_near); PCM_ALSA_LOCATE(pcm_hw_params_set_period_time_near); PCM_ALSA_LOCATE(pcm_hw_params); PCM_ALSA_LOCATE(pcm_hw_params_get_sbits); PCM_ALSA_LOCATE(pcm_hw_params_free); PCM_ALSA_LOCATE(pcm_prepare); PCM_ALSA_LOCATE(pcm_writei); PCM_ALSA_LOCATE(pcm_drain); PCM_ALSA_LOCATE(pcm_drop); PCM_ALSA_LOCATE(pcm_resume); } if ((pcm = malloc(sizeof(*pcm)))) { int result; if (!*device) device = "default"; if ((result = pcmAlsa_pcm_open(&pcm->handle, device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) >= 0) { pcmAlsa_pcm_nonblock(pcm->handle, 0); if ((result = pcmAlsa_pcm_hw_params_malloc(&pcm->hardwareParameters)) >= 0) { if ((result = pcmAlsa_pcm_hw_params_any(pcm->handle, pcm->hardwareParameters)) >= 0) { if ((result = pcmAlsa_pcm_hw_params_set_access(pcm->handle, pcm->hardwareParameters, SND_PCM_ACCESS_RW_INTERLEAVED)) >= 0) { if (configurePcmSampleFormat(pcm, errorLevel)) { if (configurePcmSampleRate(pcm, errorLevel)) { if (configurePcmChannelCount(pcm, errorLevel)) { pcm->bufferTime = 500000; if ((result = pcmAlsa_pcm_hw_params_set_buffer_time_near(pcm->handle, pcm->hardwareParameters, &pcm->bufferTime, NULL)) >= 0) { pcm->periodTime = pcm->bufferTime / 8; if ((result = pcmAlsa_pcm_hw_params_set_period_time_near(pcm->handle, pcm->hardwareParameters, &pcm->periodTime, NULL)) >= 0) { if ((result = pcmAlsa_pcm_hw_params(pcm->handle, pcm->hardwareParameters)) >= 0) { logMessage(LOG_DEBUG, "ALSA PCM: Chan=%u Rate=%u BufTim=%u PerTim=%u", pcm->channelCount, pcm->sampleRate, pcm->bufferTime, pcm->periodTime); return pcm; } else { logPcmError(errorLevel, "set hardware parameters", result); } } else { logPcmError(errorLevel, "set period time near", result); } } else { logPcmError(errorLevel, "set buffer time near", result); } } } } } else { logPcmError(errorLevel, "set access", result); } } else { logPcmError(errorLevel, "get hardware parameters", result); } pcmAlsa_pcm_hw_params_free(pcm->hardwareParameters); } else { logPcmError(errorLevel, "hardware parameters allocation", result); } pcmAlsa_pcm_close(pcm->handle); } else { logPcmError(errorLevel, "open", result); } free(pcm); } else { logSystemError("PCM device allocation"); } return NULL; }
int createPidFile (const char *path, ProcessIdentifier pid) { #if defined(GRUB_RUNTIME) errno = EROFS; #else /* create pid file */ if (!pid) pid = getProcessIdentifier(); if (path && *path) { typedef enum {PFS_ready, PFS_stale, PFS_clash, PFS_error} PidFileState; PidFileState state = PFS_error; int file = open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR #ifdef S_IRGRP | S_IRGRP #endif /* S_IRGRP */ #ifdef S_IROTH | S_IROTH #endif /* S_IROTH */ ); if (file != -1) { int locked = acquireFileLock(file, 1); if (locked || (errno == ENOSYS)) { char buffer[0X20]; ssize_t length; if ((length = read(file, buffer, sizeof(buffer))) != -1) { ProcessIdentifier oldPid; char terminator; int count; if (length == sizeof(buffer)) length -= 1; buffer[length] = 0; count = sscanf(buffer, "%" SCNpid "%c", &oldPid, &terminator); state = PFS_stale; if ((count == 1) || ((count == 2) && ((terminator == '\n') || (terminator == '\r')))) { if (oldPid == pid) { state = PFS_ready; } else if (testProcessIdentifier(oldPid)) { logMessage(LOG_ERR, "instance already running: PID=%" PRIpid, oldPid); state = PFS_clash; } } } else { logSystemError("read"); } if (state == PFS_stale) { state = PFS_error; if (lseek(file, 0, SEEK_SET) != -1) { if (ftruncate(file, 0) != -1) { length = snprintf(buffer, sizeof(buffer), "%" PRIpid "\n", pid); if (write(file, buffer, length) != -1) { state = PFS_ready; } else { logSystemError("write"); } } else { logSystemError("ftruncate"); } } else { logSystemError("lseek"); } } if (locked) releaseFileLock(file); } close(file); } else { logMessage(LOG_WARNING, "%s: %s: %s", gettext("cannot open process identifier file"), path, strerror(errno)); } switch (state) { case PFS_ready: return 1; case PFS_clash: errno = EEXIST; break; case PFS_error: break; default: logMessage(LOG_WARNING, "unexpected PID file state: %u", state); break; } } #endif /* create pid file */ return 0; }