summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/iio/light/acpi-als.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/iio/light/acpi-als.c')
0 files changed, 0 insertions, 0 deletions
7 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
/*
 * SCM_RIGHTS with unix socket help program for test
 *
 * Copyright IBM, Inc. 2013
 *
 * Authors:
 *  Wenchao Xia    <xiawenc@linux.vnet.ibm.com>
 *
 * This work is licensed under the terms of the GNU LGPL, version 2 or later.
 * See the COPYING.LIB file in the top-level directory.
 */

#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

/* #define SOCKET_SCM_DEBUG */

/*
 * @fd and @fd_to_send will not be checked for validation in this function,
 * a blank will be sent as iov data to notify qemu.
 */
static int send_fd(int fd, int fd_to_send)
{
    struct msghdr msg;
    struct iovec iov[1];
    int ret;
    char control[CMSG_SPACE(sizeof(int))];
    struct cmsghdr *cmsg;

    memset(&msg, 0, sizeof(msg));
    memset(control, 0, sizeof(control));

    /* Send a blank to notify qemu */
    iov[0].iov_base = (void *)" ";
    iov[0].iov_len = 1;

    msg.msg_iov = iov;
    msg.msg_iovlen = 1;

    msg.msg_control = control;
    msg.msg_controllen = sizeof(control);

    cmsg = CMSG_FIRSTHDR(&msg);

    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    memcpy(CMSG_DATA(cmsg), &fd_to_send, sizeof(int));

    do {
        ret = sendmsg(fd, &msg, 0);
    } while (ret < 0 && errno == EINTR);

    if (ret < 0) {
        fprintf(stderr, "Failed to send msg, reason: %s\n", strerror(errno));
    }

    return ret;
}

/* Convert string to fd number. */
static int get_fd_num(const char *fd_str)
{
    int sock;
    char *err;

    errno = 0;
    sock = strtol(fd_str, &err, 10);
    if (errno) {
        fprintf(stderr, "Failed in strtol for socket fd, reason: %s\n",
                strerror(errno));
        return -1;
    }
    if (!*fd_str || *err || sock < 0) {
        fprintf(stderr, "bad numerical value for socket fd '%s'\n", fd_str);
        return -1;
    }

    return sock;
}

/*
 * To make things simple, the caller needs to specify:
 * 1. socket fd.
 * 2. path of the file to be sent.
 */
int main(int argc, char **argv, char **envp)
{
    int sock, fd, ret;

#ifdef SOCKET_SCM_DEBUG
    int i;
    for (i = 0; i < argc; i++) {
        fprintf(stderr, "Parameter %d: %s\n", i, argv[i]);
    }
#endif

    if (argc != 3) {
        fprintf(stderr,
                "Usage: %s < socket-fd > < file-path >\n",
                argv[0]);
        return EXIT_FAILURE;
    }


    sock = get_fd_num(argv[1]);
    if (sock < 0) {
        return EXIT_FAILURE;
    }

    /* Now only open a file in readonly mode for test purpose. If more precise
       control is needed, use python script in file operation, which is
       supposed to fork and exec this program. */
    fd = open(argv[2], O_RDONLY);
    if (fd < 0) {
        fprintf(stderr, "Failed to open file '%s'\n", argv[2]);
        return EXIT_FAILURE;
    }

    ret = send_fd(sock, fd);
    if (ret < 0) {
        close(fd);
        return EXIT_FAILURE;
    }

    close(fd);
    return EXIT_SUCCESS;
}