mailing list of musl libc
 help / color / mirror / code / Atom feed
72a95a45a1e077e3bd318a5f5a9bc0364fb5f22c blob 4654 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
 
#define _GNU_SOURCE
#include <spawn.h>
#include <sched.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/wait.h>
#include "syscall.h"
#include "pthread_impl.h"
#include "fdop.h"
#include "libc.h"

static int dup3_or_set_cloexec(int SrcFd, int DestFd, int Flg)
{
	return (DestFd!=SrcFd) ? dup3(SrcFd,DestFd,Flg) : fcntl(DestFd,F_SETFD,Flg);
}

struct args {
	volatile int ret;
	sigset_t oldmask;
	const char *path;
	int (*exec)(const char *, char *const *, char *const *);
	const posix_spawn_file_actions_t *fa;
	const posix_spawnattr_t *restrict attr;
	char *const *argv, *const *envp;
};

void __get_handler_set(sigset_t *);

static int __sys_dup2(int old, int new)
{
#ifdef SYS_dup2
	return __syscall(SYS_dup2, old, new);
#else
	if (old==new) {
		int r = __syscall(SYS_fcntl, old, F_GETFD);
		return r<0 ? r : old;
	} else {
		return __syscall(SYS_dup3, old, new, 0);
	}
#endif
}

static int child(void *args_vp)
{
	int i, ret;
	struct sigaction sa = {0};
	struct args *args = args_vp;
	const posix_spawn_file_actions_t *fa = args->fa;
	const posix_spawnattr_t *restrict attr = args->attr;
	sigset_t hset;


	/* All signal dispositions must be either SIG_DFL or SIG_IGN
	 * before signals are unblocked. Otherwise a signal handler
	 * from the parent might get run in the child while sharing
	 * memory, with unpredictable and dangerous results. To
	 * reduce overhead, sigaction has tracked for us which signals
	 * potentially have a signal handler. */
	__get_handler_set(&hset);
	for (i=1; i<_NSIG; i++) {
		if ((attr->__flags & POSIX_SPAWN_SETSIGDEF)
		     && sigismember(&attr->__def, i)) {
			sa.sa_handler = SIG_DFL;
		} else if (sigismember(&hset, i)) {
			if (i-32<3U) {
				sa.sa_handler = SIG_IGN;
			} else {
				__libc_sigaction(i, 0, &sa);
				if (sa.sa_handler==SIG_IGN) continue;
				sa.sa_handler = SIG_DFL;
			}
		} else {
			continue;
		}
		__libc_sigaction(i, &sa, 0);
	}
	

	if (attr->__flags & POSIX_SPAWN_SETSID)
		if ((ret=__syscall(SYS_setsid)) < 0)
			goto fail;

	if (attr->__flags & POSIX_SPAWN_SETPGROUP)
		if ((ret=__syscall(SYS_setpgid, 0, attr->__pgrp)))
			goto fail;

	/* Use syscalls directly because the library functions attempt
	 * to do a multi-threaded synchronized id-change, which would
	 * trash the parent's state. */
	if (attr->__flags & POSIX_SPAWN_RESETIDS)
		if ((ret=__syscall(SYS_setgid, __syscall(SYS_getgid))) ||
		    (ret=__syscall(SYS_setuid, __syscall(SYS_getuid))) )
			goto fail;

	/*file actions (opens) are potentially long-blocking, so the process should
	 become interruptible before they're invoked */
	pthread_sigmask(SIG_SETMASK, (attr->__flags & POSIX_SPAWN_SETSIGMASK)
		? &attr->__mask : &args->oldmask, 0);


	if (fa && fa->__actions) {
		struct fdop *op;
		int fd;
		for (op = fa->__actions; op->next; op = op->next);
		for (; op; op = op->prev) {
			switch(op->cmd) {
			case FDOP_CLOSE:
				__syscall(SYS_close, op->fd);
				break;
			case FDOP_DUP2:
				if ((ret=dup3_or_set_cloexec(op->srcfd, op->fd, 0))<0)
					goto fail;
				break;
			case FDOP_OPEN:
				fd = __sys_open(op->path, op->oflag, op->mode);
				if ((ret=fd) < 0) goto fail;
				if (fd != op->fd) {
					if ((ret=dup3_or_set_cloexec(fd, op->fd, 0))<0)
						goto fail;
					__syscall(SYS_close, fd);
				}
				break;
			}
		}
	}

	args->exec(args->path, args->argv, args->envp);
	ret = -errno;

fail:
	/* Since sizeof errno < PIPE_BUF, the write is atomic. */
	ret = -ret;
	if (ret) args->ret = ret;
	_exit(127);
}


