rev |
line source |
pascal@1001
|
1 --- gpxe-0.9.3/src/arch/i386/interface/pxe/pxe_call.c
|
pascal@1001
|
2 +++ gpxe-0.9.3/src/arch/i386/interface/pxe/pxe_call.c
|
pascal@1001
|
3 @@ -96,6 +96,8 @@
|
pascal@1001
|
4 PXENV_EXIT_t ( * file_select ) ( struct s_PXENV_FILE_SELECT * );
|
pascal@1001
|
5 PXENV_EXIT_t ( * file_read ) ( struct s_PXENV_FILE_READ * );
|
pascal@1001
|
6 PXENV_EXIT_t ( * get_file_size ) ( struct s_PXENV_GET_FILE_SIZE * );
|
pascal@1001
|
7 + PXENV_EXIT_t ( * file_exec ) ( struct s_PXENV_FILE_EXEC * );
|
pascal@1001
|
8 + PXENV_EXIT_t ( * file_api_check ) ( struct s_PXENV_FILE_API_CHECK * );
|
pascal@1001
|
9 };
|
pascal@1001
|
10
|
pascal@1001
|
11 /**
|
pascal@1001
|
12 @@ -294,6 +296,14 @@
|
pascal@1001
|
13 pxenv_call.get_file_size = pxenv_get_file_size;
|
pascal@1001
|
14 param_len = sizeof ( pxenv_any.get_file_size );
|
pascal@1001
|
15 break;
|
pascal@1001
|
16 + case PXENV_FILE_EXEC:
|
pascal@1001
|
17 + pxenv_call.file_exec = pxenv_file_exec;
|
pascal@1001
|
18 + param_len = sizeof ( pxenv_any.file_exec );
|
pascal@1001
|
19 + break;
|
pascal@1001
|
20 + case PXENV_FILE_API_CHECK:
|
pascal@1001
|
21 + pxenv_call.file_api_check = pxenv_file_api_check;
|
pascal@1001
|
22 + param_len = sizeof ( pxenv_any.file_api_check );
|
pascal@1001
|
23 + break;
|
pascal@1001
|
24 default:
|
pascal@1001
|
25 DBG ( "PXENV_UNKNOWN_%hx", opcode );
|
pascal@1001
|
26 pxenv_call.unknown = pxenv_unknown;
|
pascal@1001
|
27
|
pascal@962
|
28 --- gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
|
pascal@962
|
29 +++ gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
|
pascal@1010
|
30 @@ -197,7 +197,7 @@
|
pascal@1010
|
31 */
|
pascal@1010
|
32
|
pascal@1010
|
33 /* Jump to loaded copy */
|
pascal@1010
|
34 - ljmp $SYSSEG, $run_etherboot
|
pascal@1010
|
35 + ljmp $SYSSEG, $run_etherboot2
|
pascal@1010
|
36
|
pascal@1010
|
37 endseg: .word SYSSEG + _load_size_pgh
|
pascal@1010
|
38 .section ".zinfo.fixup", "a" /* Compressor fixup information */
|
pascal@1010
|
39 @@ -441,11 +441,16 @@
|
pascal@962
|
40 /* Calculated lcall to _start with %cs:0000 = image start */
|
pascal@962
|
41 lret
|
pascal@962
|
42
|
pascal@962
|
43 +boot_url:
|
pascal@1001
|
44 + .space 256, 0
|
pascal@962
|
45
|
pascal@962
|
46 .org PREFIXSIZE
|
pascal@962
|
47 /*
|
pascal@1010
|
48 We're now at the beginning of the kernel proper.
|
pascal@1010
|
49 */
|
pascal@1010
|
50 +run_etherboot2:
|
pascal@1010
|
51 + push %cs
|
pascal@1010
|
52 + pop %ds
|
pascal@1010
|
53 run_etherboot:
|
pascal@1010
|
54 call install
|
pascal@1010
|
55
|
pascal@1010
|
56 @@ -453,6 +458,13 @@
|
pascal@962
|
57 movw %bx, %ss
|
pascal@962
|
58 movw $_estack16, %sp
|
pascal@962
|
59
|
pascal@962
|
60 + /* Copy our boot_url structure to the forced_url variable */
|
pascal@962
|
61 + movw %bx, %es
|
pascal@962
|
62 + movw $forced_url, %di
|
pascal@962
|
63 + movw $boot_url, %si
|
pascal@1001
|
64 + movw $256, %cx
|
pascal@962
|
65 + rep movsb
|
pascal@962
|
66 +
|
pascal@962
|
67 /* Jump to .text16 segment */
|
pascal@962
|
68 pushw %ax
|
pascal@962
|
69 pushw $1f
|
pascal@962
|
70 --- gpxe-0.9.3/src/arch/i386/prefix/pxeprefix.S
|
pascal@962
|
71 +++ gpxe-0.9.3/src/arch/i386/prefix/pxeprefix.S
|
pascal@1001
|
72 @@ -19,6 +19,9 @@
|
pascal@962
|
73 .section ".prefix"
|
pascal@962
|
74 /* Set up our non-stack segment registers */
|
pascal@962
|
75 jmp $0x7c0, $1f
|
pascal@1001
|
76 +#define PXELOADER_KEEP_UNDI
|
pascal@962
|
77 +boot_url:
|
pascal@1001
|
78 + .space 256, 0
|
pascal@962
|
79 1: movw %cs, %ax
|
pascal@962
|
80 movw %ax, %ds
|
pascal@962
|
81 movw $0x40, %ax /* BIOS data segment access */
|
pascal@1001
|
82 @@ -703,16 +706,22 @@
|
pascal@962
|
83 /* Set up real-mode stack */
|
pascal@962
|
84 movw %bx, %ss
|
pascal@962
|
85 movw $_estack16, %sp
|
pascal@962
|
86 -
|
pascal@962
|
87 + movw %bx, %es
|
pascal@962
|
88 +
|
pascal@962
|
89 #ifdef PXELOADER_KEEP_UNDI
|
pascal@962
|
90 /* Copy our undi_device structure to the preloaded_undi variable */
|
pascal@962
|
91 - movw %bx, %es
|
pascal@962
|
92 movw $preloaded_undi, %di
|
pascal@962
|
93 movw $undi_device, %si
|
pascal@962
|
94 movw $undi_device_size, %cx
|
pascal@962
|
95 rep movsb
|
pascal@962
|
96 #endif
|
pascal@962
|
97
|
pascal@962
|
98 + /* Copy our boot_url structure to the forced_url variable */
|
pascal@962
|
99 + movw $forced_url, %di
|
pascal@962
|
100 + movw $boot_url, %si
|
pascal@1001
|
101 + movw $256, %cx
|
pascal@962
|
102 + rep movsb
|
pascal@962
|
103 +
|
pascal@962
|
104 /* Jump to .text16 segment with %ds pointing to .data16 */
|
pascal@962
|
105 movw %bx, %ds
|
pascal@962
|
106 pushw %ax
|
pascal@962
|
107
|
pascal@1001
|
108 --- gpxe-0.9.3/src/include/pxe_api.h
|
pascal@1001
|
109 +++ gpxe-0.9.3/src/include/pxe_api.h
|
pascal@1001
|
110 @@ -1684,6 +1684,54 @@
|
pascal@1001
|
111
|
pascal@1001
|
112 /** @} */ /* pxenv_get_file_size */
|
pascal@1001
|
113
|
pascal@1001
|
114 +/** @defgroup pxenv_file_exec PXENV_FILE_EXEC
|
pascal@1001
|
115 + *
|
pascal@1001
|
116 + * FILE EXEC
|
pascal@1001
|
117 + *
|
pascal@1001
|
118 + * @{
|
pascal@1001
|
119 + */
|
pascal@1001
|
120 +
|
pascal@1001
|
121 +/** PXE API function code for pxenv_file_exec() */
|
pascal@1001
|
122 +#define PXENV_FILE_EXEC 0x00e5
|
pascal@1001
|
123 +
|
pascal@1001
|
124 +/** Parameter block for pxenv_file_exec() */
|
pascal@1001
|
125 +struct s_PXENV_FILE_EXEC {
|
pascal@1001
|
126 + PXENV_STATUS_t Status; /**< PXE status code */
|
pascal@1001
|
127 + SEGOFF16_t Command; /**< Command to execute */
|
pascal@1001
|
128 +} PACKED;
|
pascal@1001
|
129 +
|
pascal@1001
|
130 +typedef struct s_PXENV_FILE_EXEC PXENV_FILE_EXEC_t;
|
pascal@1001
|
131 +
|
pascal@1001
|
132 +extern PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec );
|
pascal@1001
|
133 +
|
pascal@1001
|
134 +/** @} */ /* pxenv_file_exec */
|
pascal@1001
|
135 +
|
pascal@1001
|
136 +/** @defgroup pxenv_file_api_check PXENV_FILE_API_CHECK
|
pascal@1001
|
137 + *
|
pascal@1001
|
138 + * FILE API CHECK
|
pascal@1001
|
139 + *
|
pascal@1001
|
140 + * @{
|
pascal@1001
|
141 + */
|
pascal@1001
|
142 +
|
pascal@1001
|
143 +/** PXE API function code for pxenv_file_api_check() */
|
pascal@1001
|
144 +#define PXENV_FILE_API_CHECK 0x00e6
|
pascal@1001
|
145 +
|
pascal@1001
|
146 +/** Parameter block for pxenv_file_api_check() */
|
pascal@1001
|
147 +struct s_PXENV_FILE_API_CHECK {
|
pascal@1001
|
148 + PXENV_STATUS_t Status; /**< PXE status code */
|
pascal@1001
|
149 + UINT16_t Size; /**< Size of structure */
|
pascal@1001
|
150 + UINT32_t Magic; /**< Magic number */
|
pascal@1001
|
151 + UINT32_t Provider; /**< Implementation identifier */
|
pascal@1001
|
152 + UINT32_t APIMask; /**< Supported API functions */
|
pascal@1001
|
153 + UINT32_t Flags; /**< Reserved for the future */
|
pascal@1001
|
154 +} PACKED;
|
pascal@1001
|
155 +
|
pascal@1001
|
156 +typedef struct s_PXENV_FILE_API_CHECK PXENV_FILE_API_CHECK_t;
|
pascal@1001
|
157 +
|
pascal@1001
|
158 +extern PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check );
|
pascal@1001
|
159 +
|
pascal@1001
|
160 +/** @} */ /* pxenv_file_api_check */
|
pascal@1001
|
161 +
|
pascal@1001
|
162 /** @} */ /* pxe_file_api */
|
pascal@1001
|
163
|
pascal@1001
|
164 /** @defgroup pxe_loader_api PXE Loader API
|
pascal@1001
|
165
|
pascal@1001
|
166 --- gpxe-0.9.3/src/include/pxe.h
|
pascal@1001
|
167 +++ gpxe-0.9.3/src/include/pxe.h
|
pascal@1001
|
168 @@ -63,6 +63,8 @@
|
pascal@1001
|
169 struct s_PXENV_FILE_SELECT file_select;
|
pascal@1001
|
170 struct s_PXENV_FILE_READ file_read;
|
pascal@1001
|
171 struct s_PXENV_GET_FILE_SIZE get_file_size;
|
pascal@1001
|
172 + struct s_PXENV_FILE_EXEC file_exec;
|
pascal@1001
|
173 + struct s_PXENV_FILE_API_CHECK file_api_check;
|
pascal@1001
|
174 };
|
pascal@1001
|
175
|
pascal@1001
|
176 typedef union u_PXENV_ANY PXENV_ANY_t;
|
pascal@1001
|
177
|
pascal@1001
|
178 --- gpxe-0.9.3/src/interface/pxe/pxe_file.c
|
pascal@1001
|
179 +++ gpxe-0.9.3/src/interface/pxe/pxe_file.c
|
pascal@1001
|
180 @@ -31,7 +31,7 @@
|
pascal@1001
|
181 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
pascal@1001
|
182 */
|
pascal@1001
|
183
|
pascal@1001
|
184 -FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 1 );
|
pascal@1001
|
185 +FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 2 );
|
pascal@1001
|
186
|
pascal@1001
|
187 /**
|
pascal@1001
|
188 * FILE OPEN
|
pascal@1005
|
189 @@ -148,12 +148,14 @@
|
pascal@1005
|
190
|
pascal@1005
|
191 buffer = real_to_user ( file_read->Buffer.segment,
|
pascal@1005
|
192 file_read->Buffer.offset );
|
pascal@1005
|
193 - if ( ( len = read_user ( file_read->FileHandle, buffer, 0,
|
pascal@1005
|
194 + while ( ( len = read_user ( file_read->FileHandle, buffer, 0,
|
pascal@1005
|
195 file_read->BufferSize ) ) < 0 ) {
|
pascal@1005
|
196 file_read->Status = PXENV_STATUS ( len );
|
pascal@1005
|
197 + if (len == (ssize_t) -1309286401 /* -EWOULDBLOCK */ ) {
|
pascal@1005
|
198 + continue;
|
pascal@1005
|
199 + }
|
pascal@1005
|
200 return PXENV_EXIT_FAILURE;
|
pascal@1005
|
201 }
|
pascal@1005
|
202 -
|
pascal@1005
|
203 DBG ( " read %04zx", ( ( size_t ) len ) );
|
pascal@1005
|
204
|
pascal@1005
|
205 file_read->BufferSize = len;
|
pascal@1005
|
206 @@ -189,3 +191,76 @@
|
pascal@1001
|
207 get_file_size->Status = PXENV_STATUS_SUCCESS;
|
pascal@1001
|
208 return PXENV_EXIT_SUCCESS;
|
pascal@1001
|
209 }
|
pascal@1001
|
210 +
|
pascal@1001
|
211 +/**
|
pascal@1001
|
212 + * FILE EXEC
|
pascal@1001
|
213 + *
|
pascal@1001
|
214 + * @v file_exec Pointer to a struct s_PXENV_FILE_EXEC
|
pascal@1001
|
215 + * @v s_PXENV_FILE_EXEC::Command Command to execute
|
pascal@1001
|
216 + * @ret #PXENV_EXIT_SUCCESS Command was executed successfully
|
pascal@1001
|
217 + * @ret #PXENV_EXIT_FAILURE Command was not executed successfully
|
pascal@1001
|
218 + * @ret s_PXENV_FILE_EXEC::Status PXE status code
|
pascal@1001
|
219 + *
|
pascal@1001
|
220 + */
|
pascal@1001
|
221 +PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) {
|
pascal@1001
|
222 + userptr_t command;
|
pascal@1001
|
223 + size_t command_len;
|
pascal@1001
|
224 + int rc;
|
pascal@1001
|
225 +
|
pascal@1001
|
226 + DBG ( "PXENV_FILE_EXEC" );
|
pascal@1001
|
227 +
|
pascal@1001
|
228 + /* Copy name from external program, and exec it */
|
pascal@1001
|
229 + command = real_to_user ( file_exec->Command.segment,
|
pascal@1001
|
230 + file_exec->Command.offset );
|
pascal@1001
|
231 + command_len = strlen_user ( command, 0 );
|
pascal@1001
|
232 + {
|
pascal@1001
|
233 + char command_string[ command_len + 1 ];
|
pascal@1001
|
234 +
|
pascal@1001
|
235 + copy_from_user ( command_string, command, 0,
|
pascal@1001
|
236 + sizeof ( command_string ) );
|
pascal@1001
|
237 + DBG ( " %s", command_string );
|
pascal@1001
|
238 +
|
pascal@1001
|
239 + if ( ( rc = system ( command_string ) ) != 0 ) {
|
pascal@1001
|
240 + file_exec->Status = PXENV_STATUS ( rc );
|
pascal@1001
|
241 + return PXENV_EXIT_FAILURE;
|
pascal@1001
|
242 + }
|
pascal@1001
|
243 + }
|
pascal@1001
|
244 +
|
pascal@1001
|
245 + file_exec->Status = PXENV_STATUS_SUCCESS;
|
pascal@1001
|
246 + return PXENV_EXIT_SUCCESS;
|
pascal@1001
|
247 +}
|
pascal@1001
|
248 +
|
pascal@1001
|
249 +/**
|
pascal@1001
|
250 + * FILE API CHECK
|
pascal@1001
|
251 + *
|
pascal@1001
|
252 + * @v file_exec Pointer to a struct s_PXENV_FILE_API_CHECK
|
pascal@1001
|
253 + * @v s_PXENV_FILE_API_CHECK::Magic Inbound magic number (0x91d447b2)
|
pascal@1001
|
254 + * @ret #PXENV_EXIT_SUCCESS Command was executed successfully
|
pascal@1001
|
255 + * @ret #PXENV_EXIT_FAILURE Command was not executed successfully
|
pascal@1001
|
256 + * @ret s_PXENV_FILE_API_CHECK::Status PXE status code
|
pascal@1001
|
257 + * @ret s_PXENV_FILE_API_CHECK::Magic Outbound magic number (0xe9c17b20)
|
pascal@1001
|
258 + * @ret s_PXENV_FILE_API_CHECK::Provider "gPXE" (0x45585067)
|
pascal@1001
|
259 + * @ret s_PXENV_FILE_API_CHECK::APIMask API function bitmask
|
pascal@1001
|
260 + * @ret s_PXENV_FILE_API_CHECK::Flags Reserved
|
pascal@1001
|
261 + *
|
pascal@1001
|
262 + */
|
pascal@1001
|
263 +PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check ) {
|
pascal@1001
|
264 + DBG ( "PXENV_FILE_API_CHECK" );
|
pascal@1001
|
265 +
|
pascal@1001
|
266 + if ( file_api_check->Magic != 0x91d447b2 ) {
|
pascal@1001
|
267 + file_api_check->Status = PXENV_STATUS_BAD_FUNC;
|
pascal@1001
|
268 + return PXENV_EXIT_FAILURE;
|
pascal@1001
|
269 + } else if ( file_api_check->Size <
|
pascal@1001
|
270 + sizeof(struct s_PXENV_FILE_API_CHECK) ) {
|
pascal@1001
|
271 + file_api_check->Status = PXENV_STATUS_OUT_OF_RESOURCES;
|
pascal@1001
|
272 + return PXENV_EXIT_FAILURE;
|
pascal@1001
|
273 + } else {
|
pascal@1001
|
274 + file_api_check->Status = PXENV_STATUS_SUCCESS;
|
pascal@1001
|
275 + file_api_check->Size = sizeof(struct s_PXENV_FILE_API_CHECK);
|
pascal@1001
|
276 + file_api_check->Magic = 0xe9c17b20;
|
pascal@1001
|
277 + file_api_check->Provider = 0x45585067; /* "gPXE" */
|
pascal@1001
|
278 + file_api_check->APIMask = 0x0000007f; /* Functions e0-e6 */
|
pascal@1001
|
279 + file_api_check->Flags = 0; /* None defined */
|
pascal@1001
|
280 + return PXENV_EXIT_SUCCESS;
|
pascal@1001
|
281 + }
|
pascal@1001
|
282 +}
|
pascal@955
|
283 --- gpxe-0.9.3/src/usr/autoboot.c
|
pascal@955
|
284 +++ gpxe-0.9.3/src/usr/autoboot.c
|
pascal@1001
|
285 @@ -120,6 +120,28 @@
|
pascal@962
|
286 return -ENOTSUP;
|
pascal@962
|
287 }
|
pascal@962
|
288
|
pascal@1001
|
289 +static void set_url ( char buf[], const char url[] ) {
|
pascal@1001
|
290 + int i, d = 0;
|
pascal@1001
|
291 +
|
pascal@1001
|
292 + for (i = 0; url[i] >= ' '; i++) {
|
pascal@1001
|
293 + if (url[i] == '/') d = i;
|
pascal@1001
|
294 + buf[i] = url[i];
|
pascal@1001
|
295 + }
|
pascal@1001
|
296 + buf[i] = 0;
|
pascal@1001
|
297 + if (strstr(buf,"pxelinux")) {
|
pascal@1001
|
298 + struct dhcp_option_block *options = list_entry (
|
pascal@1001
|
299 + dhcp_option_blocks.next, typeof ( *options ), list );
|
pascal@1001
|
300 +
|
pascal@1001
|
301 + set_dhcp_option( options, 208, "\xF1\x00\x74\x7E", 4 );
|
pascal@1001
|
302 + set_dhcp_option( options, 210, buf, d+1 );
|
pascal@1001
|
303 + }
|
pascal@1001
|
304 +}
|
pascal@1001
|
305 +
|
pascal@962
|
306 +struct _forced_url {
|
pascal@1001
|
307 + char url[256];
|
pascal@962
|
308 +};
|
pascal@962
|
309 +struct _forced_url __data16 ( forced_url );
|
pascal@962
|
310 +#define forced_url __use_data16 ( forced_url )
|
pascal@962
|
311 /**
|
pascal@962
|
312 * Boot from a network device
|
pascal@962
|
313 *
|
pascal@1001
|
314 @@ -148,6 +170,12 @@
|
pascal@962
|
315 /* Try to download and boot whatever we are given as a filename */
|
pascal@962
|
316 dhcp_snprintf ( buf, sizeof ( buf ),
|
pascal@955
|
317 find_global_dhcp_option ( DHCP_BOOTFILE_NAME ) );
|
pascal@1001
|
318 +
|
pascal@1001
|
319 + if ( forced_url.url[0] != 0 ) {
|
pascal@1001
|
320 + /* Try to boot a forced url if we have one */
|
pascal@1001
|
321 + set_url ( buf, forced_url.url );
|
pascal@1001
|
322 + }
|
pascal@962
|
323 + while (1) {
|
pascal@955
|
324 if ( buf[0] ) {
|
pascal@962
|
325 printf ( "Booting from filename \"%s\"\n", buf );
|
pascal@962
|
326 return boot_filename ( buf );
|
pascal@1001
|
327 @@ -162,7 +190,8 @@
|
pascal@962
|
328 }
|
pascal@962
|
329
|
pascal@955
|
330 printf ( "No filename or root path specified\n" );
|
pascal@955
|
331 - return -ENOENT;
|
pascal@1001
|
332 + set_url ( buf, "http://boot.slitaz.org/gpxe" );
|
pascal@962
|
333 + }
|
pascal@955
|
334 }
|
pascal@962
|
335
|
pascal@962
|
336 /**
|
pascal@1005
|
337
|
pascal@1005
|
338 --- gpxe-0.9.3/src/interface/pxe/pxe_tftp.c
|
pascal@1005
|
339 +++ gpxe-0.9.3/src/interface/pxe/pxe_tftp.c
|
pascal@1005
|
340 @@ -189,7 +189,7 @@
|
pascal@1005
|
341 if ( blksize < TFTP_DEFAULT_BLKSIZE )
|
pascal@1005
|
342 blksize = TFTP_DEFAULT_BLKSIZE;
|
pascal@1005
|
343 snprintf ( uri_string, sizeof ( uri_string ),
|
pascal@1005
|
344 - "tftp://%s:%d%s%s?blksize=%d",
|
pascal@1005
|
345 + "tftp://%s:%d%s%s?blksize=%zd",
|
pascal@1005
|
346 inet_ntoa ( address ), ntohs ( port ),
|
pascal@1005
|
347 ( ( filename[0] == '/' ) ? "" : "/" ), filename, blksize );
|
pascal@1005
|
348 DBG ( " %s", uri_string );
|
pascal@1005
|
349 --- gpxe-0.9.3/src/core/posix_io.c
|
pascal@1005
|
350 +++ gpxe-0.9.3/src/core/posix_io.c
|
pascal@1005
|
351 @@ -114,7 +114,7 @@
|
pascal@1005
|
352 static int
|
pascal@1005
|
353 posix_file_xfer_deliver_iob ( struct xfer_interface *xfer,
|
pascal@1005
|
354 struct io_buffer *iobuf,
|
pascal@1005
|
355 - struct xfer_metadata *meta __unused ) {
|
pascal@1005
|
356 + struct xfer_metadata *meta ) {
|
pascal@1005
|
357 struct posix_file *file =
|
pascal@1005
|
358 container_of ( xfer, struct posix_file, xfer );
|
pascal@1005
|
359
|
pascal@1005
|
360 @@ -125,7 +125,12 @@
|
pascal@1005
|
361 if ( file->filesize < file->pos )
|
pascal@1005
|
362 file->filesize = file->pos;
|
pascal@1005
|
363
|
pascal@1005
|
364 - list_add_tail ( &iobuf->list, &file->data );
|
pascal@1005
|
365 + if ( iob_len ( iobuf ) ) {
|
pascal@1005
|
366 + list_add_tail ( &iobuf->list, &file->data );
|
pascal@1005
|
367 + } else {
|
pascal@1005
|
368 + free_iob ( iobuf );
|
pascal@1005
|
369 + }
|
pascal@1005
|
370 +
|
pascal@1005
|
371 return 0;
|
pascal@1005
|
372 }
|
pascal@1005
|
373
|
pascal@1005
|
374 @@ -293,12 +298,15 @@
|
pascal@1005
|
375 free_iob ( iobuf );
|
pascal@1005
|
376 }
|
pascal@1005
|
377 file->pos += len;
|
pascal@1005
|
378 + assert ( len != 0 );
|
pascal@1005
|
379 return len;
|
pascal@1005
|
380 }
|
pascal@1005
|
381
|
pascal@1005
|
382 /* If file has completed, return (after returning all data) */
|
pascal@1005
|
383 - if ( file->rc != -EINPROGRESS )
|
pascal@1005
|
384 + if ( file->rc != -EINPROGRESS ) {
|
pascal@1005
|
385 + assert ( list_empty ( &file->data ) );
|
pascal@1005
|
386 return file->rc;
|
pascal@1005
|
387 + }
|
pascal@1005
|
388
|
pascal@1005
|
389 /* No data ready and file still in progress; return -WOULDBLOCK */
|
pascal@1005
|
390 return -EWOULDBLOCK;
|