Right now, I am so stuck. I don't know what to do now.....
Ok I give you the code first. I made some variables to be global because simplify purpose. So don't say global variables are not safe. First, make it work. Then improve it. Bruce Eckel said that. After my program works, I will remove the global variables.
My implementation file is window1.cc. And the global variables are:
Code:
string song, outputsong, s1;
int songlength, outputsonglength;
char* arg_list[10];
const int file = 1;
const int directory = 2;
And the here's the function that "deal" with system call in LInux box:
Code:
int spawn( char* program, char** arg_list ) {
pid_t child_pid;
child_pid = fork();
if( child_pid != 0 )
return child_pid;
else {
execvp( program, arg_list );
}
}
Code:
void do_ogg() {
if( fork() == 0 ) {
int child;
arg_list[0] = "oggdec";
song.copy( arg_list[1], songlength, 0 );
arg_list[1][songlength] = '\0';
arg_list[2] = NULL;
spawn( "oggdec", arg_list );
wait(&child);
arg_list[0] = "lame";
outputsong += ".wav";
outputsong.copy( arg_list[1], outputsonglength+4, 0 );
arg_list[1][outputsonglength+4] = '\0';
outputsong = outputsong.substr( 0, outputsonglength );
arg_list[2] = NULL;
spawn( "lame", arg_list );
wait(&child);
arg_list[0] = "rm";
spawn( "rm", arg_list );
wait(&child);
delete arg_list[2];
arg_list[2] = new char[100];
arg_list[0] = "mv";
string temp = outputsong + ".wav" + ".mp3";
temp.copy( arg_list[1], outputsonglength+8, 0 );
arg_list[1][outputsonglength+8] = '\0';
outputsong += ".mp3";
outputsong.copy( arg_list[2], outputsonglength+4, 0 );
arg_list[2][outputsonglength+4] = '\0';
arg_list[3] = NULL;
spawn( "mv", arg_list );
wait(&child);
_exit( 0 );
}
}
void do_mp3() {
if( fork() == 0 ) {
int child;
arg_list[0] = "mpg321";
song.copy( arg_list[1], songlength, 0 );
arg_list[1][songlength] = '\0';
arg_list[2] = "-w";
outputsong.copy( arg_list[3], outputsonglength, 0 );
arg_list[3][outputsonglength] = '\0';
arg_list[4] = NULL;
spawn("mpg321", arg_list);
wait(&child);
arg_list[0] = "oggenc";
outputsong.copy( arg_list[1], outputsonglength, 0 );
arg_list[1][outputsonglength] = '\0';
arg_list[2] = NULL;
spawn("oggenc", arg_list);
wait(&child);
arg_list[0] = "rm";
outputsong.copy( arg_list[1], outputsonglength, 0 );
spawn("rm", arg_list);
wait(&child);
_exit( 0 );
}
}
Code:
void window1::on_processing() {
const int mp3 = 1, ogg = 2, no = 0;
for(int ii=0; ii<10; ii++)
arg_list[ii] = new char[100];
int type;
songlength = song.length();
string temp( song, 0, songlength-4 );
outputsong = temp;
outputsonglength = outputsong.length();
s1 = song.substr(outputsonglength+1,3) ;
if(s1=="mp3") type = mp3;
else if(s1=="ogg") type = ogg;
else type = no;
switch(type) {
case mp3: do_mp3();
break;
case ogg: do_ogg();
break;
default:
break;
}
for(int i=0; i<10; i++)
delete arg_list[i] ;
}
Now here's come the fun part:
Code:
void window1::on_convert_clicked()
{
if(status==1) {
song = input->get_text();
on_processing();
}
else if(status==2) {
Gtk::Dialog *dialog;
dialog = new class Gtk::Dialog("bla bla", *this ) ;
dialog->add_button("ogg",1);
dialog->add_button("mp3",2);
int bla = 1;
bla = dialog->run();
DIR *d;
struct dirent *dir;
delete dialog;
Glib::ustring Direct = input->get_text();
d = opendir(Direct.c_str());
vector<string> files;
string temp;
switch(bla) {
case 1:
if(d) {
while((dir = readdir(d))) {
temp = dir->d_name;
if(temp.length()>=4)
if(temp.substr(temp.length()-4,4)==".ogg")
files.push_back(temp);
}
}
break;
case 2:
if(d) {
while((dir = readdir(d))) {
temp = dir->d_name;
if(temp.length()>=4)
if(temp.substr(temp.length()-4,4)==".mp3")
files.push_back(temp);
}
}
break;
default:
break;
}
int child;
//Look over here, guyZ!!! Here's the part that make trouble
if(fork()==0)
for( int i=0; i<files.size(); i++ ) {
song = Direct + "/" + files[i] ;
on_processing();
wait(&child);
}
//The end of comment
}
}
Ok, I give you explanation. If user want to convert directory, after push the convert button, the dialog pop and ask: "Hey, dude, what do you want to do? Ogg to mp3 or mp3 to ogg?" There are two button: ogg and mp3 as you can see in on_convert_clicked function. But in testing sessing, I got this error after push the convert button:
The program 'converter' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadWindow (invalid Window parameter)'.
(Details: serial 4528 error_code 3 request_code 10 minor_code 0)
(Note to programmers: normally, X errors are reported asynchronously;
that is, you will receive the error a while after causing it.
To debug your program, run it with the --sync command line
option to change this behavior. You can then get a meaningful
backtrace from your debugger if you break on the gdk_x_error() function.)
I have debug it and it crash misteriously after fork() session in on_convert_clicked() function. After fork() session, it step, step, step, step, then crash. If I post my gdb sessions, it would make my post longer than needed. Again, I got no clue in my gdb session. Maybe this is not correct forum to ask like gtkmm library spesific question but a guy in gtkmm mailing list told me that:
I've not looked at your code in any great depth, but I suspect thaton_processing() is trying to talk to the GUI. If this is the case, thenwhen you fork() and it tries to talk to the GUI from one of the childprocesses, you're asking for trouble, as you end up with X windowsshared across processes which X doesn't think they should be accessedfrom, and it starts complaining about it. Try doing everything in asingle process; if it works, then you need to consider more carefullyhow you're going to do things in the background, if you're going to doit - if you do fork(), make sure only the parent talks directly to theGUI. If you need to pass data from the children for the GUI to display,it will have to pass through the parent process in some way - pipes,FIFOs, shared memory, whatever.Hopefully that will help and I'm not barking up entirely the wrong tree.
As you can see, guyz, none my child processes talk to GUI....... I reply his email and he said he cann't help further. So I come back into this forum because this error relate with child processes. I found this clue because if in on_convert_clicked() function, I comment these statements:
Code:
.......................
default:
break;
}
int child;
/*
if(fork()==0)
for( int i=0; i<files.size(); i++ ) {
song = Direct + "/" + files[i] ;
on_processing();
wait(&child);
}
*/
}
..........................
The error dissapear. But if I comment some statements in on_processing() function:
Code:
..................
else type = no;
switch(type) {
case mp3: // do_mp3();
break;
case ogg: // do_ogg();
break;
default:
break;
}
for(int i=0; i<10; i++)
............
and I use the original on_convert_clicked() function, the error still exist. So the problem is located in this function:
Code:
....................
int child;
if(fork()==0)
for( int i=0; i<files.size(); i++ ) {
song = Direct + "/" + files[i] ;
on_processing();
wait(&child);
}
.....................
Ok, my problem relate with system call and fork() function so I guess this is the correct forum to ask. Can you help me? Is there something in my code wrong in using system call?
Note to Salem:
Thanx for the previous post. I really almost cann't believe that you reply my previous post in less than 5 minutes!!!! What a wonderful forum and Guru!!!!
Note to administrator:
I found bug. Try to use blablabla[-i] in [-code] [/-code] block and below it outside [-code] [/-code] you make this block: [-i] [/-i]. It will make italic from [-i] inside [-code] [/-code] block until found [/-i] outside [-code][/-code] block. You will see what I mean. To solve it manually I have to make it blablabla[-i] [-i] [/-i] statement. Use [-i] in [-code] [/-code] block suppose not to make it italic, right?!!! I mean [-i] in [-code] [/-code] block should has no effect, rigth!!!!!