Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #7194 > unrolled thread
| Started by | Ruben Safir <ruben@mrbrklyn.com> |
|---|---|
| First post | 2011-06-28 08:34 +0000 |
| Last post | 2011-07-02 00:47 +0000 |
| Articles | 9 — 5 participants |
Back to article view | Back to comp.lang.c++
reading from a temp file Ruben Safir <ruben@mrbrklyn.com> - 2011-06-28 08:34 +0000
Re: reading from a temp file Ian Collins <ian-news@hotmail.com> - 2011-06-28 20:37 +1200
Re: reading from a temp file jt@toerring.de (Jens Thoms Toerring) - 2011-06-28 09:55 +0000
Re: reading from a temp file Ruben Safir <ruben@mrbrklyn.com> - 2011-06-28 12:32 +0000
Re: reading from a temp file jt@toerring.de (Jens Thoms Toerring) - 2011-06-28 13:54 +0000
Re: reading from a temp file Ruben Safir <mrbrklyn@panix.com> - 2011-07-01 05:14 +0000
Re: reading from a temp file Michael DOUBEZ <michael.doubez@free.fr> - 2011-07-01 00:54 -0700
Re: reading from a temp file Michael DOUBEZ <michael.doubez@free.fr> - 2011-07-01 01:20 -0700
Re: reading from a temp file Ruben Safir <mrbrklyn@panix.com> - 2011-07-02 00:47 +0000
| From | Ruben Safir <ruben@mrbrklyn.com> |
|---|---|
| Date | 2011-06-28 08:34 +0000 |
| Subject | reading from a temp file |
| Message-ID | <iuc3me$nam$2@reader1.panix.com> |
any clue why this isn't retrieving the contents of the temp file
Question Deck::create_question(WINDOW* menu_win, std::ostream &os ,std::istream &in ){
char default_editor[20000] = "vi ";
char * editor;
char tmp[4096];
char path[] = "/tmp/fileXXXXXX";
int fd;
fd = mkstemp(path);
editor = getenv("EDITOR");
if (editor == NULL){
editor = default_editor;
}
strcat(editor, path);
char quest_prompt[] = "Edit Your Question";
....
std::string input_q, input_a;
while( ( c=wgetch(quest_win) ) ){
if ( (c == 10) ){
def_prog_mode();
endwin();
system(editor);
reset_prog_mode();
__gnu_cxx::stdio_filebuf< char> tmpfile_buf(fd, std::ios::binary|std::ios::app);
std::istream is(&tmpfile_buf);
is.seekg(0, std::ios::beg);
while(is){
is.read( tmp, 4096);
std::cerr << "What did we read" << tmp << std::endl;
input_q = tmp;
}
tmpfile_buf.close();
break;
}
}
remove(path);
[toc] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-06-28 20:37 +1200 |
| Message-ID | <96ti78FuacU2@mid.individual.net> |
| In reply to | #7194 |
On 06/28/11 08:34 PM, Ruben Safir wrote:
> any clue why this isn't retrieving the contents of the temp file
>
>
> Question Deck::create_question(WINDOW* menu_win, std::ostream&os ,std::istream&in ){
>
> char default_editor[20000] = "vi ";
> char * editor;
> char tmp[4096];
> char path[] = "/tmp/fileXXXXXX";
Why don't you use strings?
> int fd;
> fd = mkstemp(path);
> editor = getenv("EDITOR");
> if (editor == NULL){
> editor = default_editor;
> }
>
> strcat(editor, path);
> char quest_prompt[] = "Edit Your Question";
> .....
> std::string input_q, input_a;
> while( ( c=wgetch(quest_win) ) ){
> if ( (c == 10) ){
> def_prog_mode();
> endwin();
What are these?
> system(editor);
> reset_prog_mode();
and this?
> __gnu_cxx::stdio_filebuf< char> tmpfile_buf(fd, std::ios::binary|std::ios::app);
What's one of those?
> std::istream is(&tmpfile_buf);
> is.seekg(0, std::ios::beg);
> while(is){
> is.read( tmp, 4096);
> std::cerr<< "What did we read"<< tmp<< std::endl;
> input_q = tmp;
> }
> tmpfile_buf.close();
> break;
> }
> }
> remove(path);
>
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2011-06-28 09:55 +0000 |
| Message-ID | <96tmp9FvidU1@mid.uni-berlin.de> |
| In reply to | #7195 |
Ian Collins <ian-news@hotmail.com> wrote:
> On 06/28/11 08:34 PM, Ruben Safir wrote:
> > any clue why this isn't retrieving the contents of the temp file
> >
> > Question Deck::create_question(WINDOW* menu_win, std::ostream&os ,std::istream&in ){
> >
> > char default_editor[20000] = "vi ";
> > char * editor;
> > char tmp[4096];
> > char path[] = "/tmp/fileXXXXXX";
> Why don't you use strings?
> > int fd;
> > fd = mkstemp(path);
> > editor = getenv("EDITOR");
> > if (editor == NULL){
> > editor = default_editor;
> > }
> >
> > strcat(editor, path);
Also note that if the 'EDITOR' environment variable should be
set you're now trying to write into memory belonging to what-
ever returned the environment string. Definitely not a good
idea - while getenv() unfortunately returns a 'char *' and
not a 'char const *' (which would make this mistake impossible)
it's not meant as allowing you to modify that string (or, worse,
write past its trailing '\0').
> > char quest_prompt[] = "Edit Your Question";
> > .....
> > std::string input_q, input_a;
> > while( ( c=wgetch(quest_win) ) ){
What's 'quest_win'? There's no definition before. Did you mean
'menu_win' instead?
> > if ( (c == 10) ){
> > def_prog_mode();
> > endwin();
> What are these?
I suspect something related to (n)curses.
> > system(editor);
> > reset_prog_mode();
> and this?
> > __gnu_cxx::stdio_filebuf< char> tmpfile_buf(fd, std::ios::binary|std::ios::app);
> What's one of those?
> > std::istream is(&tmpfile_buf);
I suspect a highly system dependent attempt to obtain an input
stream from a file descriptor...
> > is.seekg(0, std::ios::beg);
> > while(is){
What should set 'is' to 0? Shouldn't you check for 'is.eof()'
and/or 'is.fail()'?
> > is.read( tmp, 4096);
> > std::cerr<< "What did we read"<< tmp<< std::endl;
> > input_q = tmp;
> > }
> > tmpfile_buf.close();
> > break;
> > }
> > }
> > remove(path);
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | Ruben Safir <ruben@mrbrklyn.com> |
|---|---|
| Date | 2011-06-28 12:32 +0000 |
| Message-ID | <iuchk3$pjj$1@reader1.panix.com> |
| In reply to | #7196 |
On Tue, 28 Jun 2011 09:55:53 +0000, Jens Thoms Toerring wrote: > Also note that if the 'EDITOR' environment variable should be set you're > now trying to write into memory belonging to what- ever returned the > environment string. Definitely not a good idea - while getenv() > unfortunately returns a 'char *' and not a 'char const *' (which would > make this mistake impossible) it's not meant as allowing you to modify > that string (or, worse, write past its trailing '\0'). what are you say? That I can overwrite the environmental variable?
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2011-06-28 13:54 +0000 |
| Message-ID | <96u4o9F9b6U1@mid.uni-berlin.de> |
| In reply to | #7200 |
Ruben Safir <ruben@mrbrklyn.com> wrote:
> On Tue, 28 Jun 2011 09:55:53 +0000, Jens Thoms Toerring wrote:
> > Also note that if the 'EDITOR' environment variable should be set you're
> > now trying to write into memory belonging to what- ever returned the
> > environment string. Definitely not a good idea - while getenv()
> > unfortunately returns a 'char *' and not a 'char const *' (which would
> > make this mistake impossible) it's not meant as allowing you to modify
> > that string (or, worse, write past its trailing '\0').
> what are you say? That I can overwrite the environmental variable?
>>> editor = getenv("EDITOR");
>>> if (editor == NULL){
>>> editor = default_editor;
>>> }
>>> strcat(editor, path);
With that code you append to the string you got from
getenv() unless it did return NULL, i.e. in the case
that the 'EDITOR' environment variable is set. And
that's not such a good thing to try - you're not even
supposed to change that string. To be (more or less)
on the safe side you would need
editor = getenv( "EDITOR" );
if ( editor != NULL )
{
strcpy( default_editor, editor );
strcat( default_editor, " " ); // needed between command and path
}
editor = default_editor;
strcat( editor, path );
More or less safe because, of course, the 'default_editor'
buffer needs to be large enough and there aren't any tests
for that here (and you have no idea what the 'EDITOR' envi-
ronment variable had been set to). So it probably would be
more prudent to use std::string since then the size gets
adapted automatically to whatever is needed, e.g. something
like
std::string editor( "vi " );
if ( ( char *env = getenv( "EDITOR" ) ) != 0 )
editor = std::string( env ) + " ";
editor += path;
...
system( editor.c_str( ) );
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | Ruben Safir <mrbrklyn@panix.com> |
|---|---|
| Date | 2011-07-01 05:14 +0000 |
| Message-ID | <iujl2t$bu7$1@reader1.panix.com> |
| In reply to | #7206 |
Jens Thoms Toerring <jt@toerring.de> wrote:
> Ruben Safir <ruben@mrbrklyn.com> wrote:
>> On Tue, 28 Jun 2011 09:55:53 +0000, Jens Thoms Toerring wrote:
>
>> > Also note that if the 'EDITOR' environment variable should be set you're
>> > now trying to write into memory belonging to what- ever returned the
>> > environment string. Definitely not a good idea - while getenv()
>> > unfortunately returns a 'char *' and not a 'char const *' (which would
>> > make this mistake impossible) it's not meant as allowing you to modify
>> > that string (or, worse, write past its trailing '\0').
>
>> what are you say? That I can overwrite the environmental variable?
>
>>>> editor = getenv("EDITOR");
>>>> if (editor == NULL){
>>>> editor = default_editor;
>>>> }
>>>> strcat(editor, path);
>
Yeah - that is a definite bug. I must have had a brain crap. I
obviously can strcat onto a string which doesn't have any extra buffer
allocation, let alone do so without checking the size of the string to
assure safety...
> With that code you append to the string you got from
> getenv() unless it did return NULL, i.e. in the case
> that the 'EDITOR' environment variable is set. And
> that's not such a good thing to try - you're not even
> supposed to change that string. To be (more or less)
> on the safe side you would need
>
> editor = getenv( "EDITOR" );
> if ( editor != NULL )
> {
> strcpy( default_editor, editor );
> strcat( default_editor, " " ); // needed between command and path
> }
> editor = default_editor;
> strcat( editor, path );
>
> More or less safe because, of course, the 'default_editor'
> buffer needs to be large enough and there aren't any tests
> for that here (and you have no idea what the 'EDITOR' envi-
> ronment variable had been set to). So it probably would be
> more prudent to use std::string since then the size gets
> adapted automatically to whatever is needed, e.g. something
> like
>
> std::string editor( "vi " );
> if ( ( char *env = getenv( "EDITOR" ) ) != 0 )
> editor = std::string( env ) + " ";
> editor += path;
> ...
> system( editor.c_str( ) );
>
> Regards, Jens
[toc] | [prev] | [next] | [standalone]
| From | Michael DOUBEZ <michael.doubez@free.fr> |
|---|---|
| Date | 2011-07-01 00:54 -0700 |
| Message-ID | <9618fbc5-51e3-4bbd-b9c7-45e15329a5c7@a11g2000yqm.googlegroups.com> |
| In reply to | #7200 |
On Jun 28, 2:32 pm, Ruben Safir <ru...@mrbrklyn.com> wrote: > On Tue, 28 Jun 2011 09:55:53 +0000, Jens Thoms Toerring wrote: > > Also note that if the 'EDITOR' environment variable should be set you're > > now trying to write into memory belonging to what- ever returned the > > environment string. Definitely not a good idea - while getenv() > > unfortunately returns a 'char *' and not a 'char const *' (which would > > make this mistake impossible) it's not meant as allowing you to modify > > that string (or, worse, write past its trailing '\0'). > > what are you say? That I can overwrite the environmental variable? For your process at least. man getenv [...] NOTES The strings in the environment list are of the form name=value. As typically implemented, getenv() returns a pointer to a string within the environment list. The caller must take care not to modify this string, since that would change the environment of the process. The implementation of getenv() is not required to be reentrant. The string pointed to by the return value of getenv() may be statically allocated, and can be modified by a subsequent call to getenv(), putenv(3), setenv(3), or unsetenv(3). [...] -- Michael
[toc] | [prev] | [next] | [standalone]
| From | Michael DOUBEZ <michael.doubez@free.fr> |
|---|---|
| Date | 2011-07-01 01:20 -0700 |
| Message-ID | <c172014c-298e-4077-a806-57e2dab95626@m22g2000yqh.googlegroups.com> |
| In reply to | #7195 |
On Jun 28, 10:37 am, Ian Collins <ian-n...@hotmail.com> wrote:
> On 06/28/11 08:34 PM, Ruben Safir wrote:
>
> > any clue why this isn't retrieving the contents of the temp file
>
> > Question Deck::create_question(WINDOW* menu_win, std::ostream&os ,std::istream&in ){
>
> > char default_editor[20000] = "vi ";
> > char * editor;
> > char tmp[4096];
> > char path[] = "/tmp/fileXXXXXX";
>
> Why don't you use strings?
because mkstemp expect a char* that is modified. A solution is to
using std::vector<char> instead.
>
> > int fd;
> > fd = mkstemp(path);
> > editor = getenv("EDITOR");
> > if (editor == NULL){
> > editor = default_editor;
> > }
>
> > strcat(editor, path);
> > char quest_prompt[] = "Edit Your Question";
> > .....
> > std::string input_q, input_a;
> > while( ( c=wgetch(quest_win) ) ){
> > if ( (c == 10) ){
> > def_prog_mode();
> > endwin();
>
> What are these?
>
> > system(editor);
> > reset_prog_mode();
>
> and this?
A gnu extension for building a filebuf from a file descriptor. IMO
closing the fildescriptor returned and using a simple ifstream with
path, would be less trouble.
In particular, the openmode are not good: binary will not translate
carriage return and app is irrelevant in input mode (and input mode is
missing). Use plain std::ios::in instead.
I don't know how it works in conccurent access, stdio_sync_filebuf<>
may be required here (with minimal buffer size in parameter for good
measure).
> > __gnu_cxx::stdio_filebuf< char> tmpfile_buf(fd, std::ios::binary|std::ios::app);
>
> What's one of those?
>
> > std::istream is(&tmpfile_buf);
> > is.seekg(0, std::ios::beg);
seekg is not guaranteed to work
> > while(is){
> > is.read( tmp, 4096);
> > std::cerr<< "What did we read"<< tmp<< std::endl;
> > input_q = tmp;
> > }
> > tmpfile_buf.close();
Note that you can dump the content of a file with:
std::err<<is.rdbuf();
> > break;
> > }
> > }
> > remove(path);
>
--
Michael
[toc] | [prev] | [next] | [standalone]
| From | Ruben Safir <mrbrklyn@panix.com> |
|---|---|
| Date | 2011-07-02 00:47 +0000 |
| Message-ID | <iulpqv$n0n$1@reader1.panix.com> |
| In reply to | #7325 |
Michael DOUBEZ <michael.doubez@free.fr> wrote:
> On Jun 28, 10:37 am, Ian Collins <ian-n...@hotmail.com> wrote:
>> On 06/28/11 08:34 PM, Ruben Safir wrote:
>>
>> > any clue why this isn't retrieving the contents of the temp file
>>
>> > Question Deck::create_question(WINDOW* menu_win, std::ostream&os ,std::istream&in ){
>>
>> > char default_editor[20000] = "vi ";
>> > char * editor;
>> > char tmp[4096];
>> > char path[] = "/tmp/fileXXXXXX";
>>
>> Why don't you use strings?
>
> because mkstemp expect a char* that is modified. A solution is to
> using std::vector<char> instead.
>
std::vector<char> or std::vector<char *> ?
>>
>> > int fd;
>> > fd = mkstemp(path);
>> > editor = getenv("EDITOR");
>> > if (editor == NULL){
>> > editor = default_editor;
>> > }
>>
>> > strcat(editor, path);
>> > char quest_prompt[] = "Edit Your Question";
>> > .....
>> > std::string input_q, input_a;
>> > while( ( c=wgetch(quest_win) ) ){
>> > if ( (c == 10) ){
>> > def_prog_mode();
>> > endwin();
>>
>> What are these?
>>
>> > system(editor);
>> > reset_prog_mode();
>>
>> and this?
>
> A gnu extension for building a filebuf from a file descriptor. IMO
> closing the fildescriptor returned and using a simple ifstream with
> path, would be less trouble.
Those above are part of ncures.h, but those below as was you describe.
>
> In particular, the openmode are not good: binary will not translate
> carriage return and app is irrelevant in input mode (and input mode is
> missing). Use plain std::ios::in instead.
>
The editor is creating a text file so you might be correct, but I don't
think I want carriage returns altered or interpreted, just eventually
dumped into a data file at 4096 bit clips. And I don't want to deal
with deliminators or terminators on input, or output, which is a problem
with getline and getchar. I want them included in the input stream,
whole.
> I don't know how it works in conccurent access, stdio_sync_filebuf<>
> may be required here (with minimal buffer size in parameter for good
> measure).
>
It didn't have trouble with two seperate streams from the same fd. I
did have trouble using one stream for both in and out.
>> > __gnu_cxx::stdio_filebuf< char> tmpfile_buf(fd, std::ios::binary|std::ios::app);
>>
>> What's one of those?
>>
>> > std::istream is(&tmpfile_buf);
>> > is.seekg(0, std::ios::beg);
>
> seekg is not guaranteed to work
>
Upon input? It didn't work away. I thought maybe I as set to the end
of the stream but it didn't like binary mode at all, and the eof bits
behaved as I expected so I can only guess that it was behaving OK.
>> > while(is){
>> > is.read( tmp, 4096);
>> > std::cerr<< "What did we read"<< tmp<< std::endl;
>> > input_q = tmp;
>> > }
>> > tmpfile_buf.close();
>
> Note that you can dump the content of a file with:
> std::err<<is.rdbuf();
>
I want a guaranteed chunk of 4096, no greater.
>> > break;
>> > }
>> > }
>> > remove(path);
>>
>
> --
> Michael
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web