summaryrefslogtreecommitdiff
path: root/w32/subproc/misc.c
blob: 5273fa0cb8aa17c10e4c0b8c6f378997d8e79830 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/* Process handling for Windows
Copyright (C) 1996-2013 Free Software Foundation, Inc.
This file is part of GNU Make.

GNU Make is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.

GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <config.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "proc.h"


/*
 * Description:  Convert a NULL string terminated UNIX environment block to
 *              an environment block suitable for a windows32 system call
 *
 * Returns:  TRUE= success, FALSE=fail
 *
 * Notes/Dependencies:  the environment block is sorted in case-insensitive
 *      order, is double-null terminated, and is a char *, not a char **
 */
int _cdecl compare(const void *a1, const void *a2)
{
        return _stricoll(*((char**)a1),*((char**)a2));
}
bool_t
arr2envblk(char **arr, char **envblk_out, int *envsize_needed)
{
        char **tmp;
        int size_needed;
        int arrcnt;
        char *ptr;

        arrcnt = 0;
        while (arr[arrcnt]) {
                arrcnt++;
        }

        tmp = (char**) calloc(arrcnt + 1, sizeof(char *));
        if (!tmp) {
                return FALSE;
        }

        arrcnt = 0;
        size_needed = *envsize_needed = 0;
        while (arr[arrcnt]) {
                tmp[arrcnt] = arr[arrcnt];
                size_needed += strlen(arr[arrcnt]) + 1;
                arrcnt++;
        }
        size_needed++;
        *envsize_needed = size_needed;

        qsort((void *) tmp, (size_t) arrcnt, sizeof (char*), compare);

        ptr = *envblk_out = calloc(size_needed, 1);
        if (!ptr) {
                free(tmp);
                return FALSE;
        }

        arrcnt = 0;
        while (tmp[arrcnt]) {
                strcpy(ptr, tmp[arrcnt]);
                ptr += strlen(tmp[arrcnt]) + 1;
                arrcnt++;
        }

        free(tmp);
        return TRUE;
}