Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #7194 > unrolled thread

reading from a temp file

Started byRuben Safir <ruben@mrbrklyn.com>
First post2011-06-28 08:34 +0000
Last post2011-07-02 00:47 +0000
Articles 9 — 5 participants

Back to article view | Back to comp.lang.c++


Contents

  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

#7194 — reading from a temp file

FromRuben Safir <ruben@mrbrklyn.com>
Date2011-06-28 08:34 +0000
Subjectreading 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]


#7195

FromIan Collins <ian-news@hotmail.com>
Date2011-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]


#7196

Fromjt@toerring.de (Jens Thoms Toerring)
Date2011-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]


#7200

FromRuben Safir <ruben@mrbrklyn.com>
Date2011-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]


#7206

Fromjt@toerring.de (Jens Thoms Toerring)
Date2011-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]


#7318

FromRuben Safir <mrbrklyn@panix.com>
Date2011-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]


#7323

FromMichael DOUBEZ <michael.doubez@free.fr>
Date2011-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]


#7325

FromMichael DOUBEZ <michael.doubez@free.fr>
Date2011-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]


#7340

FromRuben Safir <mrbrklyn@panix.com>
Date2011-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