how exactly does pclose work in C?


 
Thread Tools Search this Thread
Top Forums Programming how exactly does pclose work in C?
# 1  
Old 03-15-2011
Question how exactly does pclose work in C?

If i have the pointer to the pipe, which is given to pclose, what exactly does pclose do with it?
# 2  
Old 03-15-2011
Quote:
Originally Posted by man pclose
The pclose() function waits for the associated process to terminate and
returns the exit status of the command as returned by wait4(2).
Quote:
Originally Posted by man wait4
The wait3() and wait4() system calls are similar to waitpid(2), but
additionally return resource usage information about the child in the
structure pointed to by rusage.
Quote:
Originally Posted by man waitpid
All of these system calls (wait, waitpid, waitid...) are used to wait for state changes in a child
of the calling process, and obtain information about the child whose
state has changed. A state change is considered to be: the child ter‐
minated; the child was stopped by a signal; or the child was resumed by
a signal. In the case of a terminated child, performing a wait allows
the system to release the resources associated with the child; if a
wait is not performed, then the terminated child remains in a "zombie"
state (see NOTES below).
# 3  
Old 03-15-2011
this is what pclose does
Code:
/*
* pclose --
*    Pclose returns -1 if stream is not associated with a `popened' command,
*    if already `pclosed', or waitpid returns an error.
*/
int
pclose(iop)
FILE *iop;
{
    register struct pid *cur, *last;
    int pstat;
    pid_t pid;

    (void)fclose(iop);

    /* Find the appropriate file pointer. */
    for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
    if (cur->fp == iop)
    break;
    if (cur == NULL)
    return (-1);

    do {
        pid = waitpid(cur->pid, &pstat, 0);
    } while (pid == -1 && errno == EINTR);

    /* Remove the entry from the linked list. */
    if (last == NULL)
    pidlist = cur->next;
    else
    last->next = cur->next;
    free(cur);
    
    return (pid == -1 ? -1 : pstat);
}

But I don't understand what its doing, its somehow using structs as linked lists...
Can someone show me what each line does?

How can a for loop be like
for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
and where is its start and ending brackets?

Last edited by omega666; 03-15-2011 at 08:02 PM..
# 4  
Old 03-15-2011
It is easy, if no brackets are present, it means it only executes one instruction (or block) just after that line. That means:

Code:
for a hundred of times
{
     cout << "foo";
     cout << "bar" << endl;
}

You will see 100 times foobar

Code:
for a hundred of times
      cout << "foo";
cout << "bar" << endl;

You'll see 100 times foo and once bar at the end.

and:

Code:
for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)

Means:

At start, we define last to be NULL and cur to be pidlist.
The for loop will continue while cur is != 0, that is, while (bool)cur is true.

At end of EACH LOOP, it defines last to be cur, and cur to be the next member of cur.

This is an usual way to loop through an structure of nodes. A node is an structure that knows who structure is next and who is last.

So the loop starts on cur, goes ->next, goes ->next, and ->next... until cur = cur->next is NULL. That is, there is no next after this.

I hope that is a bit helpful for you.
# 5  
Old 03-15-2011
That may not be what pclose on your system does. It's an internal implementation detail. This is also why I can't tell you what each line does -- it's using structure members defined somewhere else. Another implementation-specific detail.

That looks like very, very, very old code by the way, to still use the old K&R function definition syntax.

Broadly, what it does is
Code:
int
pclose(iop)
FILE *iop;
{
    register struct pid *cur, *last;
    int pstat;
    pid_t pid;
    // Close the file.
    (void)fclose(iop);
    // pidlist must be a global variable of type 'struct pid', whatever that is.
    // It must contain the PID to wait for, and the matching FILE *, since it
    // wasn't contained in the FILE pointer itself.
    /* Find the appropriate file pointer. */
    // Whenever there's no brackets, it acts like it only encloses the next
    // statement, like this:
    for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
    {
        if (cur->fp == iop)
        {
            break;
        }
    }

    if (cur == NULL)
    {
        return (-1);
    }

    // Wait for the process.  Keep trying until it either succeeds or fails.
    do {
        pid = waitpid(cur->pid, &pstat, 0);
    } while (pid == -1 && errno == EINTR);

    /* Remove the entry from the linked list. */
    if (last == NULL)
    pidlist = cur->next;
    else
    last->next = cur->next;
    free(cur);
    
    return (pid == -1 ? -1 : pstat);
}

You can make a linked list with structures by having a structure that contains a pointer to another structure of the same type.

Code:
struct node
{
        struct node *next;
        struct node *prev;
        int value;
};


int main(void)
{
    struct node a,b, *z;
    a.prev=NULL;
    a.next=&b;
    a.value=3;

    b.prev=&a;
    b.next=NULL;
    b.value=5;

    z=&a;
    while(z != NULL)
    {
        printf("node %p=%d\n", z, z->value);
        z=z->next;
    }
}

