Home | History | Annotate | Line # | Download | only in gen
posix_spawn_fileactions.c revision 1.1.2.1.6.1
      1          1.1    martin /*-
      2          1.1    martin  * Copyright (c) 2008 Ed Schouten <ed (at) FreeBSD.org>
      3          1.1    martin  * All rights reserved.
      4          1.1    martin  *
      5          1.1    martin  * Redistribution and use in source and binary forms, with or without
      6          1.1    martin  * modification, are permitted provided that the following conditions
      7          1.1    martin  * are met:
      8          1.1    martin  * 1. Redistributions of source code must retain the above copyright
      9          1.1    martin  *    notice, this list of conditions and the following disclaimer.
     10          1.1    martin  * 2. Redistributions in binary form must reproduce the above copyright
     11          1.1    martin  *    notice, this list of conditions and the following disclaimer in the
     12          1.1    martin  *    documentation and/or other materials provided with the distribution.
     13          1.1    martin  *
     14          1.1    martin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     15          1.1    martin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16          1.1    martin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     17          1.1    martin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     18          1.1    martin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     19          1.1    martin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     20          1.1    martin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     21          1.1    martin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     22          1.1    martin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     23          1.1    martin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     24          1.1    martin  * SUCH DAMAGE.
     25          1.1    martin  */
     26          1.1    martin 
     27          1.1    martin #include <sys/cdefs.h>
     28  1.1.2.1.6.1  sborrill __RCSID("$NetBSD: posix_spawn_fileactions.c,v 1.1.2.1.6.1 2014/02/03 11:57:24 sborrill Exp $");
     29          1.1    martin 
     30          1.1    martin #include "namespace.h"
     31          1.1    martin 
     32          1.1    martin #include <errno.h>
     33          1.1    martin #include <fcntl.h>
     34          1.1    martin #include <sched.h>
     35          1.1    martin #include <signal.h>
     36          1.1    martin #include <stdlib.h>
     37          1.1    martin #include <string.h>
     38          1.1    martin #include <unistd.h>
     39          1.1    martin #include <spawn.h>
     40          1.1    martin 
     41          1.1    martin #define MIN_SIZE	16
     42          1.1    martin 
     43          1.1    martin /*
     44          1.1    martin  * File descriptor actions
     45          1.1    martin  */
     46          1.1    martin 
     47          1.1    martin int
     48          1.1    martin posix_spawn_file_actions_init(posix_spawn_file_actions_t *fa)
     49          1.1    martin {
     50          1.1    martin 	if (fa == NULL)
     51  1.1.2.1.6.1  sborrill 		return (EINVAL);
     52          1.1    martin 
     53          1.1    martin 	fa->fae = malloc(MIN_SIZE * sizeof(struct posix_spawn_file_actions_entry));
     54          1.1    martin 	if (fa->fae == NULL)
     55  1.1.2.1.6.1  sborrill 		return (ENOMEM);
     56          1.1    martin 	fa->size = MIN_SIZE;
     57          1.1    martin 	fa->len = 0;
     58          1.1    martin 
     59          1.1    martin 	return (0);
     60          1.1    martin }
     61          1.1    martin 
     62          1.1    martin int
     63          1.1    martin posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *fa)
     64          1.1    martin {
     65      1.1.2.1       riz 	unsigned int i;
     66          1.1    martin 
     67          1.1    martin 	if (fa == NULL)
     68  1.1.2.1.6.1  sborrill 		return (EINVAL);
     69          1.1    martin 
     70          1.1    martin 	for (i = 0; i < fa->len; i++) {
     71          1.1    martin 		if (fa->fae[i].fae_action == FAE_OPEN)
     72          1.1    martin 			free(fa->fae[i].fae_path);
     73          1.1    martin 	}
     74          1.1    martin 
     75          1.1    martin 	free(fa->fae);
     76          1.1    martin 	return (0);
     77          1.1    martin }
     78          1.1    martin 
     79          1.1    martin static int
     80  1.1.2.1.6.1  sborrill posix_spawn_file_actions_getentry(posix_spawn_file_actions_t *fa,
     81  1.1.2.1.6.1  sborrill     unsigned int *i)
     82          1.1    martin {
     83  1.1.2.1.6.1  sborrill 	posix_spawn_file_actions_entry_t *fae;
     84  1.1.2.1.6.1  sborrill 
     85          1.1    martin 	if (fa == NULL)
     86  1.1.2.1.6.1  sborrill 		return (EINVAL);
     87          1.1    martin 
     88          1.1    martin 	if (fa->len < fa->size)
     89  1.1.2.1.6.1  sborrill 		goto out;
     90          1.1    martin 
     91  1.1.2.1.6.1  sborrill 	fae = realloc(fa->fae, (fa->size + MIN_SIZE) * sizeof(*fa->fae));
     92  1.1.2.1.6.1  sborrill 	if (fae == NULL)
     93  1.1.2.1.6.1  sborrill 		return (ENOMEM);
     94          1.1    martin 
     95  1.1.2.1.6.1  sborrill 	fa->fae = fae;
     96          1.1    martin 	fa->size += MIN_SIZE;
     97          1.1    martin 
     98  1.1.2.1.6.1  sborrill out:
     99  1.1.2.1.6.1  sborrill 	*i = fa->len;
    100  1.1.2.1.6.1  sborrill 	return (0);
    101          1.1    martin }
    102          1.1    martin 
    103          1.1    martin int
    104          1.1    martin posix_spawn_file_actions_addopen(posix_spawn_file_actions_t * __restrict fa,
    105          1.1    martin     int fildes, const char * __restrict path, int oflag, mode_t mode)
    106          1.1    martin {
    107  1.1.2.1.6.1  sborrill 	char *faepath;
    108  1.1.2.1.6.1  sborrill 	unsigned int i;
    109  1.1.2.1.6.1  sborrill 	int error;
    110          1.1    martin 
    111          1.1    martin 	if (fildes < 0)
    112          1.1    martin 		return (EBADF);
    113          1.1    martin 
    114  1.1.2.1.6.1  sborrill 	error = posix_spawn_file_actions_getentry(fa, &i);
    115  1.1.2.1.6.1  sborrill 	if (error)
    116  1.1.2.1.6.1  sborrill 		return (error);
    117  1.1.2.1.6.1  sborrill 
    118  1.1.2.1.6.1  sborrill 	faepath = strdup(path);
    119  1.1.2.1.6.1  sborrill 	if (faepath == NULL)
    120          1.1    martin 		return (ENOMEM);
    121          1.1    martin 
    122          1.1    martin 	fa->fae[i].fae_action = FAE_OPEN;
    123  1.1.2.1.6.1  sborrill 	fa->fae[i].fae_path = faepath;
    124          1.1    martin 	fa->fae[i].fae_fildes = fildes;
    125          1.1    martin 	fa->fae[i].fae_oflag = oflag;
    126          1.1    martin 	fa->fae[i].fae_mode = mode;
    127          1.1    martin 	fa->len++;
    128          1.1    martin 
    129          1.1    martin 	return (0);
    130          1.1    martin }
    131          1.1    martin 
    132          1.1    martin int
    133          1.1    martin posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *fa,
    134          1.1    martin     int fildes, int newfildes)
    135          1.1    martin {
    136  1.1.2.1.6.1  sborrill 	unsigned int i;
    137  1.1.2.1.6.1  sborrill 	int error;
    138          1.1    martin 
    139          1.1    martin 	if (fildes < 0 || newfildes < 0)
    140          1.1    martin 		return (EBADF);
    141          1.1    martin 
    142  1.1.2.1.6.1  sborrill 	error = posix_spawn_file_actions_getentry(fa, &i);
    143  1.1.2.1.6.1  sborrill 	if (error)
    144  1.1.2.1.6.1  sborrill 		return (error);
    145          1.1    martin 
    146          1.1    martin 	fa->fae[i].fae_action = FAE_DUP2;
    147          1.1    martin 	fa->fae[i].fae_fildes = fildes;
    148          1.1    martin 	fa->fae[i].fae_newfildes = newfildes;
    149          1.1    martin 	fa->len++;
    150          1.1    martin 
    151          1.1    martin 	return (0);
    152          1.1    martin }
    153          1.1    martin 
    154          1.1    martin int
    155          1.1    martin posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *fa,
    156          1.1    martin     int fildes)
    157          1.1    martin {
    158  1.1.2.1.6.1  sborrill 	unsigned int i;
    159  1.1.2.1.6.1  sborrill 	int error;
    160          1.1    martin 
    161          1.1    martin 	if (fildes < 0)
    162          1.1    martin 		return (EBADF);
    163          1.1    martin 
    164  1.1.2.1.6.1  sborrill 	error = posix_spawn_file_actions_getentry(fa, &i);
    165  1.1.2.1.6.1  sborrill 	if (error)
    166  1.1.2.1.6.1  sborrill 		return (error);
    167          1.1    martin 
    168          1.1    martin 	fa->fae[i].fae_action = FAE_CLOSE;
    169          1.1    martin 	fa->fae[i].fae_fildes = fildes;
    170          1.1    martin 	fa->len++;
    171          1.1    martin 
    172          1.1    martin 	return (0);
    173          1.1    martin }
    174