Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to interrupt popen()?

Status
Not open for further replies.

mackpei

Programmer
Jun 6, 2000
27
DE
Hello,

I have a question: how to interrupt a command execution given in popen()?

It seems that I could use kill(pid), but how can I find out the pid of the command execution in popen()?

Are they any methods for this?

Thanks!

Mack
 
I think you would need to do the whole fork() execl() pipe() bit yourself, if you want that degree of control over things.

popen() is a simple wrapper, which is great if all you want to do is the simple thing.


--
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
 
Which OS is this for?

Unix - use ps

Windows - use task manager. If you can't see it on the processes tab, View/Select columns/PID on the. If you use procexp (download from MS) it will give you the processes in a tree so you can see the hierarchy.

Any other OS, I don't know
 
Hmm, I was seeking an elegant way.

Someone told me the following solution, I think this is what I am looking for.

Anyway thanks for your responses.

Mack

> I've been working on ZipOMatic lately, but now that I'm
> close to finishing it, I don't know how to kill the zip process,
> having started it with popen().
>
> It does a lot, but as of yet, no zipping:
> >
> I need to open a process (or multiple ones), read it's output,
> kill off the process if the user presses Stop, or otherwise wait
> for it to terminate.
>
> And it needs to be thread-safe, so, IIRC, no fork()'ing.
> (there will be BLoopers around)

popen() use fork() :)

However, the issue there is to get the forked process team id, so that you can kill it or wait his end.
Here's my own popen() implementation, called my_popen() ;-) :

-----8<--------------------------------
static FILE * my_popen
(
Arguments & args,
const char * type,
long * tid
)
{
int p[2];
FILE * fp;

if (*type != 'r' && *type != 'w')
return NULL;

if (pipe(p) < 0)
return NULL;

if ((*tid = fork()) > 0) { /* then we are the parent */
if (*type == 'r') {
close(p[1]);
fp = fdopen(p[0], type);
} else {
close(p[0]);
fp = fdopen(p[1], type);
}

return fp;
} else if (*tid == 0) { /* we're the child */

/* make our thread id the process group leader */
setpgid(0, 0);

if (*type == 'r') {
fflush(stdout);
fflush(stderr);
close(1);
if (dup(p[1]) < 0)
perror("dup of write side of pipe failed");
close(2);
if (dup(p[1]) < 0)
perror("dup of write side of pipe failed");
} else {
close(0);
if (dup(p[0]) < 0)
perror("dup of read side of pipe failed");
}

close(p[0]); /* close since we dup()'ed what we needed */
close(p[1]);

execve(args[0], args, environ);

printf("my_popen(): execve(%s) failed!\n", args[0]);
} else { /* we're having major problems... */
close(p[0]);
close(p[1]);
printf("my_popen(): fork() failure!\n");
}

return NULL;
}
-----8<--------------------------------

Arguments is just a wrapping class around argv arrays... feel free to
move back to classic string arrays.

Here how I use it in one of my pet project:

-----8<--------------------------------
Arguments cmd;
FILE *output;
long cmd_process_id;
bool cancel;
char line[1024];

cmd << "/boot/home/config/bin/cdrecord";
cmd << "dev=0,2,0";
cmd << "speed=4";
cmd << -v"
cmd << "/tmp/cd.img";

output = my_popen(cmd, "r", &cmd_process_id);
if (!output)
return;

while ( ! feof(output) && ! ferror(output) ) {
if ( cancel ) {
kill(-cmd_process_id, SIGINT);
break;
};

fgets(line, sizeof(line), output);

// Do something with process output
};

pclose(output);
------8<-----------------------------
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top