Code:
$ ./a.out
node 0x7fff3f48bce0=3
node 0x7fff3f48bcc0=5
$


Last edited by Corona688; 03-15-2011 at 08:36 PM..
# 6  
Old 03-15-2011
here its supposed to return the exit code of the command, in this case is the exit code equal to pstat? and why didnt it use WEXITSTATUS?

still i dont understand how something can be removed from the chain..
can u make an example where there is like 5 structs in the chain, then u remove the 1st or 3rd or last so i can see the easy way to remove structs from the chain

Last edited by omega666; 03-15-2011 at 09:01 PM..
# 7  
Old 03-15-2011
Quote:
Originally Posted by omega666
here its supposed to return the exit code of the command, in this case is the exit code equal to pstat?
Sorry, could you rephrase that?
Quote:
and why didnt it use WEXITSTATUS?
Because the code is very, very old.
Quote:
still i dont understand how something can be removed from the chain..
All you do is alter the pointers so nothing's pointing to the node you want to remove any more. Then you're free to delete it or free() it or whatever.
Quote:
can u make an example where there is like 5 structs in the chain, then u remove the 1st or 3rd or last so i can see the easy way to remove structs from the chain
Can you use the word "you"? Can you tell me you've actually compiled any of the code I've written for you?
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. IP Networking

Discussion at work, would a router work pluging a cable in wan1 and lan1?

hi all. and sorry for the random question, but this sparkled a raging flame-war at work and i want more points of view situation a router, with linux of some sort, dhcp client requesting for ip in wan1 (as usual with wan ports) dhcp server listening in lan1, and assigning ip (as usual... (9 Replies)
Discussion started by: broli
9 Replies

2. Shell Programming and Scripting

My script work on Linux but not work in sunos.

My script work on Linux but not work in sun os. my script. logFiles="sentLog1.log sentLog2.log" intial_time="0 0" logLocation="/usr/local/tomcat/logs/" sleepTime=600 failMessage=":: $(tput bold)Log not update$(tput rmso) = " successMessage="OK" arr=($logFiles)... (7 Replies)
Discussion started by: ooilinlove
7 Replies

3. IP Networking

NIC will not work, but it did work.

I have a client machine that was built and loaded with SCO UNIX 2.1.3, (yes it is old). The machine worked fine on the closed network that I tested on in my shop. I then had to change it to the network that it would be connected to. Below is the host file, router and subnet mask file that I usually... (0 Replies)
Discussion started by: NC user
0 Replies

4. UNIX for Advanced & Expert Users

popen and pclose solved

Hi I am trying to use popen function with wrtie option to give inputs to ftp command. #include "stdio.h" int main(int argv ,char *argc) { int size=0; char *buf; FILE *fp; fp = popen("ftp","w"); while(getline(&buf,&size,stdin) != -1) write(fp,buf);... (0 Replies)
Discussion started by: kumaran_5555
0 Replies

5. Shell Programming and Scripting

ls -d does not work

Hi falks, I need to dispaly a list of only directories . As it written in the manual ,the command to do it is 'ls -d'. When i issue 'ls -d' i'm getting: tornado.orca.ent:DB10g :/home/oracle/Create_Database > ls -d . Is anyone have any idea why id does not display directories ,or maybe... (11 Replies)
Discussion started by: nir_s
11 Replies

6. Linux

Come and work for me! (UK)

********nothing too see here!!!****** (2 Replies)
Discussion started by: TonyChapman
2 Replies

7. Linux

How does it work?

Can anyone explain how Graphic LCD (CSTN / STN) work in Unix... From Graphic file thro driver code to display....? Thanks (1 Reply)
Discussion started by: nat123
1 Replies

8. UNIX for Dummies Questions & Answers

cant get this to work

whoami | grep < $1 | echo $1 trying to write a script that finds out who the user is and then takes occurences of that username from a file that is passed as an argument and then displays it (6 Replies)
Discussion started by: iago
6 Replies

9. UNIX for Advanced & Expert Users

pclose returning -1

Hi all, In my application i am trying to select some text & then give it to print. for this i am opening a stream using popen & then later closing using pclose. Now this is working fine in my environment (solaris) but the pclose function is failing at my clients m/c. Even though print is... (3 Replies)
Discussion started by: nimishm123
3 Replies

10. UNIX for Dummies Questions & Answers

Script doesn't work, but commands inside work

Howdie everyone... I have a shell script RemoveFiles.sh Inside this file, it only has two commands as below: rm -f ../../reportToday/temp/* rm -f ../../report/* My problem is that when i execute this script, nothing happened. Files remained unremoved. I don't see any error message as it... (2 Replies)
Discussion started by: cheongww
2 Replies
Login or Register to Ask a Question