Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/VLC/src/posix/   (VLC Media Plyer ©)  Datei vom 23.9.2026 mit Größe 4 kB image not shown  

Quelle  process.c   Sprache: C

 

// SPDX-License-Identifier: LGPL-2.1-or-later
/*****************************************************************************
 * process.c: posix implementation of process management
 *****************************************************************************
 * Copyright © 2025 Videolabs, VideoLAN and VLC authors
 *
 * Authors: Gabriel Lafond Thenaille <gabriel@videolabs.io>
 *****************************************************************************/


#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#ifdef HAVE_POLL_H
# include <poll.h>
#endif

#include <assert.h>
#include <signal.h>
#include <sys/poll.h>

#include <vlc_common.h>
#include <vlc_process.h>
#include <vlc_interrupt.h>
#include <vlc_spawn.h>
#include <vlc_poll.h>
#include <vlc_fs.h>
#include <vlc_network.h>

static_assert(HAVE_VLC_PROCESS_SPAWN == 1, "mismatching HAVE_VLC_PROCESS_SPAWN declaration");

struct vlc_process {

    /* Pid of the linked process */
    pid_t pid;

    /* File descriptor of the socketpair */
    int fd;
};

struct vlc_process*
vlc_process_Spawn(const char *path, int argc, const char *const *argv)
{
    assert(path != NULL);
    if (argc > 0) {
        assert(argv != NULL);
        assert(argv[0] != NULL);
    }

    int ret = VLC_EGENERIC;
    int fds[2] = { -1, -1 };
    int extfd_in = -1;
    int extfd_out = -1;
    const char **args = NULL;

    struct vlc_process *process = malloc(sizeof(*process));
    if (process == NULL) {
        return NULL;
    }

    ret = vlc_socketpair(PF_LOCAL, SOCK_STREAM, 0, fds, false);
    if (ret != 0) {
        goto end;
    }

    extfd_in = vlc_dup(fds[1]);
    if (extfd_in == -1) {
        ret = -1;
        goto end;
    }
    extfd_out = vlc_dup(fds[1]);
    if (extfd_out == -1) {
        ret = -1;
        goto end;
    }

    process->fd = fds[0];

    int process_fds[4] = {extfd_in, extfd_out, STDERR_FILENO, -1};

    /* `argc + 2`, 1 for the process->path and the last to be NULL */
    args = malloc((argc + 2) * sizeof(*args));
    if (args == NULL) {
        ret = VLC_ENOMEM;
        goto end;
    }
    args[0] = path;
    for (int i = 0; i < argc; i++) {
        args[i + 1] = argv[i];
    }
    args[argc + 1] = NULL;

    ret = vlc_spawnp(&process->pid, path, process_fds, args);
    if (ret != 0) {
        goto end;
    }

end:

    free(args);

    if (extfd_in != -1) {
        vlc_close(extfd_in);
    }
    if (extfd_out != -1) {
        vlc_close(extfd_out);
    }
    if (fds[1] != -1) {
        net_Close(fds[1]);
    }

    if (ret != 0) {
        if (fds[0] != -1) {
            shutdown(fds[0], SHUT_RDWR);
            net_Close(fds[0]);
        }
        free(process);
        return NULL;
    }
    return process;
}

VLC_API void
vlc_process_Kill(struct vlc_process *process)
{
    assert(process != NULL);

    kill(process->pid, SIGTERM);
    shutdown(process->fd, SHUT_RDWR);
}

VLC_API int
vlc_process_Terminate(struct vlc_process *process, bool kill_process)
{
    assert(process != NULL);

    if (kill_process) {
        vlc_process_Kill(process);
    }

    shutdown(process->fd, SHUT_RDWR);
    net_Close(process->fd);

    int status = vlc_waitpid(process->pid);
    process->pid = 0;
    process->fd = -1;
    free(process);
    return status;
}

ssize_t
vlc_process_fd_Read(struct vlc_process *process, uint8_t *buf, size_t size,
                    vlc_tick_t timeout_ms)
{
    assert(process != NULL);
    assert(process->fd != -1);
    assert(buf != NULL);

    struct pollfd fds = {
        .fd = process->fd, .events = POLLIN, .revents = 0
    };

    int ret = vlc_poll_i11e(&fds, 1, timeout_ms);
    if (ret < 0) {
        return -1;
    } else if (ret == 0) {
        errno = ETIMEDOUT;
        return -1;
    } else if (!(fds.revents & POLLIN)) {
        errno = EINVAL;
        return -1;
    }

    return recv(process->fd, buf, size, 0);
}

ssize_t
vlc_process_fd_Write(struct vlc_process *process, const uint8_t *buf,
                     size_t size, vlc_tick_t timeout_ms)
{
    assert(process != NULL);
    assert(process->fd != -1);
    assert(buf != NULL);

    struct pollfd fds = {
        .fd = process->fd, .events = POLLOUT, .revents = 0
    };

    int ret = vlc_poll_i11e(&fds, 1, timeout_ms);
    if (ret < 0) {
        return -1;
    } else if (ret == 0) {
        errno = ETIMEDOUT;
        return -1;
    } else if (!(fds.revents & POLLOUT)) {
        errno = EINVAL;
        return -1;
    }

    return vlc_send_i11e(process->fd, buf, size, 0);
}

Messung
CHZG
849510093

¤ Dauer der Verarbeitung: 0.0 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.