I'm planning to package OpenTibia Server for Debian. One of the things I want to do is add startup via /etc/init.d and daemonization of the otserv process.
Thing is, we should probably redirect output to syslog. This is usually done via the syslog() function. Currently, the code is swarmed with:
std::cout << "Stuff to printout" << std::endl;
Is there a proper, easy to add, way to redirect standard output and standard error output into syslog without replacing every single "call" to std::cout and friends?
You can pipe your stdout to syslog with the logger command:
NAME
logger - a shell command interface to the syslog(3) system log module
SYNOPSIS
logger [-isd] [-f file] [-p pri] [-t tag] [-u socket] [message ...]
DESCRIPTION
Logger makes entries in the system log. It provides a shell command
interface to the syslog(3) system log module.
If you don't supply a message on the command line it reads stdin
You can redirect any stream in C++ via the rdbuf() command. This is a bit convoluted to implement but not that hard.
You need to write a streambuf that would output to syslog on overflow(), and replace the std::cout rdbuf with your streambuf.
An example, that would output to a file (no error handling, untested code)
#include <iostream>
#include <fstream>
using namespace std;
int main (int argc, char** argv) {
streambuf * yourStreamBuffer = NULL;
ofstream outputFileStream;
outputFileStream.open ("theOutputFile.txt");
yourStreamBuffer = outputFileStream.rdbuf();
cout.rdbuf(yourStreamBuffer);
cout << "Ends up in the file, not std::cout!";
outputFileStream.close();
return 0;
}
Not sure whether a straight "C" answer suffices; but in "C" you can use underlying stdio features to plug the (FILE*) directly into syslog calls, without an intervening "logger" process. Check out
http://mischasan.wordpress.com/2011/05/25/redirecting-stderr-to-syslog/
Try wrapping the execution of the binary with a suitable script, that just reads stdout and stderr, and send any data read from them on using syslog(). That should work without any code changes in the wrapped application, and be pretty easy.
Not sure if there are existing scripts to pipe into, but writing one shouldn't be hard if not.
I just wrote some code that will do this. It's using ASL instead of syslog, and it's using kevents, so you may need to port it to different APIs for your system (syslog instead of ASL and poll/select instead of kevent)
http://cgit.freedesktop.org/xorg/app/xinit/tree/launchd/console_redirect.c
Furthermore, I basically added this to libsystem_asl on Mountain Lion. Check out the man page for asl_log_descriptor.
Example:
#include <asl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
asl_log_descriptor(NULL, NULL, ASL_LEVEL_INFO, STDOUT_FILENO, ASL_LOG_DESCRIPTOR_WRITE);
asl_log_descriptor(NULL, NULL, ASL_LEVEL_NOTICE, STDERR_FILENO, ASL_LOG_DESCRIPTOR_WRITE);
fprintf(stdout, "This is written to stdout which will be at log level info.");
fprintf(stderr, "This is written to stderr which will be at log level notice.");
return 0;
}
Related
I'm trying to write a C++ program which will start new process (some script, programm, command) like daemon and gets some info from it (stdout). I'm trying to use popen(). But subprocess finishing when main program complete. I dont know, does C++ have something easy in use like Python (subprocessing). There is my code:
#include <stdio.h>
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
FILE *in;
char buff[512];
in = popen(argv[1], "r");
fgets(buff, sizeof(buff), in);
cout << buff;
}
P.S: & in the end of executive command doesn't helps.
fgets doesn't wait for the subprocess to complete, and neither does popen.
You need to read until the end of in:
while (fgets(buff, sizeof(buff), in))
{
cout << buff;
}
Reference for popen function: http://man7.org/linux/man-pages/man3/popen.3.html
Excerpt:
"The popen() function opens a process by creating a pipe, forking, and invoking the shell."
I think that because of the fork mechanism, when your (calling) process ends, its child process (the called one) is stopped too, at least as default behaviour.
One option is to keep reading from the pipe (and keep the caller process running) until the child process ends.
Your code is also missing a pclose(in) before exiting.
See also this other post on StackOverflow.
Have a look here https://github.com/arun11299/cpp-subprocess
This library can be exactly what you're looking for.
I am spawning a process in python using subprocess and want to read output from the program using pipes. The C++ program does not seem to close the pipe though, even when explicitly telling it to close.
#include <cstdlib>
#include <ext/stdio_filebuf.h>
#include <iostream>
int main(int argc, char **argv) {
int fd = atoi(argv[1]);
__gnu_cxx::stdio_filebuf<char> buffer(fd, std::ios::out);
std::ostream stream(&buffer);
stream << "Hello World" << std::endl;
buffer.close();
return 0;
}
I invoke this small program with this python snippet:
import os
import subprocess
read, write = os.pipe()
proc = subprocess.Popen(["./dummy", str(write)])
data = os.fdopen(read, "r").read()
print data
The read() method does not return, as the fd is not closed. Opening and closing the write fd in python solves the problem. But it seems like a hack to me. Is there a way to close the fd in my C++ process?
Thanks a lot!
Spawning a child process on Linux (all POSIX OSes, really) is usually accomplished via fork and exec. After fork, both processes have the file open. The C++ process closes it, but the file remains open until the parent process closes the fd also. This is normal for code using fork, and usually is handled by a wrapper around fork. Read the man page for pipe. I guess python has no way of knowing which files are being transferred to the child, though, and therefore doesn't know what to close in the parent vs the child process.
POSIX file descriptors are local to the process. The file descriptor write from the Python tool is not valid in the C++ process.
Perhaps the easiest way would be to have the C++ process write its output to stdout (like cout <<), and Python call Popen using stdout=PIPE and read proc.stdout (or use proc.communicate() instead of using fdopen. This should work in Windows, too.
For passing the file descriptor as a command-line argument, see Ben Voigt's answer.
I have a C++ program which has the prototype of the main function as follows:
int main(int argc, char * argv[])
The code hasn't been written by me, but this is a single C file available here.
When I compile this code, and through the command line run it as:
someexe in.txt > out.txt
This gives me an output out.txt which is generated in the same directory by operating on some input from in.txt.
someexe in.txt out.txt
This gives me an output on the command line itself. (without using > operator)
However, instead of passing the command line argument and without using the output redirection > operator, I have been trying to call the main function from another function and passing the parameters myself. If I pass an array of char* {fileDirName, in.txt}, I am not sure how to go about generating an out.txt (since I think > output redirection is an operating system level function available in command line).
Any suggestions would be greatly appreciated
The program in the link is readily available as copy paste and can be tried (main function is written at the last in the above program)
Assuming the aim is to mimic the output redirection feature (> out.txt) of the shell you can do something like:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <iostream>
int main() {
int fd = open("out.txt", O_WRONLY|O_CREAT|O_TRUNC, 0660);
assert(fd >= 0);
const int ret = dup2(fd, 1);
assert(ret >= 0);
std::cout << "Hello redirected world!" << std::endl;
close(fd);
}
You can do similar for stdin also, to mimic the input redirection (< in.txt). These will be preserved across calls to exec() too.
Of course it would be simpler to modify the program to write to the place you wanted given you have the source available.
Note though that dup2(), which "swap" the stdout fd for the one we just opened is non-portable. IIRC open() (as opposed to fopen()) is UNIX specific also)
You can't call another main() from inside the source another program - main() is special.
If you want to reuse this source code as a library you need to rename main() to something else.
However if it is handling input from either a pipe or a file (eg myprog < input.txt or myprog input.txt) in the normal Unix way then that's a little trickier to handle transparently.
The best way would be to call the compiled program as a separate process from within your new program, passing the correct commandline parameters - see the exec() family of calls
i'm writing a little c++ app to wrap around the opencv haar training function (namely cvCreateTreeCascadeClassifier). The function throws a whole load of output to the console and I wish to parse this output so that I can populate various variables in my code.
The function I wish to use is not part of the actual openCV library; instead it has to be built with my code as part of the project. All of the output from the the function is via printf.
Question: Is it possible to intercept the printf statements before they end up on the console? I've managed to redirect them using freopen but this seems a little clumsy as I then need to parse the file and then delete it when the function call is finished. Also, the function is likely to be running for several hours (and possibly even weeks!) so the size of the file might be an issue if its constantly being appended too.
Requirements: I need this app to be c++ and to run on both windows and linux (but have no problem with conditional compile statements if need be). I would also like to be able to still see my cout and cerr messages on the console (just not the printf).
My googling has removed my will to live! Can anyone help with a solution via either code example or pointers to places I should be looking for an answer?
Thanks
What you can do is:
create a pipe
make the writable end of the pipe the new stdout
read from the readable part of the pipe
Reading and writing should happen in different threads or you risk that your program starves on one end of the pipe.
Here's a sample how to do the redirection in unix & windows:
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
/* gcc defined unix */
#ifdef unix
#include <unistd.h>
#endif
#ifdef WIN32
#include <io.h>
#define pipe(X) _pipe(X,4096,O_BINARY)
#define fileno _fileno
#define dup2 _dup2
#define read _read
#endif
#include <assert.h>
int main()
{
int fds[2];
int res;
char buf[256];
int so;
res=pipe(fds);
assert(res==0);
so=fileno(stdout);
// close stdout handle and make the writable part of fds the new stdout.
res=dup2(fds[1],so);
assert(res!=-1);
printf("Hi there\n");
fflush(stdout);
// reading should happen in a different thread
res=read(fds[0],buf,sizeof(buf)-1);
assert(res>=0 && res<sizeof(buf));
buf[res]=0;
fprintf(stderr,"buf=>%s\n",buf);
return 0;
}
This code should print
buf=>Hi there
(I'm using assert here, because I am too lazy to do real error checking for this example)
Encapsulate the lib into an application, and pipe the application's output to your application. Now write a script so that you don't have to run the apps together every time with a pipe.
Take a look at: http://www.unix.com/programming/136225-reading-stdout-pipe.html it seems promising, but i never tried it.
I want to run a dos command from my program for example "dir" command.
I am doing it like,
system("dir");
Is there any way to read the output of that command directly into a program variable?
We can always redirect the output to a file and then read that file, by doing
system("dir > command.out");
And then reading command.out file. But how can we do it directly rather than redirectling to a file and then reading?
You can't redirect it to a variable, but you can do a trick similar to how pipes are used in Unix for chaining commands. Call CreateProcess(), and pass it a STARTUPINFO instance with accordingly set handles and STARTF_USESTDHANDLES in STARTUPINFO::dwFlags. Then read the data coming from the spawned process through the set handles.
If your library has popen() POSIX function, that's what you need. You can read command output from pipe and parse it any way you like.
FILE *dir;
char direntry[80];
dir = popen("dir", "r");
while (!feof(dir)) {
fgets(direntry, sizeof(direntry), dir);
/* do something with direntry */
}
Found an alternate way or rather windows equivalent of popen. It is _popen(). This works just right for me and moreover it's easy to use.
char psBuffer[128];
FILE *pPipe;
if( (pPipe = _popen( "dir", "rt" )) != NULL)
{
while(fgets(psBuffer, 128, pPipe))
{
printf(psBuffer);
}
}
Find the details with full example here.
You can't. The programs run in different memory spaces, as they are different processes. Generally, in modern operating systems, processes don't share memory.
Also, it would be difficult to define a variable in C that can hold the output of a command such as "dir"; it's would need to dynamically grow to make room.
The best way is to use a pipe, that will make it possible to read the command's output from a stream, from which you can store it as you see fit.
Use popen() it does exactly what you want.
It creates a bidirectional pipe, forks the processes. In the child it then connects the pipe to standard in and standard out then execs the command specified as the first parameter to popen().
#include <stdio.h>
#include <string>
#include <iostream>
int main()
{
std::string output;
FILE* data = popen("cat PLOP","r");
for(char c = getc(data);c != EOF;c = getc(data))
{
output += c;
}
pclose(data);
std::cout << "Data(" << output << ")\n";
}