1
2
3
4
5
6
7
8
9
|
/*
* Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
* the packaging of this file.
*
|
|
|
1
2
3
4
5
6
7
8
9
|
/*
* Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im>
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
* the packaging of this file.
*
|
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
#import "OFInitializationFailedException.h"
#import "OFNotOpenException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFWriteFailedException.h"
#if !defined(HAVE_POSIX_SPAWNP) || !defined(HAVE_SPAWN_H)
extern char **environ;
#endif
@interface OFSubprocess ()
- (void)of_getArgv: (char ***)argv
forProgramName: (OFString *)programName
andArguments: (OFArray *)arguments;
- (char **)of_environmentForDictionary: (OFDictionary *)dictionary;
|
|
>
>
>
|
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
#import "OFInitializationFailedException.h"
#import "OFNotOpenException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFWriteFailedException.h"
#ifndef OF_MACOS
extern char **environ;
#else
# include <crt_externs.h>
# define environ (*_NSGetEnviron())
#endif
@interface OFSubprocess ()
- (void)of_getArgv: (char ***)argv
forProgramName: (OFString *)programName
andArguments: (OFArray *)arguments;
- (char **)of_environmentForDictionary: (OFDictionary *)dictionary;
|
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
|
if (posix_spawnattr_setflags(&attr,
POSIX_SPAWN_CLOEXEC_DEFAULT) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self.class];
# endif
if (posix_spawnp(&_pid, path, &actions, &attr,
argv, env) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self.class];
} @finally {
posix_spawn_file_actions_destroy(&actions);
posix_spawnattr_destroy(&attr);
}
#else
if ((_pid = vfork()) == 0) {
environ = env;
close(_readPipe[0]);
close(_writePipe[1]);
dup2(_writePipe[0], 0);
dup2(_readPipe[1], 1);
execvp(path, argv);
|
|
>
|
|
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
if (posix_spawnattr_setflags(&attr,
POSIX_SPAWN_CLOEXEC_DEFAULT) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self.class];
# endif
if (posix_spawnp(&_pid, path, &actions, &attr,
argv, (env != NULL ? env : environ)) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self.class];
} @finally {
posix_spawn_file_actions_destroy(&actions);
posix_spawnattr_destroy(&attr);
}
#else
if ((_pid = vfork()) == 0) {
if (env != NULL)
environ = env;
close(_readPipe[0]);
close(_writePipe[1]);
dup2(_writePipe[0], 0);
dup2(_readPipe[1], 1);
execvp(path, argv);
|
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
|
}
- (void)close
{
if (_readPipe[0] == -1)
@throw [OFNotOpenException exceptionWithObject: self];
[self closeForWriting];
close(_readPipe[0]);
if (_pid != -1) {
kill(_pid, SIGTERM);
waitpid(_pid, &_status, WNOHANG);
}
|
>
|
>
|
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
|
}
- (void)close
{
if (_readPipe[0] == -1)
@throw [OFNotOpenException exceptionWithObject: self];
if (_writePipe[1] != -1)
[self closeForWriting];
close(_readPipe[0]);
if (_pid != -1) {
kill(_pid, SIGTERM);
waitpid(_pid, &_status, WNOHANG);
}
|