Home | History | Annotate | Line # | Download | only in c
      1  1.1  christos /*
      2  1.1  christos #progos: linux
      3  1.1  christos #output: got: a\nthen: bc\nexit: 0\n
      4  1.1  christos */
      5  1.1  christos 
      6  1.1  christos /* This is a very limited subset of what ex1.c does; we just check that
      7  1.1  christos    thread creation (clone syscall) and pipe writes and reads work. */
      8  1.1  christos 
      9  1.1  christos #include <stddef.h>
     10  1.1  christos #include <stdio.h>
     11  1.1  christos #include <stdlib.h>
     12  1.1  christos #include <unistd.h>
     13  1.1  christos #include <sched.h>
     14  1.1  christos #include <signal.h>
     15  1.1  christos #include <sys/types.h>
     16  1.1  christos #include <sys/wait.h>
     17  1.1  christos 
     18  1.1  christos int pip[2];
     19  1.1  christos 
     20  1.1  christos int
     21  1.1  christos process (void *arg)
     22  1.1  christos {
     23  1.1  christos   char *s = arg;
     24  1.1  christos   if (write (pip[1], s+2, 1) != 1) abort ();
     25  1.1  christos   if (write (pip[1], s+1, 1) != 1) abort ();
     26  1.1  christos   if (write (pip[1], s, 1) != 1) abort ();
     27  1.1  christos   return 0;
     28  1.1  christos }
     29  1.1  christos 
     30  1.1  christos int
     31  1.1  christos main (void)
     32  1.1  christos {
     33  1.1  christos   int retcode;
     34  1.1  christos   int pid;
     35  1.1  christos   int st;
     36  1.1  christos   long stack[16384];
     37  1.1  christos   char buf[10] = {0};
     38  1.1  christos 
     39  1.1  christos   retcode = pipe (pip);
     40  1.1  christos 
     41  1.1  christos   if (retcode != 0)
     42  1.1  christos     {
     43  1.1  christos       fprintf (stderr, "Bad pipe %d\n", retcode);
     44  1.1  christos       abort ();
     45  1.1  christos     }
     46  1.1  christos 
     47  1.1  christos   pid = clone (process, (char *) stack + sizeof (stack) - 64,
     48  1.1  christos 	       (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)
     49  1.1  christos 	       | SIGCHLD, "cba");
     50  1.1  christos   if (pid <= 0)
     51  1.1  christos     {
     52  1.1  christos       fprintf (stderr, "Bad clone %d\n", pid);
     53  1.1  christos       abort ();
     54  1.1  christos     }
     55  1.1  christos 
     56  1.1  christos   if ((retcode = read (pip[0], buf, 1)) != 1)
     57  1.1  christos     {
     58  1.1  christos       fprintf (stderr, "Bad read 1: %d\n", retcode);
     59  1.1  christos       abort ();
     60  1.1  christos     }
     61  1.1  christos   printf ("got: %c\n", buf[0]);
     62  1.1  christos   retcode = read (pip[0], buf, 2);
     63  1.1  christos   if (retcode == 1)
     64  1.1  christos     {
     65  1.1  christos       retcode = read (pip[0], buf+1, 1);
     66  1.1  christos       if (retcode != 1)
     67  1.1  christos 	{
     68  1.1  christos 	  fprintf (stderr, "Bad read 1.5: %d\n", retcode);
     69  1.1  christos 	  abort ();
     70  1.1  christos 	}
     71  1.1  christos       retcode = 2;
     72  1.1  christos     }
     73  1.1  christos   if (retcode != 2)
     74  1.1  christos     {
     75  1.1  christos       fprintf (stderr, "Bad read 2: %d\n", retcode);
     76  1.1  christos       abort ();
     77  1.1  christos     }
     78  1.1  christos 
     79  1.1  christos   printf ("then: %s\n", buf);
     80  1.1  christos   retcode = wait4 (-1, &st, WNOHANG | __WCLONE, NULL);
     81  1.1  christos 
     82  1.1  christos   if (retcode != pid || !WIFEXITED (st))
     83  1.1  christos     {
     84  1.1  christos       fprintf (stderr, "Bad wait %d %x\n", retcode, st);
     85  1.1  christos       abort ();
     86  1.1  christos     }
     87  1.1  christos 
     88  1.1  christos   printf ("exit: %d\n", WEXITSTATUS (st));
     89  1.1  christos   return 0;
     90  1.1  christos }
     91