ObjFW  Diff

Differences From Artifact [ba7c43016e]:

To Artifact [a3654b4d40]:

  • File src/OFStdIOStream.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: 4023) [annotate] [blame] [check-ins using]


18
19
20
21
22
23
24

25
26
27
28
29
30
31
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32







+








/* Work around __block being used by glibc */
#include <stdlib.h>	/* include any libc header to get the libc defines */
#ifdef __GLIBC__
# undef __USE_XOPEN
#endif

#include <errno.h>
#include <unistd.h>

#import "OFStdIOStream.h"
#import "OFDate.h"
#import "OFApplication.h"

#import "OFOutOfRangeException.h"
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
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







+
+
+
+

-
-
+

-
+
+




-
-
+

-
+
+











+
+
+
+

-
+

-
+
+




-
-
+

-
+
+







}

- (size_t)lowlevelReadIntoBuffer: (void*)buffer
			  length: (size_t)length
{
	ssize_t ret;

	if (_fd == -1 || _atEndOfStream)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];

#ifndef _WIN32
	if (_fd == -1 || _atEndOfStream ||
	    (ret = read(_fd, buffer, length)) < 0)
	if ((ret = read(_fd, buffer, length)) < 0)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];
						  requestedLength: length
							    errNo: errno];
#else
	if (length > UINT_MAX)
		@throw [OFOutOfRangeException exception];

	if (_fd == -1 || _atEndOfStream ||
	    (ret = read(_fd, buffer, (unsigned int)length)) < 0)
	if ((ret = read(_fd, buffer, (unsigned int)length)) < 0)
		@throw [OFReadFailedException exceptionWithObject: self
						  requestedLength: length];
						  requestedLength: length
							    errNo: errno];
#endif

	if (ret == 0)
		_atEndOfStream = true;

	return ret;
}

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

#ifndef _WIN32
	if (_fd == -1 || _atEndOfStream || write(_fd, buffer, length) < length)
	if (write(_fd, buffer, length) < length)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length];
						   requestedLength: length
							     errNo: errno];
#else
	if (length > UINT_MAX)
		@throw [OFOutOfRangeException exception];

	if (_fd == -1 || _atEndOfStream ||
	    write(_fd, buffer, (unsigned int)length) < length)
	if (write(_fd, buffer, (unsigned int)length) < length)
		@throw [OFWriteFailedException exceptionWithObject: self
						   requestedLength: length];
						   requestedLength: length
							     errNo: errno];
#endif
}

- (int)fileDescriptorForReading
{
	return _fd;
}