0

I am creating a simple logging program. When a user enters log some_file into the console, the program currently simply receives some basic input from cin, and records it into some_file.

However, instead of implementing my own editor with cin, I'd like to open the Nano editor and let the user edit his message there.

Then, when the message is complete, I'd like my C++ logger to receive it as a string and carry on.

This is exactly what git does on commits.

How can I achieve this?

(Preferably without using tools such as expect, just raw C++ code.)

corazza
  • 31,222
  • 37
  • 115
  • 186

3 Answers3

3

Most editors expect to work with normal files, so you'd typically create a temporary file, then pass the name of that file to the editor on its command line. When the editor returns, you copy the content from the temporary file into your log, then destroy the file.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1

If you want to use the Nano editor then you need to run the system() function to invoke Nano with a temporary file. Then remove the file later..

std::string filename = "/tmp/.out." + std::to_string(getpid());
std::string cmd = "/bin/nano " + filename
system(cmd.c_str());
// read from filename
unlink(filename.c_str());

Update

If using tmpnam() as suggested by DevSolar

char filename[L_tmpnam];
tmpnam(filename);
std::string cmd  = "/bin/nano " + filename
system(cmd.c_str());
unlink(filename);
Ajith
  • 613
  • 1
  • 15
  • 32
  • 1
    The problem with this is there may be another `out.txt` in `/tmp` which could have permissions for another user (check out the sticky bit on `/tmp` if you don't already understand). The best option would be to have a library make a temporary file for you, e.g., `mktemp` from the command-line will make a temporary file for you. – Ian Stapleton Cordasco Jan 08 '13 at 15:20
  • But to run mktemp from C++ you will need to depend on system() again. And you would need to know the filename that is created at run time. Wouldn't it be better to use maybe getpid(), some other more unique string to append it to the filename and generate it yourself. – Ajith Jan 08 '13 at 15:30
  • 1
    You could use the library function `tmpnam()`, which provides you with a somewhat-unique name for a temporary file that did not exist **at the time of the function call**. Needless to say this isn't 100% secure either. – DevSolar Jan 08 '13 at 15:38
  • 1
    @Ajith, yes there should also be a system API in C++. I know it exists in C (but I'm blanking on the library to load) so it must already exist in C++. A quick google search indicates that it is in `stdlib.h` and is called `mkstemp` though. So you cold do it like that to get a truly random filename. But yeah, I didn't mean to call system once again. – Ian Stapleton Cordasco Jan 08 '13 at 15:39
  • mkstemp() would return a file descriptor, so I think in this case it is better to use [tmpnam()](http://www.cplusplus.com/reference/cstdio/tmpnam/) as DevSolar suggested. – Ajith Jan 08 '13 at 15:43
0

what about open a file(passing file name to the editor), save and then read it from your program? I've always thought git works the same way.

allergic
  • 392
  • 2
  • 6