ObjFW  Diff

Differences From Artifact [957d79c2fa]:

To Artifact [5b951c5966]:

  • File src/OFProcess.m — part of check-in [62e2de30b9] at 2015-02-16 08:39:17 on branch trunk — Explicitly pass errno to exceptions

    The old behaviour where the exception would access errno directly on
    creation of the exception was very fragile. The two main problems with
    it were that sometimes it would pick up an errno even though none had
    been set and in other cases that when the exception was created errno
    had already been overridden.

    This also greatly increases errno handling on Win32, especially in
    conjunction with sockets. It can still be improved further, though. (user: js, size: 14203) [annotate] [blame] [check-ins using]


12
13
14
15
16
17
18

19
20
21
22
23
24
25
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"


#include <string.h>

/* Work around __block being used by glibc */
#ifdef __GLIBC__
# undef __USE_XOPEN
#endif








>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <errno.h>
#include <string.h>

/* Work around __block being used by glibc */
#ifdef __GLIBC__
# undef __USE_XOPEN
#endif

452
453
454
455
456
457
458
459



460
461
462

463
464
465
466
467



468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489



490
491
492

493
494
495
496
497
498
499



500
501





502
503


504
505
506
507
508
509
510
#ifndef _WIN32
	ssize_t ret;
#else
	DWORD ret;
#endif

#ifndef _WIN32
	if (_readPipe[0] == -1 || _atEndOfStream ||



	    (ret = read(_readPipe[0], buffer, length)) < 0)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];

#else
	if (length > UINT32_MAX)
		@throw [OFOutOfRangeException exception];

	if (_readPipe[0] == NULL || _atEndOfStream ||



	    !ReadFile(_readPipe[0], buffer, (DWORD)length, &ret, NULL)) {
		if (GetLastError() == ERROR_BROKEN_PIPE) {
			_atEndOfStream = true;
			return 0;
		}

		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];
	}
#endif

	if (ret == 0)
		_atEndOfStream = true;

	return ret;
}

- (void)lowlevelWriteBuffer: (const void*)buffer
		     length: (size_t)length
{
#ifndef _WIN32
	if (_writePipe[1] == -1 || _atEndOfStream ||



	    write(_writePipe[1], buffer, length) < length)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length];

#else
	DWORD ret;

	if (length > UINT32_MAX)
		@throw [OFOutOfRangeException exception];

	if (_writePipe[1] == NULL || _atEndOfStream ||



	    !WriteFile(_writePipe[1], buffer, (DWORD)length, &ret, NULL) ||
	    ret < length)





		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length];


#endif
}

- (int)fileDescriptorForReading
{
#ifndef _WIN32
	return _readPipe[0];







|
>
>
>
|

|
>




|
>
>
>
|




















|
>
>
>
|

|
>






|
>
>
>
|
|
>
>
>
>
>

|
>
>







453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
#ifndef _WIN32
	ssize_t ret;
#else
	DWORD ret;
#endif

#ifndef _WIN32
	if (_readPipe[0] == -1 || _atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];

	if ((ret = read(_readPipe[0], buffer, length)) < 0)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length
							    errNo: errno];
#else
	if (length > UINT32_MAX)
		@throw [OFOutOfRangeException exception];

	if (_readPipe[0] == NULL || _atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];

	if (!ReadFile(_readPipe[0], buffer, (DWORD)length, &ret, NULL)) {
		if (GetLastError() == ERROR_BROKEN_PIPE) {
			_atEndOfStream = true;
			return 0;
		}

		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];
	}
#endif

	if (ret == 0)
		_atEndOfStream = true;

	return ret;
}

- (void)lowlevelWriteBuffer: (const void*)buffer
		     length: (size_t)length
{
#ifndef _WIN32
	if (_writePipe[1] == -1 || _atEndOfStream)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length];

	if (write(_writePipe[1], buffer, length) < length)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length
							     errNo: errno];
#else
	DWORD ret;

	if (length > UINT32_MAX)
		@throw [OFOutOfRangeException exception];

	if (_writePipe[1] == NULL || _atEndOfStream)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length];

	if (!WriteFile(_writePipe[1], buffer, (DWORD)length, &ret, NULL) ||
	    ret < length) {
		int errNo = 0;

		if (GetLastError() == ERROR_BROKEN_PIPE)
			errNo = EPIPE;

		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length
							     errNo: errNo];
	}
#endif
}

- (int)fileDescriptorForReading
{
#ifndef _WIN32
	return _readPipe[0];