int __posix_spawnx(pid_t *restrict res, const char *restrict path,
	int (*exec)(const char *, char *const *, char *const *),
	const posix_spawn_file_actions_t *fa,
	const posix_spawnattr_t *restrict attr,
	char *const argv[restrict], char *const envp[restrict])
{
	pid_t pid;
	char stack[1024];
	int ec=0, cs;
	struct args args;

	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);

	args.path = path;
	args.exec = exec;
	args.fa = fa;
	args.attr = attr ? attr : &(const posix_spawnattr_t){0};
	args.argv = argv;
	args.envp = envp;
	pthread_sigmask(SIG_BLOCK, SIGALL_SET, &args.oldmask);

	pid = __clone(child, stack+sizeof stack,
		CLONE_VM|CLONE_VFORK|SIGCHLD, &args);

	if (pid > 0) {
		if (0!=(ec=args.ret)) 
			waitpid(pid, &(int){0}, 0);
	} else {
		ec = -pid;
	}

	if (!ec && res) *res = pid;

	pthread_sigmask(SIG_SETMASK, &args.oldmask, 0);
	pthread_setcancelstate(cs, 0);

	return ec;
}

int posix_spawn(pid_t *restrict res, const char *restrict path,
	const posix_spawn_file_actions_t *fa,
	const posix_spawnattr_t *restrict attr,
	char *const argv[restrict], char *const envp[restrict])
{
	return __posix_spawnx(res, path, execve, fa, attr, argv, envp);
}
debug log:

solving 72a95a45 ...
found 72a95a45 in https://inbox.vuxu.org/musl/CAHy7VY5r_9XzvPOx__n-2k91yXYCHvpjy2emuq=wH8VmmFpy8A@mail.gmail.com/
found 137898d8 in https://inbox.vuxu.org/musl/CAHy7VY5r_9XzvPOx__n-2k91yXYCHvpjy2emuq=wH8VmmFpy8A@mail.gmail.com/
found d4377288 in https://inbox.vuxu.org/musl/CAHy7VY5r_9XzvPOx__n-2k91yXYCHvpjy2emuq=wH8VmmFpy8A@mail.gmail.com/
found ea5d2998 in https://git.vuxu.org/mirror/musl/
preparing index
index prepared:
100644 ea5d29982b8a84b3388800204b64aebdb3c4d52d	src/process/posix_spawn.c

applying [1/3] https://inbox.vuxu.org/musl/CAHy7VY5r_9XzvPOx__n-2k91yXYCHvpjy2emuq=wH8VmmFpy8A@mail.gmail.com/
diff --git a/src/process/posix_spawn.c b/src/process/posix_spawn.c
index ea5d2998..d4377288 100644


applying [2/3] https://inbox.vuxu.org/musl/CAHy7VY5r_9XzvPOx__n-2k91yXYCHvpjy2emuq=wH8VmmFpy8A@mail.gmail.com/
diff --git a/src/process/posix_spawn.c b/src/process/posix_spawn.c
index d4377288..137898d8 100644


applying [3/3] https://inbox.vuxu.org/musl/CAHy7VY5r_9XzvPOx__n-2k91yXYCHvpjy2emuq=wH8VmmFpy8A@mail.gmail.com/
diff --git a/src/process/posix_spawn.c b/src/process/posix_spawn.c
index 137898d8..72a95a45 100644

3:85: trailing whitespace.
		if (0!=(ec=args.ret)) 
Checking patch src/process/posix_spawn.c...
Applied patch src/process/posix_spawn.c cleanly.
2:106: trailing whitespace.
 the user may wish to adddup2 a CLOEXEC filedescriptor 
Checking patch src/process/posix_spawn.c...
Applied patch src/process/posix_spawn.c cleanly.
1:162: trailing whitespace.
	
Checking patch src/process/posix_spawn.c...
Applied patch src/process/posix_spawn.c cleanly.
warning: 3 lines add whitespace errors.

index at:
100644 72a95a45a1e077e3bd318a5f5a9bc0364fb5f22c	src/process/posix_spawn.c

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).