解決策 1
気に入らないかもしれない非常に単純な解決策: を使用して端末でアプリケーションを実行するスクリプトを作成しますgnome-terminal -x <your_program> <your_args>
。スクリプトをダブルクリックすると、ターミナルが開きます。
解決策 2
もう少し複雑な解決策として、'--noconsole' 引数をアプリケーションに追加します。引数が存在する場合は、アプリケーションを実行するだけです。「--noconsole」が存在しない場合:
if( fork() == 0 ) {
execlp("gnome-terminal", "gnome-terminal", "-x", argv[0], "--noconsole", NULL );
} else {
exit( 0 );
}
これにより、引数gnome-terminal
を使用してアプリケーションを実行する子プロセスが作成され--noconsole
ます。理にかなっていますか?ちょっとハックですが、うまくいきます。
解決策 3
これは最もトリッキーなソリューションですが、いくつかの点でよりエレガントです。アイデアは、stdout をファイルにリダイレクトし、実行中のターミナルを作成することtail -f <file_name> --pid=<parent_pid>
です。これにより、親プロセスの出力が出力され、親プロセスが終了すると終了します。
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
// Create terminal and redirect output to it, returns 0 on success,
// -1 otherwise.
int make_terminal() {
char pidarg[256]; // the '--pid=' argument of tail
pid_t child; // the pid of the child proc
pid_t parent; // the pid of the parent proc
FILE* fp; // file to which output is redirected
int fn; // file no of fp
// Open file for redirection
fp = fopen("/tmp/asdf.log","w");
fn = fileno(fp);
// Get pid of current process and create string with argument for tail
parent = getpid();
sprintf( pidarg, "--pid=%d", parent );
// Create child process
child = fork();
if( child == 0 ) {
// CHILD PROCESS
// Replace child process with a gnome-terminal running:
// tail -f /tmp/asdf.log --pid=<parent_pid>
// This prints the lines outputed in asdf.log and exits when
// the parent process dies.
execlp( "gnome-terminal", "gnome-terminal", "-x", "tail","-f","/tmp/asdf.log", pidarg, NULL );
// if there's an error, print out the message and exit
perror("execlp()");
exit( -1 );
} else {
// PARENT PROCESS
close(1); // close stdout
int ok = dup2( fn, 1 ); // replace stdout with the file
if( ok != 1 ) {
perror("dup2()");
return -1;
}
// Make stdout flush on newline, doesn't happen by default
// since stdout is actually a file at this point.
setvbuf( stdout, NULL, _IONBF, BUFSIZ );
}
return 0;
}
int main( int argc, char *argv[]) {
// Attempt to create terminal.
if( make_terminal() != 0 ) {
fprintf( stderr, "Could not create terminal!\n" );
return -1;
}
// Stuff is now printed to terminal, let's print a message every
// second for 10 seconds.
int i = 0;
while( i < 10 ) {
printf( "iteration %d\n", ++ i );
sleep( 1 );
}
return 0;
}