Link to home
Start Free TrialLog in
Avatar of snip_face
snip_face

asked on

Passing control to mplayer after calling execl

Hello everybody.

Now please be gentle with me as this is my first post :p. Basicly what I'm trying to do is make a media player program such as freevo just as a
bit of a learning experience in C with SDL for the GUI. Now I'm just at an early stage at this point but basicly what I'm doing is forking an calling execl

Now at this stage I don't have the exact code I'm using as I'm currently in windows and all my code is on my linux boot, but I what I'm doing is something along these lines :


        pid = fork();

        if (pid == 0) {
             execl("/bin/mplayer","mplayer","/* various arguments for mplayer*/",0);
        }

         else {
            wait(&status);        
         }

 Now what happens is mplayer executes fine, and by hardcoding a movie name in it starts playing the movie. However control doesn't pass over to mplayer, so the program more or less locks up as I can't quit mplayer or control it in any way what so ever. Now in Operating systems at uni we ve just done pipes and redirection of input/output using dup2, and I was thinking maybe I needed to redirect the stdin to mplayer? But I'm probably going off on some strange tangent...

Anyways, any response would be greatly apreciated, and if needed I can post the proper code if anyone has an idea of whats wrong


Thankyou in advance Snip_Face (All the good names were taken)    
Avatar of Jaime Olivares
Jaime Olivares
Flag of Peru image

have you tried to use system() function?
Avatar of jkr
Check out http://www.gmonline.demon.co.uk/cscene/CS4/CS4-06.html ("Pipes in Unix"). Basically, you would

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main (int argc, char **argv)
{
  int filedes1[2], filedes2[2];
  int pid;
 
  /* Argument checking. */

  if (argc < 4)
    {
      puts("Wrong number of arguments given");
      exit(1);
    }


  /* Make our first pipe. */

  if (pipe(filedes1) == -1)
    {
      perror ("pipe");
      exit(1);
    }

  /* Make our second pipe. */
 
  if (pipe(filedes2) == -1)
    {
      perror ("pipe");
      exit(1);
    }

  /* Fork a child */

  if ((pid = fork()) == 0)
    {
      dup2(filedes1[0], fileno(stdin)); /* Copy the reading end of the pipe. */
      dup2(filedes2[1], fileno(stdout)); /* Copy the writing end of the pipe */
     
      /* Uncomment this if you want stderr sent too.

      dup2(filedes2[1], fileno(stderr));

      */

      /* If execl() returns at all, there was an error. */
     
      if (execl(argv[1], argv[1] == -1)) /* Bye bye! */
      {
        perror("execl");
        exit(128);
      }
    }
  else if (pid == -1)
    {
      perror("fork");
      exit(1);
    }
  else
    {
      int output;
      char c;

      write(filedes1[1], argv[2], strlen(argv[2])); /* Write the string */

      if((output = open(argv[3], O_WRONLY)) == -1)
      {
        perror("open");
        exit(1);
      }

      while (read(filedes2[0], &c, 1) != 0)
        write(output, &c, 1);
   
      exit(0);
    }
}
>Now what happens is mplayer executes fine, and by hardcoding a movie name in it starts playing >the movie. However control doesn't pass over to mplayer, so the program more or less locks up
If control does not pass over to the mplayer, how is it able to play the movie? If it is playing the movie the definitely it is gettnig executed (control is getting passed to it)

>I can't quit mplayer or control it in any way what so ever.
You can control mplayer only in the ways that it will allow you to control it, by providing command line options. If you want additional control, you need to write some wrappers on top of its existing interface or add additional controls within mplayer.

I do not think that you need I/O redirection here. If you can provide further details about exact nature of your problem and what you desire to achieve, may be we can discuss this further.
Avatar of snip_face
snip_face

ASKER

Sorry I've been busy at Uni...I'll get back to this post as soon as I have time

Thanks Snip_face
Are you saying that you're executing mplayer, and it starts running fine, but it's not accepting user input or something like that ?  Like not reacting to mouseclicks ?  Can you kill mplayer from a shell prompt ?

If that's the case then it may be some X-windows issue where mplayer is not seeing or not reacting to X events or something like that.  It might conceivably also be the wait() statement, although that should only cause your parent process to hang, and not the child (mplayer) process.
I'm saying exactly that sneeuw_chan, what I'll do is execute the code, but you can't control mplayer. Hence you can't fast forward, stop ...etc, or exit. I'm not able to kill it through a terminal either.  mplayer works fine normally on my system, with the only issue of this kind being when I execute it through the program..

I have managed to find the program again...



   pid = fork();
    if ( pid < 0 )
  {
    printf("Cannot fork!!\n");
    exit(1);
  }
  if ( pid == 0 )
  {
     execl("/usr/local/bin/mplayer","mplayer","-fs","-double","-screenw","800","-screenh","600","-
     vo","cvidix",filename,"2&>/dev/null",0);
  }
  else {
      printf("Waiting for child process to finish.. ");
      while (wait(&status) != pid)
        /* empty */ ;
      printf("Done!\n");
  }
Is the parent process an X application ?
Are you executing this fork function as reaction on a mousclick or menuclick or something else GUI-ish ?
In that case, it might be that your parent process has locked the X resources somehow.  Although that should mean that all your other windows stop working as well, not just the mplayer one.
It could also be that it's an SDL issue.  What kind of library is this SDL anyway ?  Is it the 'Simple DirectMedia Layer' ?  Because that's pretty low-level, IIRC.

In any case, if it's the GUI that's frozen, but the movie is playing, then it's an X-Windows issue.  (Assuming you're running under X-Windows.)

One quick-fix guess would be to not do the 'wait' bit in the parent process, so that the parent continues executing as well.  If that works, you at least know a lot more about the problem.  (At worst, you get some zombie processes, but that's a developer's life...)
Oh and by the way, the "2&>/dev/null" argument to execl is not going to work, because that kind of redirection is done by a shell, which execl doesn't use.  You want 'system' for that.  Or just do a 'close(2)' in the child process before execl-ing.  (If you want to play nice, you can open a logfile and do a dup2(logfile, 2) )

Also, it's quite strange that you're not able to kill the mplayer process from a prompt.  Not even wth kill -9 ?
Hm, this has nothing to do with X... -vo cvidix means that the video output is to console vidix... Look at http://www.mplayerhq.hu/DOCS/HTML-single/en/MPlayer.html#vidix for better/more explanations.

-- Glenn
Then it rather depends on how mplayer does user input in console mode.   If it simply reads from stdin, that's supposed to be copied if you fork a child, isn't it ?  At least it is according to the manpage for fork().
If you want to find out about where the current file descriptors are pointing, fnd the PID of the mplayer process, and do an 'ls -l /proc/<PID>/fd/', and look at the entries for 0, 1 and 2.
Is SDL a console GUI-ish library ?  In that case, I wonder what it does with all your key inputs, could very well be that they get caught by the SDL and never make it to the mplayer process.
Basically yes to your advice there sneeuw_chan... SDL can work in both X/GUI and *fb/console. One can well wonder who gets to play with the kdb and pointer:-). I'm guessing it'd work just fine if implemented for straight X (that is: no cvidix, but rather one of the X11 -vo options).

You said:
> At worst, you get some zombie processes
Zombies are harmless references telling you "there once was a process named PID" retained so that no newly spawned process could snarf the PID and thus potentially "foul things up" for the parent. They take no real resources.

Orphans are equally harmless, and would be what the mplayer'd become... Just reparented "upward":-).

-- Glenn
ASKER CERTIFIED SOLUTION
Avatar of Gns
Gns

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial