~ubuntu-branches/ubuntu/trusty/musl/trusty-proposed

« back to all changes in this revision

Viewing changes to src/process/system.c

  • Committer: Package Import Robot
  • Author(s): Kevin Bortis
  • Date: 2013-09-20 20:54:14 UTC
  • Revision ID: package-import@ubuntu.com-20130920205414-5b61trtmma18w58o
Tags: upstream-0.9.13
ImportĀ upstreamĀ versionĀ 0.9.13

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <unistd.h>
 
2
#include <fcntl.h>
 
3
#include <signal.h>
 
4
#include <sys/wait.h>
 
5
#include <spawn.h>
 
6
#include <errno.h>
 
7
#include "pthread_impl.h"
 
8
#include "libc.h"
 
9
 
 
10
extern char **__environ;
 
11
 
 
12
int system(const char *cmd)
 
13
{
 
14
        pid_t pid;
 
15
        sigset_t old, reset;
 
16
        struct sigaction sa = { .sa_handler = SIG_IGN }, oldint, oldquit;
 
17
        int status = 0x7f00, ret;
 
18
        posix_spawnattr_t attr;
 
19
 
 
20
        pthread_testcancel();
 
21
 
 
22
        if (!cmd) return 1;
 
23
 
 
24
        sigaction(SIGINT, &sa, &oldint);
 
25
        sigaction(SIGQUIT, &sa, &oldquit);
 
26
        sigaddset(&sa.sa_mask, SIGCHLD);
 
27
        sigprocmask(SIG_BLOCK, &sa.sa_mask, &old);
 
28
 
 
29
        sigemptyset(&reset);
 
30
        if (oldint.sa_handler != SIG_IGN) sigaddset(&reset, SIGINT);
 
31
        if (oldquit.sa_handler != SIG_IGN) sigaddset(&reset, SIGQUIT);
 
32
        posix_spawnattr_init(&attr);
 
33
        posix_spawnattr_setsigmask(&attr, &old);
 
34
        posix_spawnattr_setsigdefault(&attr, &reset);
 
35
        posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETSIGMASK);
 
36
        ret = posix_spawn(&pid, "/bin/sh", 0, &attr,
 
37
                (char *[]){"sh", "-c", (char *)cmd, 0}, __environ);
 
38
        posix_spawnattr_destroy(&attr);
 
39
 
 
40
        if (!ret) while (waitpid(pid, &status, 0)<0 && errno == EINTR);
 
41
        sigaction(SIGINT, &oldint, NULL);
 
42
        sigaction(SIGQUIT, &oldquit, NULL);
 
43
        sigprocmask(SIG_SETMASK, &old, NULL);
 
44
 
 
45
        if (ret) errno = ret;
 
46
        return status;
 
47
}