FAQ > Working with Processes


Match word(s).

If you have any questions or comments,
please visit us on the Forums.

FAQ > Linux/Unix Specific > Working with Processes

This item was added on: 2003/03/07

  • How do I pipe output from one program to another?

  • How do I run my program in the background, like my shell does if I type ./prog &?

  • How do I determine whether my program's I/O is redirected or not?

  • How do I read and modify the contents of another program's address space and how do I get process information, like /usr/bin/top?

  • How do I limit process resources?


  • How do I pipe output from one program to another?

    This can achieved using the pipe() function:

    #include <unistd.h>
    int pipe(int filedes[2]);

    
    /*
     *  This code creates a pipe and spawns a child process using fork().
     *  The child then becomes the 'more' program and waits for
     *  input on STDIN.  The parent process sends data down its
     *  end of the pipe, which is received by the child.
     *
     */
    #include <sys/types.h> 
    #include <sys/wait.h> 
    #include <unistd.h> 
    
    int   fd[2], i;
    pid_t child;
    if (pipe(fd) != 0)
    {
      /* pipe( ) error */
    }
    child = fork();
    if (child == -1)
    {
      /* fork( ) error */
    }
    else if (child == 0)
    {
      close(fd[1]);
      if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO)
      {
        /* dup2( ) error */
      }
      execl("/usr/bin/more", (char *) NULL);
    }
    else
    {
      close(fd[0]);
      for (i = 0; i < 100; ++i)
      {
        if (write(fd[1], "hello\n", 6) == -1)
        {
          /* write( ) error */
        }
      }
      close(fd[1]);
      waitpid(child, NULL, 0);
    }
    
    



    How do I run my program in the background, like my shell does if I type ./prog &?

    
    #include <unistd.h> 
    #include <sys/types.h> 
    
    pid_t child;
    child = fork();
    if (child == -1)
    {
      /* fork( ) error */
    }
    else if (child == 0)
    {
      if (setsid() == -1)
      {
        /* setsid( ) error */
      }
    }
    else
    {
      return(0);
    }
    
    /* program continues here */
    
    



    How do I determine whether my program's I/O is redirected or not?

    
    #include <unistd.h> 
    
    if (isatty(STDIN_FILENO) == 0)
    {
      /* input is pipe or file */
    }
    if (isatty(STDOUT_FILENO) == 0)
    {
      /* output is redirected/piped */
    }
    
    



    How do I read and modify the contents of another program's address space and how do I get process information, like /usr/bin/top?

    There is no portable solution. However, the ptrace() function is available on BSD, Linux, SunOS, Solaris, HP-UX (marked deprecated in the man page) - The interface differs slightly, though. To obtain virtual addresses, use nlist() on the executable file or the KVM library (-lkvm), if you have it (available on BSD and Sun systems).

    The kinfo_proc structure offers a load of other information, like amount of pages in text/data/stack segments, owner user/group ID, tty, resource usage and much more.

    Have a look at /usr/include/sys/user.h, /usr/include/sys/proc.h, /usr/include/sys/resourcevar.h. Note that this is only the surface of the KVM library. Consult your manual help pages for further information.

    
    #include <kvm.h> 
    #include <sys/types.h> 
    #include <sys/ptrace.h> 
    #include <unistd.h> 
    #include <signal.h> 
    #include <stdio.h> 
    
    pid_t             child;
    kvm_t             *kvm;
    struct kinfo_proc *kproc;
    child = fork();
    if (child == -1)
    {
      /* fork( ) error */
    }
    else if (child == 0)
    {
      execl("/some/program", (char *) NULL);
    }
    kvm = kvm_open(NULL, "/dev/mem", NULL, O_RDONLY, NULL);
    if (kvm == NULL)
    {
      /* kvm_open( ) error */
    }
    kproc = kvm_getprocs(kvm, KERN_PROC_PID, child, &rc);
    if (kproc == NULL)
    {
      /* kvm_getprocs( ) error */
    }
    if (rc)
    {
      char  *p = kproc->kp_eproc.e_vm.vm_daddr;
      int   data;
      if (ptrace(PT_ATTACH, child, 0, 0) != 0)
      {
        /* ptrace( ) error */
      }
      kill(child, SIGSTOP);
      wait(NULL);
      errno = 0;
      data = ptrace(PT_READ_D, child, p, 0);
      if (data == -1 && errno != 0)
      {
        /* ptrace( ) error */
      }
      printf("Data segment start: %p\n", p);
      printf("First %d bytes: %x\n", sizeof(data), data);
    }
    
    



    How do I limit process resources?

    Use setrlimit( ), which allows to control data, rss, CPU usage, maximum stack size and more.

    int setrlimit (int resource, const struct rlimit *rlim);

    
    #include <sys/types.h> 
    #include <sys/time.h> 
    #include <sys/resource.h> 
    
    struct rlimit r = { 0, 0 };
    if (setrlimit(RLIMIT_NPROC, &r) != 0)
    {
      /* setrlimit( ) error */
    }
    if (fork() == -1)
    {
      perror("fork");
    }
    
    


    Credit: vVv

    Script provided by SmartCGIs