L4Re/departure

Changeset

525:9e465646b859
2023-03-19 Paul Boddie raw files shortlog changelog graph Made a separate test payload and program for file-related testing.
conf/dstest_exec_many.cfg (file) conf/dstest_exec_many.list (file) test_files/programs/Makefile (file) test_files/programs/clip.c (file) test_files/programs/dstest_exec_payload.c (file) tests/Makefile (file) tests/dstest_exec.cc (file) tests/dstest_exec_many.cc (file)
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/conf/dstest_exec_many.cfg	Sun Mar 19 01:18:23 2023 +0100
     1.3 @@ -0,0 +1,66 @@
     1.4 +-- vim:set ft=lua:
     1.5 +
     1.6 +local L4 = require("L4");
     1.7 +
     1.8 +local l = L4.default_loader;
     1.9 +
    1.10 +local pipe_server = l:new_channel();
    1.11 +
    1.12 +l:startv({
    1.13 +    caps = {
    1.14 +      pipeserver = pipe_server:svr(),
    1.15 +      jdb = L4.Env.jdb, -- to set the server name
    1.16 +    },
    1.17 +    log = { "pipes", "r" },
    1.18 +  },
    1.19 +  "rom/pipe_server", "10");
    1.20 +
    1.21 +local block_server = l:new_channel();
    1.22 +
    1.23 +l:startv({
    1.24 +    caps = {
    1.25 +      fsserver = block_server:svr(),
    1.26 +      jdb = L4.Env.jdb, -- to set the server name
    1.27 +    },
    1.28 +    log = { "blocks", "r" },
    1.29 +  },
    1.30 +  "rom/block_server", "10");
    1.31 +
    1.32 +local ext2server = l:new_channel();
    1.33 +
    1.34 +l:startv({
    1.35 +    caps = {
    1.36 +      blockserver = block_server,
    1.37 +      pipeserver = pipe_server,
    1.38 +      fsserver = ext2server:svr(),
    1.39 +      jdb = L4.Env.jdb, -- to set the server name
    1.40 +    },
    1.41 +    log = { "ext2", "y" },
    1.42 +  },
    1.43 +  "rom/ext2_server", "blockserver", "rom/e2test.fs", "20", "fsserver");
    1.44 +
    1.45 +-- Obtain user filesystems with umask 0022 (18).
    1.46 +
    1.47 +local open_for_user = 6;
    1.48 +local ext2server_paulb = L4.cast(L4.Proto.Factory, ext2server):create(open_for_user, 1000, 1000, 18);
    1.49 +
    1.50 +local process_server = l:new_channel();
    1.51 +
    1.52 +l:startv({
    1.53 +    caps = {
    1.54 +      fsserver = ext2server_paulb,
    1.55 +      prserver = process_server:svr(),
    1.56 +      jdb = L4.Env.jdb, -- to set the server name
    1.57 +    },
    1.58 +    log = { "process", "y" },
    1.59 +  },
    1.60 +  "rom/process_server", "home/paulb/exec_region_mapper");
    1.61 +
    1.62 +l:startv({
    1.63 +    caps = {
    1.64 +      fsserver = ext2server_paulb,
    1.65 +      prserver = process_server,
    1.66 +    },
    1.67 +    log = { "client", "g" },
    1.68 +  },
    1.69 +  "rom/dstest_exec_many", "20", "home/paulb/clip", "home/paulb/LICENCE.txt", "21", "1");
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/conf/dstest_exec_many.list	Sun Mar 19 01:18:23 2023 +0100
     2.3 @@ -0,0 +1,29 @@
     2.4 +entry dstest_exec_many
     2.5 +roottask moe rom/dstest_exec_many.cfg
     2.6 +module dstest_exec_many.cfg
     2.7 +module e2test.fs
     2.8 +module l4re
     2.9 +module ned
    2.10 +module dstest_exec_many
    2.11 +module ext2_server
    2.12 +module block_server
    2.13 +module pipe_server
    2.14 +module process_server
    2.15 +module lib4re-c.so
    2.16 +module lib4re-c-util.so
    2.17 +module lib4re.so
    2.18 +module lib4re-util.so
    2.19 +module libc_be_l4refile.so
    2.20 +module libc_be_l4re.so
    2.21 +module libc_be_socket_noop.so
    2.22 +module libc_support_misc.so
    2.23 +module libdl.so
    2.24 +module libipc.so
    2.25 +module libl4sys-direct.so
    2.26 +module libl4sys.so
    2.27 +module libl4util.so
    2.28 +module libld-l4.so
    2.29 +module libpthread.so
    2.30 +module libstdc++.so
    2.31 +module libsupc++.so
    2.32 +module libuc_c.so
     3.1 --- a/test_files/programs/Makefile	Sun Mar 19 00:49:19 2023 +0100
     3.2 +++ b/test_files/programs/Makefile	Sun Mar 19 01:18:23 2023 +0100
     3.3 @@ -1,10 +1,12 @@
     3.4  PKGDIR		?= ..
     3.5  L4DIR		?= $(PKGDIR)/../../..
     3.6  
     3.7 -TARGET		= dstest_exec_payload
     3.8 +TARGET		= clip dstest_exec_payload
     3.9  
    3.10  MODE            = static
    3.11  
    3.12 +SRC_C_clip			= clip.c
    3.13 +
    3.14  SRC_C_dstest_exec_payload	= dstest_exec_payload.c
    3.15  
    3.16  REQUIRES_LIBS	= libc libfsclient l4re_c-util libsystypes
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test_files/programs/clip.c	Sun Mar 19 01:18:23 2023 +0100
     4.3 @@ -0,0 +1,157 @@
     4.4 +/*
     4.5 + * Show lines from a file.
     4.6 + *
     4.7 + * Copyright (C) 2022, 2023 Paul Boddie <paul@boddie.org.uk>
     4.8 + *
     4.9 + * This program is free software; you can redistribute it and/or
    4.10 + * modify it under the terms of the GNU General Public License as
    4.11 + * published by the Free Software Foundation; either version 2 of
    4.12 + * the License, or (at your option) any later version.
    4.13 + *
    4.14 + * This program is distributed in the hope that it will be useful,
    4.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.17 + * GNU General Public License for more details.
    4.18 + *
    4.19 + * You should have received a copy of the GNU General Public License
    4.20 + * along with this program; if not, write to the Free Software
    4.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    4.22 + * Boston, MA  02110-1301, USA
    4.23 + */
    4.24 +
    4.25 +#include <l4/sys/err.h>
    4.26 +
    4.27 +#include <stdio.h>
    4.28 +#include <stdlib.h>
    4.29 +#include <string.h>
    4.30 +
    4.31 +#include <fsclient/client.h>
    4.32 +#include <systypes/env.h>
    4.33 +#include <systypes/fcntl.h>
    4.34 +
    4.35 +
    4.36 +
    4.37 +/* Read a line from the file. */
    4.38 +
    4.39 +static int readline(file_t *file, int *lineno, char **start, char **end)
    4.40 +{
    4.41 +  static char buf[256];
    4.42 +  static offset_t current = 0, limit = 0;
    4.43 +  char *newline = NULL;
    4.44 +
    4.45 +  do
    4.46 +  {
    4.47 +    /* Obtain file content. */
    4.48 +
    4.49 +    if (!limit)
    4.50 +    {
    4.51 +      limit = client_read(file, buf, 256);
    4.52 +
    4.53 +      if (!limit)
    4.54 +      {
    4.55 +        *start = NULL;
    4.56 +        *end = NULL;
    4.57 +        return 0;
    4.58 +      }
    4.59 +
    4.60 +      current = 0;
    4.61 +
    4.62 +      /* Start of line at start of buffer. */
    4.63 +
    4.64 +      if (newline != NULL)
    4.65 +      {
    4.66 +        current += 1;
    4.67 +        *start = buf;
    4.68 +        *end = (char *) memchr(buf + current, (int) '\n', limit - current);
    4.69 +
    4.70 +        if (*end == NULL)
    4.71 +          *end = buf + limit;
    4.72 +
    4.73 +        return 1;
    4.74 +      }
    4.75 +    }
    4.76 +
    4.77 +    /* Find newline. */
    4.78 +
    4.79 +    newline = (char *) memchr(buf + current, (int) '\n', limit - current);
    4.80 +
    4.81 +    if (newline != NULL)
    4.82 +    {
    4.83 +      (*lineno)++;
    4.84 +      current = newline - (char *) buf + 1;
    4.85 +
    4.86 +      /* Start of line before end of buffer. */
    4.87 +
    4.88 +      if (current < limit)
    4.89 +      {
    4.90 +        *start = newline + 1;
    4.91 +        *end = (char *) memchr(buf + current, (int) '\n', limit - current);
    4.92 +
    4.93 +        if (*end == NULL)
    4.94 +          *end = buf + limit;
    4.95 +
    4.96 +        return 1;
    4.97 +      }
    4.98 +
    4.99 +      /* Otherwise, reset the buffer to read the start of line. */
   4.100 +
   4.101 +      else
   4.102 +        limit = 0;
   4.103 +    }
   4.104 +
   4.105 +    /* No newline: read more data. */
   4.106 +
   4.107 +    else
   4.108 +      limit = 0;
   4.109 +  }
   4.110 +  while (1);
   4.111 +}
   4.112 +
   4.113 +
   4.114 +
   4.115 +int main(int argc, char *argv[])
   4.116 +{
   4.117 +  file_t *file;
   4.118 +  int i, startline, numlines;
   4.119 +  char *start, *end;
   4.120 +
   4.121 +  if (argc < 4)
   4.122 +    return 1;
   4.123 +
   4.124 +  file = client_open(argv[1], O_RDONLY);
   4.125 +
   4.126 +  if (!client_opened(file))
   4.127 +  {
   4.128 +    if (file != NULL)
   4.129 +      printf("Error: %s\n", l4sys_errtostr(file->error));
   4.130 +    else
   4.131 +      printf("Could not open file.\n");
   4.132 +
   4.133 +    while (1);
   4.134 +  }
   4.135 +
   4.136 +  startline = atoi(argv[2]);
   4.137 +  numlines = atoi(argv[3]);
   4.138 +
   4.139 +  i = 1;
   4.140 +  while (i < startline)
   4.141 +    if (!readline(file, &i, &start, &end))
   4.142 +      break;
   4.143 +
   4.144 +  while (i < startline + numlines)
   4.145 +  {
   4.146 +    fwrite(start, sizeof(char), end - start, stdout);
   4.147 +    if (!readline(file, &i, &start, &end))
   4.148 +      break;
   4.149 +  }
   4.150 +
   4.151 +  fputs("\n\n", stdout);
   4.152 +
   4.153 +  client_close(file);
   4.154 +  client_notifier_close(client_notifier_task());
   4.155 +
   4.156 +  return 0;
   4.157 +}
   4.158 +
   4.159 +/* vim: tabstop=2 expandtab shiftwidth=2
   4.160 +*/
     5.1 --- a/test_files/programs/dstest_exec_payload.c	Sun Mar 19 00:49:19 2023 +0100
     5.2 +++ b/test_files/programs/dstest_exec_payload.c	Sun Mar 19 01:18:23 2023 +0100
     5.3 @@ -19,151 +19,17 @@
     5.4   * Boston, MA  02110-1301, USA
     5.5   */
     5.6  
     5.7 -#include <l4/re/env.h>
     5.8 -#include <l4/sys/err.h>
     5.9 -
    5.10  #include <stdio.h>
    5.11 -#include <stdlib.h>
    5.12 -#include <string.h>
    5.13 -
    5.14 -#include <fsclient/client.h>
    5.15 -#include <systypes/env.h>
    5.16 -#include <systypes/fcntl.h>
    5.17 -
    5.18 -
    5.19 -
    5.20 -/* Read a line from the file. */
    5.21 -
    5.22 -static int readline(file_t *file, int *lineno, char **start, char **end)
    5.23 -{
    5.24 -  static char buf[256];
    5.25 -  static offset_t current = 0, limit = 0;
    5.26 -  char *newline = NULL;
    5.27 -
    5.28 -  do
    5.29 -  {
    5.30 -    /* Obtain file content. */
    5.31 -
    5.32 -    if (!limit)
    5.33 -    {
    5.34 -      limit = client_read(file, buf, 256);
    5.35 -
    5.36 -      if (!limit)
    5.37 -      {
    5.38 -        *start = NULL;
    5.39 -        *end = NULL;
    5.40 -        return 0;
    5.41 -      }
    5.42 -
    5.43 -      current = 0;
    5.44 -
    5.45 -      /* Start of line at start of buffer. */
    5.46 -
    5.47 -      if (newline != NULL)
    5.48 -      {
    5.49 -        current += 1;
    5.50 -        *start = buf;
    5.51 -        *end = (char *) memchr(buf + current, (int) '\n', limit - current);
    5.52 -
    5.53 -        if (*end == NULL)
    5.54 -          *end = buf + limit;
    5.55 -
    5.56 -        return 1;
    5.57 -      }
    5.58 -    }
    5.59 -
    5.60 -    /* Find newline. */
    5.61 -
    5.62 -    newline = (char *) memchr(buf + current, (int) '\n', limit - current);
    5.63 -
    5.64 -    if (newline != NULL)
    5.65 -    {
    5.66 -      (*lineno)++;
    5.67 -      current = newline - (char *) buf + 1;
    5.68 -
    5.69 -      /* Start of line before end of buffer. */
    5.70 -
    5.71 -      if (current < limit)
    5.72 -      {
    5.73 -        *start = newline + 1;
    5.74 -        *end = (char *) memchr(buf + current, (int) '\n', limit - current);
    5.75 -
    5.76 -        if (*end == NULL)
    5.77 -          *end = buf + limit;
    5.78 -
    5.79 -        return 1;
    5.80 -      }
    5.81 -
    5.82 -      /* Otherwise, reset the buffer to read the start of line. */
    5.83 -
    5.84 -      else
    5.85 -        limit = 0;
    5.86 -    }
    5.87 -
    5.88 -    /* No newline: read more data. */
    5.89 -
    5.90 -    else
    5.91 -      limit = 0;
    5.92 -  }
    5.93 -  while (1);
    5.94 -}
    5.95  
    5.96  
    5.97  
    5.98  int main(int argc, char *argv[])
    5.99  {
   5.100 -  file_t *file;
   5.101 -  int i, lineno;
   5.102 -  char *start, *end;
   5.103 -
   5.104 -  printf("Hello from %s (%d)!\n", argc > 0 ? argv[0] : "exec_payload.c", argc);
   5.105 +  int i;
   5.106  
   5.107    for (i = 0; i < argc; i++)
   5.108      printf("Arg #%d: %s\n", i, argv[i]);
   5.109  
   5.110 -  if (argc < 2)
   5.111 -    return 1;
   5.112 -
   5.113 -  printf("Filesystem is %lx\n", l4re_env_get_cap(ENV_FILESYSTEM_SERVER_NAME));
   5.114 -  printf("Opening file %s...\n", argv[1]);
   5.115 -
   5.116 -  file = client_open(argv[1], O_RDONLY);
   5.117 -
   5.118 -  if (!client_opened(file))
   5.119 -  {
   5.120 -    if (file != NULL)
   5.121 -      printf("Error: %s\n", l4sys_errtostr(file->error));
   5.122 -    else
   5.123 -      printf("Could not open file.\n");
   5.124 -
   5.125 -    while (1);
   5.126 -  }
   5.127 -
   5.128 -  lineno = atoi(argv[2]);
   5.129 -
   5.130 -  printf("Finding line %d...\n", lineno);
   5.131 -
   5.132 -  i = 1;
   5.133 -  while (i < lineno)
   5.134 -    if (!readline(file, &i, &start, &end))
   5.135 -      break;
   5.136 -
   5.137 -  printf("Showing line %d...\n", lineno);
   5.138 -
   5.139 -  while (i == lineno)
   5.140 -  {
   5.141 -    fwrite(start, sizeof(char), end - start, stdout);
   5.142 -    if (!readline(file, &i, &start, &end))
   5.143 -      break;
   5.144 -  }
   5.145 -
   5.146 -  fputs("\n\n", stdout);
   5.147 -
   5.148 -  printf("Closing file...\n");
   5.149 -
   5.150 -  client_close(file);
   5.151 -  client_notifier_close(client_notifier_task());
   5.152 -
   5.153    printf("Terminating.\n");
   5.154    return 0;
   5.155  }
     6.1 --- a/tests/Makefile	Sun Mar 19 00:49:19 2023 +0100
     6.2 +++ b/tests/Makefile	Sun Mar 19 01:18:23 2023 +0100
     6.3 @@ -17,6 +17,7 @@
     6.4  		dstest_test_client \
     6.5  		dstest_map_test \
     6.6  		dstest_exec \
     6.7 +		dstest_exec_many \
     6.8  		dstest_file_mapping
     6.9  
    6.10  MODE            = static
    6.11 @@ -67,8 +68,9 @@
    6.12  
    6.13  SRC_CC_dstest_test_client		= dstest_test_client.cc
    6.14  
    6.15 -PLAIN_SRC_CC_dstest_exec		= dstest_exec.cc
    6.16 -SRC_CC_dstest_exec			= $(PLAIN_SRC_CC_dstest_exec) $(CLIENT_INTERFACES_SRC_CC_dstest_exec)
    6.17 +SRC_CC_dstest_exec			= dstest_exec.cc
    6.18 +
    6.19 +SRC_CC_dstest_exec_many			= dstest_exec_many.cc
    6.20  
    6.21  PLAIN_SRC_CC_dstest_file_mapping	= dstest_file_mapping.cc
    6.22  SRC_CC_dstest_file_mapping		= $(PLAIN_SRC_CC_dstest_file_mapping) $(CLIENT_INTERFACES_SRC_CC_dstest_file_mapping)
     7.1 --- a/tests/dstest_exec.cc	Sun Mar 19 00:49:19 2023 +0100
     7.2 +++ b/tests/dstest_exec.cc	Sun Mar 19 01:18:23 2023 +0100
     7.3 @@ -1,5 +1,5 @@
     7.4  /*
     7.5 - * Support for executing code in new tasks and threads.
     7.6 + * A test of executing code in new tasks and threads.
     7.7   *
     7.8   * Copyright (C) 2022, 2023 Paul Boddie <paul@boddie.org.uk>
     7.9   *
    7.10 @@ -19,9 +19,7 @@
    7.11   * Boston, MA  02110-1301, USA
    7.12   */
    7.13  
    7.14 -#include <l4/re/env.h>
    7.15  #include <l4/sys/err.h>
    7.16 -#include <l4/util/util.h>
    7.17  
    7.18  #include <fsclient/process.h>
    7.19  #include <systypes/format.h>
    7.20 @@ -42,11 +40,15 @@
    7.21  
    7.22    /* Create a new process structure. */
    7.23  
    7.24 -  process_t *process = process_new();
    7.25 +  process_t process;
    7.26 +
    7.27 +  process_init(&process);
    7.28 +
    7.29 +  printf("Start process...\n");
    7.30  
    7.31    /* Start a process for the given program. */
    7.32  
    7.33 -  err = process_start(process, argc - 1, argv + 1);
    7.34 +  err = process_start(&process, argc - 1, argv + 1);
    7.35  
    7.36    if (err)
    7.37    {
    7.38 @@ -62,7 +64,7 @@
    7.39  
    7.40    /* Subscribe to the process for notifications. */
    7.41  
    7.42 -  err = process_notify_subscribe(process, NOTIFY_TASK_SIGNAL, notifier);
    7.43 +  err = process_notify_subscribe(&process, NOTIFY_TASK_SIGNAL, notifier);
    7.44  
    7.45    if (err)
    7.46    {
    7.47 @@ -72,7 +74,7 @@
    7.48  
    7.49    /* Wait for a signal from the process. */
    7.50  
    7.51 -  err = process_notify_wait_process(process, notifier);
    7.52 +  err = process_notify_wait_process(&process, notifier);
    7.53  
    7.54    if (err)
    7.55    {
    7.56 @@ -80,11 +82,12 @@
    7.57      return 1;
    7.58    }
    7.59  
    7.60 -  notify_flags_t flags = process_notifications(process);
    7.61 -  notify_values_t values = process_notification_values(process);
    7.62 +  notify_flags_t flags = process_notifications(&process);
    7.63 +  notify_values_t values = process_notification_values(&process);
    7.64  
    7.65 -  printf("Notified with flags: %" pFMTnotify_flags "x\n", flags);
    7.66 -  printf("Notified with values: %ld, %ld\n", values.sig, values.val);
    7.67 +  process_close(&process);
    7.68 +
    7.69 +  printf("End process (flags %" pFMTnotify_flags "x values: %ld, %ld)\n", flags, values.sig, values.val);
    7.70  
    7.71    printf("End of test.\n");
    7.72    return 0;
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/tests/dstest_exec_many.cc	Sun Mar 19 01:18:23 2023 +0100
     8.3 @@ -0,0 +1,103 @@
     8.4 +/*
     8.5 + * A test of executing code in new tasks and threads.
     8.6 + *
     8.7 + * Copyright (C) 2022, 2023 Paul Boddie <paul@boddie.org.uk>
     8.8 + *
     8.9 + * This program is free software; you can redistribute it and/or
    8.10 + * modify it under the terms of the GNU General Public License as
    8.11 + * published by the Free Software Foundation; either version 2 of
    8.12 + * the License, or (at your option) any later version.
    8.13 + *
    8.14 + * This program is distributed in the hope that it will be useful,
    8.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.17 + * GNU General Public License for more details.
    8.18 + *
    8.19 + * You should have received a copy of the GNU General Public License
    8.20 + * along with this program; if not, write to the Free Software
    8.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    8.22 + * Boston, MA  02110-1301, USA
    8.23 + */
    8.24 +
    8.25 +#include <l4/sys/err.h>
    8.26 +
    8.27 +#include <fsclient/process.h>
    8.28 +#include <systypes/format.h>
    8.29 +
    8.30 +#include <stdio.h>
    8.31 +#include <stdlib.h>
    8.32 +
    8.33 +
    8.34 +
    8.35 +int main(int argc, char *argv[])
    8.36 +{
    8.37 +  long err;
    8.38 +
    8.39 +  if (argc < 3)
    8.40 +  {
    8.41 +    printf("Need a number and the program to run.\n");
    8.42 +    return 1;
    8.43 +  }
    8.44 +
    8.45 +  int num_processes = atoi(argv[1]);
    8.46 +
    8.47 +  /* Create a new process structure. */
    8.48 +
    8.49 +  process_t process;
    8.50 +
    8.51 +  process_init(&process);
    8.52 +
    8.53 +  for (int i = 1; i <= num_processes; i++)
    8.54 +  {
    8.55 +    printf("[%d/%d] Start process...\n", i, num_processes);
    8.56 +
    8.57 +    /* Start a process for the given program. */
    8.58 +
    8.59 +    err = process_start(&process, argc - 2, argv + 2);
    8.60 +
    8.61 +    if (err)
    8.62 +    {
    8.63 +      printf("Could not start process: %s\n", l4sys_errtostr(err));
    8.64 +      return 1;
    8.65 +    }
    8.66 +
    8.67 +    printf("Finished program initiation.\n");
    8.68 +
    8.69 +    /* Obtain the common notifier. */
    8.70 +
    8.71 +    process_notifier_t *notifier = process_notify_task();
    8.72 +
    8.73 +    /* Subscribe to the process for notifications. */
    8.74 +
    8.75 +    err = process_notify_subscribe(&process, NOTIFY_TASK_SIGNAL, notifier);
    8.76 +
    8.77 +    if (err)
    8.78 +    {
    8.79 +      printf("Could not subscribe to process: %s\n", l4sys_errtostr(err));
    8.80 +      return 1;
    8.81 +    }
    8.82 +
    8.83 +    /* Wait for a signal from the process. */
    8.84 +
    8.85 +    err = process_notify_wait_process(&process, notifier);
    8.86 +
    8.87 +    if (err)
    8.88 +    {
    8.89 +      printf("Could not wait for process: %s\n", l4sys_errtostr(err));
    8.90 +      return 1;
    8.91 +    }
    8.92 +
    8.93 +    notify_flags_t flags = process_notifications(&process);
    8.94 +    notify_values_t values = process_notification_values(&process);
    8.95 +
    8.96 +    process_close(&process);
    8.97 +
    8.98 +    printf("[%d/%d] End process (flags %" pFMTnotify_flags "x values: %ld, %ld)\n", i, num_processes, flags, values.sig, values.val);
    8.99 +  }
   8.100 +
   8.101 +  printf("End of test.\n");
   8.102 +  return 0;
   8.103 +}
   8.104 +
   8.105 +/* vim: tabstop=2 expandtab shiftwidth=2
   8.106 +*/