2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
6 #include <aros/debug.h>
8 #include <proto/exec.h>
10 #include "dos_intern.h"
12 /*****************************************************************************
15 #include <dos/stdio.h>
16 #include <proto/dos.h>
18 AROS_LH4(LONG
, SetVBuf
,
20 /* SetVBuf -- set buffering modes and size */
23 AROS_LHA(BPTR
, file
, D1
),
24 AROS_LHA(STRPTR
, buff
, D2
),
25 AROS_LHA(LONG
, type
, D3
),
26 AROS_LHA(LONG
, size
, D4
),
29 struct DosLibrary
*, DOSBase
, 61, Dos
)
32 Changes the buffering modes and buffer size for a filehandle.
33 With buff == NULL, the current buffer will be deallocated (if it
34 was not a user-supplied one) and a new one of (approximately) size
35 will be allocated. If buffer is non-NULL, it will be used for
36 buffering and must be at least max(size,208) bytes long, and MUST
37 be longword aligned. If size is -1, then only the buffering mode
42 buff - buffer pointer for buffered I/O or NULL.
43 type - buffering mode (see <dos/stdio.h>)
44 size - size of buffer for buffered I/O (sizes less than 208 bytes
45 will be rounded up to 208), or -1.
48 0 if operation succeeded.
50 *****************************************************************************/
54 struct FileHandle
*fh
= (struct FileHandle
*)BADDR(file
);
59 ASSERT_VALID_PTR( fh
);
60 ASSERT_VALID_PTR_OR_NULL(buff
);
62 D(bug("[SetVBuf] file=%p, buff=%p (was %p), mode=%d (flags 0x%x), size %d (was %d)\n", file
, buff
, BADDR(fh
->fh_Buf
), type
, fh
->fh_Flags
, size
, fh
->fh_BufSize
));
64 /* Ensure that buff is BPTR aligned */
65 if (buff
!= BADDR(MKBADDR(buff
)))
71 fh
->fh_Flags
= (fh
->fh_Flags
& ~FHF_NOBUF
) | FHF_LINEBUF
;
75 fh
->fh_Flags
= fh
->fh_Flags
& ~(FHF_NOBUF
| FHF_LINEBUF
);
79 fh
->fh_Flags
= (fh
->fh_Flags
| FHF_NOBUF
) & ~FHF_LINEBUF
;
88 if (fh
->fh_OrigBuf
== fh
->fh_Buf
) {
91 /* Not ours, so we're not going to free it. */
93 if (!vbuf_alloc(fh
, buff
, size
))
104 vbuf_free(FileHandlePtr fh
)
106 if (fh
->fh_Flags
& FHF_BUF
)
108 /* free buffer allocated by system */
109 if (fh
->fh_Flags
& FHF_OWNBUF
)
110 FreeMem(BADDR(fh
->fh_Buf
), fh
->fh_BufSize
);
113 fh
->fh_Pos
= fh
->fh_End
= 0;
115 fh
->fh_OrigBuf
= BNULL
;
118 fh
->fh_Flags
&= ~(FHF_BUF
| FHF_OWNBUF
);
121 APTR
vbuf_alloc(FileHandlePtr fh
, STRPTR buf
, ULONG size
)
123 ULONG flags
= FHF_BUF
;
130 buf
= AllocMem(size
, MEMF_ANY
);
131 fh
->fh_OrigBuf
= MKBADDR(buf
);
137 fh
->fh_BufSize
= size
;
138 fh
->fh_Flags
|= flags
;
139 fh
->fh_Buf
= MKBADDR(buf
);
141 fh
->fh_End
= (fh
->fh_Flags
& FHF_WRITE
) ? fh
->fh_BufSize
: 0;
147 BOOL
vbuf_inject(BPTR fh
, CONST_STRPTR argptr
, ULONG size
, struct DosLibrary
*DOSBase
)
149 FileHandlePtr fhinput
;
156 /* Handle the trivial case, where we have enough room
157 * in the minimal buffer.
159 * For AOS 1.3 C:Run compatabilty, the injected buffer
160 * MUST start at Pos==0. Yes, that stupid command does
161 * not check that fh_Pos is nonzero.
163 if ((fhinput
->fh_Flags
& FHF_BUF
) && size
<= 208) {
164 CopyMem(argptr
, BADDR(fhinput
->fh_Buf
), size
);
166 fhinput
->fh_End
= size
;
170 /* Check to see if this FileHandle has been mangled
171 * by someone else. BCPL programs like to do this,
172 * to work around argument injection issues with the
173 * old BCPL version of RunCommand.
175 if (fhinput
->fh_Flags
& FHF_BUF
) {
176 if (fhinput
->fh_Flags
& FHF_OWNBUF
) {
177 if (fhinput
->fh_Buf
!= fhinput
->fh_OrigBuf
) {
178 D(bug("%s: Not injecting to fh %p - nonstandard buffering detected\n", __func__
, fhinput
));
185 /* Deallocate old filehandle's buffer (if any) */
188 /* Must be always buffered or EndCLI won't work */
189 buf
= vbuf_alloc(fhinput
, NULL
, size
);
192 D(bug("[vbuf_inject] Handle 0x%p, buffer 0x%p, injecting string: %s, size: %u\n", fh
, buf
, argptr
, size
));
198 CopyMem(argptr
, buf
, size
);
199 DB2(bug("[vbuf_inject] Buffer contents:\n"); hexdump(buf
, (IPTR
)buf
, size
));
201 fhinput
->fh_End
= size
;