diff options
Diffstat (limited to 'cras/src/common/cras_util.c')
-rw-r--r-- | cras/src/common/cras_util.c | 264 |
1 files changed, 0 insertions, 264 deletions
diff --git a/cras/src/common/cras_util.c b/cras/src/common/cras_util.c deleted file mode 100644 index 28570bf9..00000000 --- a/cras/src/common/cras_util.c +++ /dev/null @@ -1,264 +0,0 @@ -/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#define _GNU_SOURCE /* For ppoll() */ - -#include <errno.h> -#include <fcntl.h> -#include <pthread.h> -#include <poll.h> -#include <sched.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <sys/param.h> -#include <sys/resource.h> -#include <sys/socket.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <unistd.h> - -#include "cras_util.h" - -int cras_set_rt_scheduling(int rt_lim) -{ - struct rlimit rl; - - rl.rlim_cur = rl.rlim_max = rt_lim; - - if (setrlimit(RLIMIT_RTPRIO, &rl) < 0) { - syslog(LOG_WARNING, "setrlimit %u failed: %d\n", - (unsigned)rt_lim, errno); - return -EACCES; - } - return 0; -} - -int cras_set_thread_priority(int priority) -{ - struct sched_param sched_param; - int err; - - memset(&sched_param, 0, sizeof(sched_param)); - sched_param.sched_priority = priority; - - err = pthread_setschedparam(pthread_self(), SCHED_RR, &sched_param); - if (err) - syslog(LOG_WARNING, - "Failed to set thread sched params to priority %d" - ", rc: %d\n", - priority, err); - - return err; -} - -int cras_set_nice_level(int nice) -{ - int rc; - - /* Linux isn't posix compliant with setpriority(2), it will set a thread - * priority if it is passed a tid, not affecting the rest of the threads - * in the process. Setting this priority will only succeed if the user - * has been granted permission to adjust nice values on the system. - */ - rc = setpriority(PRIO_PROCESS, syscall(__NR_gettid), nice); - if (rc) - syslog(LOG_WARNING, "Failed to set nice to %d, rc: %d", nice, - rc); - - return rc; -} - -int cras_make_fd_nonblocking(int fd) -{ - int fl; - - fl = fcntl(fd, F_GETFL); - if (fl < 0) - return fl; - if (fl & O_NONBLOCK) - return 0; - return fcntl(fd, F_SETFL, fl | O_NONBLOCK); -} - -int cras_make_fd_blocking(int fd) -{ - int fl; - - fl = fcntl(fd, F_GETFL); - if (fl < 0) - return fl; - if ((~fl) & O_NONBLOCK) - return 0; - return fcntl(fd, F_SETFL, fl & ~O_NONBLOCK); -} - -int cras_send_with_fds(int sockfd, const void *buf, size_t len, int *fd, - unsigned int num_fds) -{ - struct msghdr msg = { 0 }; - struct iovec iov; - struct cmsghdr *cmsg; - char *control; - const unsigned int control_size = CMSG_SPACE(sizeof(*fd) * num_fds); - int rc; - - control = calloc(control_size, 1); - - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - iov.iov_base = (void *)buf; - iov.iov_len = len; - - msg.msg_control = control; - msg.msg_controllen = control_size; - - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(*fd) * num_fds); - memcpy(CMSG_DATA(cmsg), fd, sizeof(*fd) * num_fds); - - rc = sendmsg(sockfd, &msg, 0); - if (rc == -1) - rc = -errno; - free(control); - return rc; -} - -int cras_recv_with_fds(int sockfd, void *buf, size_t len, int *fd, - unsigned int *num_fds) -{ - struct msghdr msg = { 0 }; - struct iovec iov; - struct cmsghdr *cmsg; - char *control; - const unsigned int control_size = CMSG_SPACE(sizeof(*fd) * *num_fds); - int rc; - int i; - - control = calloc(control_size, 1); - - for (i = 0; i < *num_fds; i++) - fd[i] = -1; - - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - iov.iov_base = buf; - iov.iov_len = len; - msg.msg_control = control; - msg.msg_controllen = control_size; - - rc = recvmsg(sockfd, &msg, 0); - if (rc < 0) { - rc = -errno; - goto exit; - } - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == SOL_SOCKET && - cmsg->cmsg_type == SCM_RIGHTS) { - size_t fd_size = cmsg->cmsg_len - sizeof(*cmsg); - *num_fds = MIN(*num_fds, fd_size / sizeof(*fd)); - memcpy(fd, CMSG_DATA(cmsg), *num_fds * sizeof(*fd)); - goto exit; - } - } - - // If we reach here, we did not find any file descriptors. - *num_fds = 0; -exit: - free(control); - return rc; -} - -int cras_poll(struct pollfd *fds, nfds_t nfds, struct timespec *timeout, - const sigset_t *sigmask) -{ - struct timespec now; - struct timespec future; - struct pollfd *fd = fds; - nfds_t i; - int rc = 0; - - if (timeout) { - /* Treat a negative timeout as valid (but timed-out) since - * this function could update timeout to have negative tv_sec - * or tv_nsec. */ - if (timeout->tv_sec < 0 || timeout->tv_nsec < 0) - return -ETIMEDOUT; - rc = clock_gettime(CLOCK_MONOTONIC_RAW, &future); - if (rc < 0) - return -errno; - add_timespecs(&future, timeout); - } - - for (i = 0; i < nfds; i++) { - fd->revents = 0; - fd++; - } - - rc = ppoll(fds, nfds, timeout, sigmask); - if (rc == 0 && timeout) { - rc = -ETIMEDOUT; - } else if (rc < 0) { - rc = -errno; - } - - if (timeout) { - clock_gettime(CLOCK_MONOTONIC_RAW, &now); - subtract_timespecs(&future, &now, timeout); - } - - return rc; -} - -int wait_for_dev_input_access() -{ - /* Wait for /dev/input/event* files to become accessible by - * having group 'input'. Setting these files to have 'rw' - * access to group 'input' is done through a udev rule - * installed by adhd into /lib/udev/rules.d. - * - * Wait for up to 2 seconds for the /dev/input/event* files to be - * readable by gavd. - * - * TODO(thutt): This could also be done with a udev enumerate - * and then a udev monitor. - */ - const unsigned max_iterations = 4; - unsigned i = 0; - - while (i < max_iterations) { - int readable; - struct timeval timeout; - const char *const pathname = "/dev/input/event0"; - - timeout.tv_sec = 0; - timeout.tv_usec = 500000; /* 1/2 second. */ - readable = access(pathname, R_OK); - - /* If the file could be opened, then the udev rule has been - * applied and gavd can read the event files. If there are no - * event files, then we don't need to wait. - * - * If access does not become available, then headphone & - * microphone jack autoswitching will not function properly. - */ - if (readable == 0 || (readable == -1 && errno == ENOENT)) { - /* Access allowed, or file does not exist. */ - break; - } - if (readable != -1 || errno != EACCES) { - syslog(LOG_ERR, "Bad access for input devs."); - return errno; - } - select(1, NULL, NULL, NULL, &timeout); - ++i; - } - - return 0; -} |