(root)/
gawk-5.2.2/
extension/
fork.c
       1  /*
       2   * fork.c - Provide fork and waitpid functions for gawk.
       3   *
       4   * Revised 6/2004
       5   * Revised 5/2012 for new extension API.
       6   */
       7  
       8  /*
       9   * Copyright (C) 2001, 2004, 2011, 2012, 2013, 2018
      10   * the Free Software Foundation, Inc.
      11   *
      12   * This file is part of GAWK, the GNU implementation of the
      13   * AWK Programming Language.
      14   *
      15   * GAWK is free software; you can redistribute it and/or modify
      16   * it under the terms of the GNU General Public License as published by
      17   * the Free Software Foundation; either version 3 of the License, or
      18   * (at your option) any later version.
      19   *
      20   * GAWK is distributed in the hope that it will be useful,
      21   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      22   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      23   * GNU General Public License for more details.
      24   *
      25   * You should have received a copy of the GNU General Public License
      26   * along with this program; if not, write to the Free Software
      27   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
      28   */
      29  
      30  #ifdef HAVE_CONFIG_H
      31  #include <config.h>
      32  #endif
      33  
      34  #include <stdio.h>
      35  #include <assert.h>
      36  #include <errno.h>
      37  #include <stdlib.h>
      38  #include <string.h>
      39  #include <unistd.h>
      40  #include <sys/wait.h>
      41  
      42  #include <sys/types.h>
      43  #include <sys/stat.h>
      44  
      45  #include "gawkapi.h"
      46  
      47  #include "gettext.h"
      48  #define _(msgid)  gettext(msgid)
      49  #define N_(msgid) msgid
      50  
      51  static const gawk_api_t *api;	/* for convenience macros to work */
      52  static awk_ext_id_t ext_id;
      53  static const char *ext_version = "fork extension: version 1.0";
      54  static awk_bool_t (*init_func)(void) = NULL;
      55  
      56  int plugin_is_GPL_compatible;
      57  
      58  
      59  /* array_set --- set an array element */
      60  
      61  static void
      62  array_set_numeric(awk_array_t array, const char *sub, double num)
      63  {
      64  	awk_value_t index, value;
      65  
      66  	set_array_element(array,
      67  		make_const_string(sub, strlen(sub), & index),
      68  		make_number(num, & value));
      69  
      70  }
      71  
      72  /*  do_fork --- provide dynamically loaded fork() builtin for gawk */
      73  
      74  static awk_value_t *
      75  do_fork(int nargs, awk_value_t *result, struct awk_ext_func *unused)
      76  {
      77  	int ret = -1;
      78  
      79  	assert(result != NULL);
      80  
      81  	ret = fork();
      82  
      83  	if (ret < 0)
      84  		update_ERRNO_int(errno);
      85  	else if (ret == 0) {
      86  		/* update PROCINFO in the child, if the array exists */
      87  		awk_value_t procinfo;
      88  
      89  		if (sym_lookup("PROCINFO", AWK_ARRAY, & procinfo)) {
      90  			if (procinfo.val_type != AWK_ARRAY) {
      91  				if (do_lint)
      92  					lintwarn(ext_id, _("fork: PROCINFO is not an array!"));
      93  			} else {
      94  				array_set_numeric(procinfo.array_cookie, "pid", getpid());
      95  				array_set_numeric(procinfo.array_cookie, "ppid", getppid());
      96  			}
      97  		}
      98  	}
      99  
     100  	/* Set the return value */
     101  	return make_number(ret, result);
     102  }
     103  
     104  /*  do_waitpid --- provide dynamically loaded waitpid() builtin for gawk */
     105  
     106  static awk_value_t *
     107  do_waitpid(int nargs, awk_value_t *result, struct awk_ext_func *unused)
     108  {
     109  	awk_value_t pid;
     110  	int ret = -1;
     111  	int options = 0;
     112  
     113  	assert(result != NULL);
     114  
     115  	if (get_argument(0, AWK_NUMBER, &pid)) {
     116  		options = WNOHANG|WUNTRACED;
     117  		ret = waitpid(pid.num_value, NULL, options);
     118  		if (ret < 0)
     119  			update_ERRNO_int(errno);
     120  	}
     121  
     122  	/* Set the return value */
     123  	return make_number(ret, result);
     124  }
     125  
     126  
     127  /*  do_wait --- provide dynamically loaded wait() builtin for gawk */
     128  
     129  static awk_value_t *
     130  do_wait(int nargs, awk_value_t *result, struct awk_ext_func *unused)
     131  {
     132  	int ret;
     133  
     134  	assert(result != NULL);
     135  
     136  	ret = wait(NULL);
     137  	if (ret < 0)
     138  		update_ERRNO_int(errno);
     139  
     140  	/* Set the return value */
     141  	return make_number(ret, result);
     142  }
     143  
     144  static awk_ext_func_t func_table[] = {
     145  	{ "fork", do_fork, 0, 0, awk_false, NULL },
     146  	{ "waitpid", do_waitpid, 1, 1, awk_false, NULL },
     147  	{ "wait", do_wait, 0, 0, awk_false, NULL },
     148  };
     149  
     150  /* define the dl_load function using the boilerplate macro */
     151  
     152  dl_load_func(func_table, fork, "")