ObjFW  Check-in [30e5c5ea27]

Overview
Comment:OFProcess: Do all memory allocation before fork()
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 30e5c5ea276bd38e0080293e238b82d0d6fb7809255c17715ef4475f5ba6096c
User & Date: js on 2014-11-09 18:54:51
Other Links: manifest | tags
Context
2014-11-16
21:35
Fix two typos in documentation check-in: 4c2dbb263c user: js tags: trunk
2014-11-09
18:54
OFProcess: Do all memory allocation before fork() check-in: 30e5c5ea27 user: js tags: trunk
2014-10-24
19:12
OFProcess: Use _exit() on failure check-in: f45a6bb10b user: js tags: trunk
Changes

Modified src/OFProcess.m from [02e2a0da24] to [ffa482714b].

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
185
186
187









188
189
190
191
192
193
194
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
185
186







+
+
+
+
+




-
-
-
-
-
-
-
+
-
-
-
-
-
-
+
+
+
+
-
-
+
-
-
-
-
+
-

-
+

-
+
-

-
+
-

-





-
+


+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+







	arguments: (OFArray*)arguments
      environment: (OFDictionary*)environment
{
	self = [super init];

	@try {
#ifndef _WIN32
		void *pool = objc_autoreleasePoolPush();
		const char *path;
		int argc;
		char **argv, **env;

		if (pipe(_readPipe) != 0 || pipe(_writePipe) != 0)
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		switch ((_pid = fork())) {
		case 0:;
			OFString *const *objects = [arguments objects];
			size_t i, count = [arguments count];
			char **argv;
			of_string_encoding_t encoding;

		path = [program cStringWithEncoding:
			argv = [self allocMemoryWithSize: sizeof(char*)
						   count: count + 2];

			encoding = [OFSystemInfo native8BitEncoding];

			argv[0] = (char*)[programName
		    [OFSystemInfo native8BitEncoding]];
		[self OF_getArgC: &argc
			 andArgV: &argv
		  forProgramName: programName
			    cStringWithEncoding: encoding];

		    andArguments: arguments];
			for (i = 0; i < count; i++)
				argv[i + 1] = (char*)[objects[i]
				    cStringWithEncoding: encoding];

		env = [self OF_environmentForDictionary: environment];
			argv[i + 1] = NULL;

			if (environment != nil) {
		if ((_pid = fork()) == 0) {
#ifdef __MACH__
				*_NSGetEnviron() = [self
			*_NSGetEnviron() = env;
				    OF_environmentForDictionary: environment];
#else
				environ = [self
			environ = env;
				    OF_environmentForDictionary: environment];
#endif
			}

			close(_readPipe[0]);
			close(_writePipe[1]);
			dup2(_writePipe[0], 0);
			dup2(_readPipe[1], 1);
			execvp([program cStringWithEncoding: encoding], argv);
			execvp(path, argv);

			_exit(EXIT_FAILURE);
		}
		case -1:

			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];
		default:
			close(_readPipe[1]);
			close(_writePipe[0]);
			break;
		}
		close(_readPipe[1]);
		close(_writePipe[0]);
		[self freeMemory: argv];

		if (_pid == -1)
			@throw [OFInitializationFailedException
			    exceptionWithClass: [self class]];

		objc_autoreleasePoolPop(pool);
#else
		SECURITY_ATTRIBUTES sa;
		PROCESS_INFORMATION pi;
		STARTUPINFOW si;
		void *pool;
		OFMutableString *argumentsString;
		OFEnumerator *enumerator;
299
300
301
302
303
304
305























306
307
308
309
310
311
312
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







{
	[self close];

	[super dealloc];
}

#ifndef _WIN32
- (void)OF_getArgC: (int*)argc
	   andArgV: (char***)argv
    forProgramName: (OFString*)programName
      andArguments: (OFArray*)arguments
{
	OFString *const *objects = [arguments objects];
	size_t i, count = [arguments count];
	of_string_encoding_t encoding;

	*argv = [self allocMemoryWithSize: sizeof(char*)
				    count: count + 2];

	encoding = [OFSystemInfo native8BitEncoding];

	(*argv)[0] = (char*)[programName cStringWithEncoding: encoding];

	for (i = 0; i < count; i++)
		(*argv)[i + 1] =
		    (char*)[objects[i] cStringWithEncoding: encoding];

	(*argv)[i + 1] = NULL;
}

- (char**)OF_environmentForDictionary: (OFDictionary*)environment
{
	OFEnumerator *keyEnumerator, *objectEnumerator;
	char **envp;
	size_t i, count;
	of_string_encoding_t encoding;