* big rework of evil: put most of functions in evil.c in their own files
* add unit test for memcpy. more will come later SVN revision: 35979
This commit is contained in:
parent
892ea362f0
commit
146b4a86c6
|
@ -1,3 +1,8 @@
|
|||
2008-09-13 Vincent Torri <doursse at users dot sf dot net>
|
||||
|
||||
* big rework of evil
|
||||
* addition of a unit test for memcpy
|
||||
|
||||
2008-07-13 Vincent Torri <doursse at users dot sf dot net>
|
||||
|
||||
* src/lib/Evil.h:
|
||||
|
|
|
@ -235,26 +235,3 @@ an Autoconf bug. Until the bug is fixed you can use this workaround:
|
|||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
||||
================================================================================
|
||||
|
||||
NOTE: For compilation with mingw32ce, run configure with the option
|
||||
|
||||
--host=arm-wince-mingw32ce
|
||||
|
||||
NOTE: For compilation with cegcc, you have to do the following steps:
|
||||
|
||||
1) After having run autogen.sh, add in config.sub file:
|
||||
|
||||
cegcc)
|
||||
basic_machine=arm-unknown
|
||||
os=-cegcc
|
||||
;;
|
||||
|
||||
after the mingw32ce case
|
||||
|
||||
2) in config.sub, add -cegcc* after -pe*. You should have a line like:
|
||||
| -cygwin* | -pe* | -cegcc* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
|
||||
3) run configure with the option
|
||||
|
||||
--host=arm-wince-cegcc
|
||||
|
|
|
@ -10,7 +10,6 @@ dnl otherwise, we set the correct flags
|
|||
dnl for each platform.
|
||||
win32_libs=""
|
||||
win32_cflags=""
|
||||
lt_enable_auto_import=""
|
||||
case "$host_os" in
|
||||
mingw|mingw32)
|
||||
win32_libs="-lole32 -luuid -lws2_32"
|
||||
|
@ -18,7 +17,6 @@ case "$host_os" in
|
|||
cegcc)
|
||||
win32_cflags="-mwin32"
|
||||
win32_libs="-lws2"
|
||||
lt_enable_auto_import="-Wl,--enable-auto-import"
|
||||
;;
|
||||
mingw32ce)
|
||||
win32_libs="-lws2"
|
||||
|
@ -29,7 +27,6 @@ case "$host_os" in
|
|||
esac
|
||||
AC_SUBST(win32_cflags)
|
||||
AC_SUBST(win32_libs)
|
||||
AC_SUBST(lt_enable_auto_import)
|
||||
|
||||
dnl needed for correct definition of EAPI
|
||||
AC_DEFINE(EFL_EVIL_BUILD, 1, [Define to mention that evil is built])
|
||||
|
@ -51,6 +48,7 @@ SNAP=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $4);}'`
|
|||
version_info=`expr $VMAJ + $VMIN`":$VMIC:$VMIN"
|
||||
AC_SUBST(version_info)
|
||||
|
||||
AM_PROG_AS
|
||||
AC_LANG(C)
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CC
|
||||
|
@ -79,8 +77,6 @@ src/Makefile
|
|||
src/bin/Makefile
|
||||
src/lib/Makefile
|
||||
src/lib/dlfcn/Makefile
|
||||
src/lib/mman/Makefile
|
||||
src/lib/pwd/Makefile
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
||||
|
|
|
@ -9,19 +9,26 @@ AM_CPPFLAGS = \
|
|||
|
||||
AM_CFLAGS = @win32_cflags@
|
||||
|
||||
bin_PROGRAMS = test_dlfcn test_pipe test_evil
|
||||
bin_PROGRAMS = suite test_dlfcn test_pipe test_evil
|
||||
|
||||
suite_SOURCES = suite.c test_memcpy.c memcpy_glibc.S
|
||||
suite_LDADD = $(top_builddir)/src/lib/libevil.la
|
||||
suite_LDFLAGS = -Wl,--enable-auto-import
|
||||
suite_DEPENDENCIES = $(top_builddir)/src/lib/libevil.la
|
||||
|
||||
test_dlfcn_SOURCES = test_dlfcn.c
|
||||
test_dlfcn_LDADD = $(top_builddir)/src/lib/libevil.la $(top_builddir)/src/lib/dlfcn/libdl.la
|
||||
test_dlfcn_LDFLAGS = @lt_enable_auto_import@
|
||||
test_dlfcn_LDFLAGS = -Wl,--enable-auto-import
|
||||
test_dlfcn_DEPENDENCIES = $(top_builddir)/src/lib/libevil.la $(top_builddir)/src/lib/dlfcn/libdl.la
|
||||
|
||||
test_pipe_SOURCES = test_pipe.c
|
||||
test_pipe_LDADD = $(top_builddir)/src/lib/libevil.la
|
||||
test_pipe_LDFLAGS = @lt_enable_auto_import@
|
||||
test_pipe_LDFLAGS = -Wl,--enable-auto-import
|
||||
test_pipe_DEPENDENCIES = $(top_builddir)/src/lib/libevil.la
|
||||
|
||||
test_evil_SOURCES = test_evil.c
|
||||
test_evil_LDADD = $(top_builddir)/src/lib/libevil.la
|
||||
test_evil_LDFLAGS = @lt_enable_auto_import@
|
||||
test_evil_LDFLAGS = -Wl,--enable-auto-import
|
||||
test_evil_DEPENDENCIES = $(top_builddir)/src/lib/libevil.la
|
||||
|
||||
EXTRA_DIST = suite.h test_memcpy.h
|
|
@ -0,0 +1,231 @@
|
|||
/* Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
Contributed by MontaVista Software, Inc. (written by Nicolas Pitre)
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* Copyright (C) 2008 Vincent Torri
|
||||
modification of the name and of the entry / end declaration
|
||||
*/
|
||||
|
||||
/*
|
||||
* Data preload for architectures that support it (ARM V5TE and above)
|
||||
*/
|
||||
#if (!defined (__ARM_ARCH_2__) && !defined (__ARM_ARCH_3__) \
|
||||
&& !defined (__ARM_ARCH_3M__) && !defined (__ARM_ARCH_4__) \
|
||||
&& !defined (__ARM_ARCH_4T__) && !defined (__ARM_ARCH_5__) \
|
||||
&& !defined (__ARM_ARCH_5T__))
|
||||
#define PLD(code...) code
|
||||
#else
|
||||
#define PLD(code...)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This can be used to enable code to cacheline align the source pointer.
|
||||
* Experiments on tested architectures (StrongARM and XScale) didn't show
|
||||
* this a worthwhile thing to do. That might be different in the future.
|
||||
*/
|
||||
//#define CALGN(code...) code
|
||||
#define CALGN(code...)
|
||||
|
||||
/*
|
||||
* Endian independent macros for shifting bytes within registers.
|
||||
*/
|
||||
#ifndef __ARMEB__
|
||||
#define pull lsr
|
||||
#define push lsl
|
||||
#else
|
||||
#define pull lsl
|
||||
#define push lsr
|
||||
#endif
|
||||
|
||||
.text
|
||||
|
||||
/* Prototype: void *memcpy_glibc(void *dest, const void *src, size_t n); */
|
||||
|
||||
.align
|
||||
.global memcpy_glibc
|
||||
.func memcpy_glibc
|
||||
memcpy_glibc:
|
||||
|
||||
stmfd sp!, {r0, r4, lr}
|
||||
|
||||
subs r2, r2, #4
|
||||
blt 8f
|
||||
ands ip, r0, #3
|
||||
PLD( pld [r1, #0] )
|
||||
bne 9f
|
||||
ands ip, r1, #3
|
||||
bne 10f
|
||||
|
||||
1: subs r2, r2, #(28)
|
||||
stmfd sp!, {r5 - r8}
|
||||
blt 5f
|
||||
|
||||
CALGN( ands ip, r1, #31 )
|
||||
CALGN( rsb r3, ip, #32 )
|
||||
CALGN( sbcnes r4, r3, r2 ) @ C is always set here
|
||||
CALGN( bcs 2f )
|
||||
CALGN( adr r4, 6f )
|
||||
CALGN( subs r2, r2, r3 ) @ C gets set
|
||||
CALGN( add pc, r4, ip )
|
||||
|
||||
PLD( pld [r1, #0] )
|
||||
2: PLD( subs r2, r2, #96 )
|
||||
PLD( pld [r1, #28] )
|
||||
PLD( blt 4f )
|
||||
PLD( pld [r1, #60] )
|
||||
PLD( pld [r1, #92] )
|
||||
|
||||
3: PLD( pld [r1, #124] )
|
||||
4: ldmia r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
|
||||
subs r2, r2, #32
|
||||
stmia r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
|
||||
bge 3b
|
||||
PLD( cmn r2, #96 )
|
||||
PLD( bge 4b )
|
||||
|
||||
5: ands ip, r2, #28
|
||||
rsb ip, ip, #32
|
||||
addne pc, pc, ip @ C is always clear here
|
||||
b 7f
|
||||
6: nop
|
||||
ldr r3, [r1], #4
|
||||
ldr r4, [r1], #4
|
||||
ldr r5, [r1], #4
|
||||
ldr r6, [r1], #4
|
||||
ldr r7, [r1], #4
|
||||
ldr r8, [r1], #4
|
||||
ldr lr, [r1], #4
|
||||
|
||||
add pc, pc, ip
|
||||
nop
|
||||
nop
|
||||
str r3, [r0], #4
|
||||
str r4, [r0], #4
|
||||
str r5, [r0], #4
|
||||
str r6, [r0], #4
|
||||
str r7, [r0], #4
|
||||
str r8, [r0], #4
|
||||
str lr, [r0], #4
|
||||
|
||||
CALGN( bcs 2b )
|
||||
|
||||
7: ldmfd sp!, {r5 - r8}
|
||||
|
||||
8: movs r2, r2, lsl #31
|
||||
ldrneb r3, [r1], #1
|
||||
ldrcsb r4, [r1], #1
|
||||
ldrcsb ip, [r1]
|
||||
strneb r3, [r0], #1
|
||||
strcsb r4, [r0], #1
|
||||
strcsb ip, [r0]
|
||||
|
||||
ldmfd sp!, {r0, r4, pc}
|
||||
|
||||
9: rsb ip, ip, #4
|
||||
cmp ip, #2
|
||||
ldrgtb r3, [r1], #1
|
||||
ldrgeb r4, [r1], #1
|
||||
ldrb lr, [r1], #1
|
||||
strgtb r3, [r0], #1
|
||||
strgeb r4, [r0], #1
|
||||
subs r2, r2, ip
|
||||
strb lr, [r0], #1
|
||||
blt 8b
|
||||
ands ip, r1, #3
|
||||
beq 1b
|
||||
|
||||
10: bic r1, r1, #3
|
||||
cmp ip, #2
|
||||
ldr lr, [r1], #4
|
||||
beq 17f
|
||||
bgt 18f
|
||||
|
||||
|
||||
.macro forward_copy_shift pull push
|
||||
|
||||
subs r2, r2, #28
|
||||
blt 14f
|
||||
|
||||
CALGN( ands ip, r1, #31 )
|
||||
CALGN( rsb ip, ip, #32 )
|
||||
CALGN( sbcnes r4, ip, r2 ) @ C is always set here
|
||||
CALGN( subcc r2, r2, ip )
|
||||
CALGN( bcc 15f )
|
||||
|
||||
11: stmfd sp!, {r5 - r9}
|
||||
|
||||
PLD( pld [r1, #0] )
|
||||
PLD( subs r2, r2, #96 )
|
||||
PLD( pld [r1, #28] )
|
||||
PLD( blt 13f )
|
||||
PLD( pld [r1, #60] )
|
||||
PLD( pld [r1, #92] )
|
||||
|
||||
12: PLD( pld [r1, #124] )
|
||||
13: ldmia r1!, {r4, r5, r6, r7}
|
||||
mov r3, lr, pull #\pull
|
||||
subs r2, r2, #32
|
||||
ldmia r1!, {r8, r9, ip, lr}
|
||||
orr r3, r3, r4, push #\push
|
||||
mov r4, r4, pull #\pull
|
||||
orr r4, r4, r5, push #\push
|
||||
mov r5, r5, pull #\pull
|
||||
orr r5, r5, r6, push #\push
|
||||
mov r6, r6, pull #\pull
|
||||
orr r6, r6, r7, push #\push
|
||||
mov r7, r7, pull #\pull
|
||||
orr r7, r7, r8, push #\push
|
||||
mov r8, r8, pull #\pull
|
||||
orr r8, r8, r9, push #\push
|
||||
mov r9, r9, pull #\pull
|
||||
orr r9, r9, ip, push #\push
|
||||
mov ip, ip, pull #\pull
|
||||
orr ip, ip, lr, push #\push
|
||||
stmia r0!, {r3, r4, r5, r6, r7, r8, r9, ip}
|
||||
bge 12b
|
||||
PLD( cmn r2, #96 )
|
||||
PLD( bge 13b )
|
||||
|
||||
ldmfd sp!, {r5 - r9}
|
||||
|
||||
14: ands ip, r2, #28
|
||||
beq 16f
|
||||
|
||||
15: mov r3, lr, pull #\pull
|
||||
ldr lr, [r1], #4
|
||||
subs ip, ip, #4
|
||||
orr r3, r3, lr, push #\push
|
||||
str r3, [r0], #4
|
||||
bgt 15b
|
||||
CALGN( cmp r2, #0 )
|
||||
CALGN( bge 11b )
|
||||
|
||||
16: sub r1, r1, #(\push / 8)
|
||||
b 8b
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
forward_copy_shift pull=8 push=24
|
||||
|
||||
17: forward_copy_shift pull=16 push=16
|
||||
|
||||
18: forward_copy_shift pull=24 push=8
|
||||
|
||||
.endfunc
|
|
@ -0,0 +1,191 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include "suite.h"
|
||||
#include "test_memcpy.h"
|
||||
|
||||
|
||||
typedef void(*function)(void);
|
||||
|
||||
struct test
|
||||
{
|
||||
const char *name;
|
||||
function fct;
|
||||
};
|
||||
|
||||
struct list
|
||||
{
|
||||
void *data;
|
||||
list *next;
|
||||
};
|
||||
|
||||
struct suite
|
||||
{
|
||||
list *first;
|
||||
list *l;
|
||||
};
|
||||
|
||||
|
||||
unsigned char *buf1 = NULL;
|
||||
unsigned char *buf2 = NULL;
|
||||
size_t page_size = 0;
|
||||
|
||||
|
||||
suite *
|
||||
suite_new(void)
|
||||
{
|
||||
suite *s;
|
||||
|
||||
if (!QueryPerformanceFrequency(&freq))
|
||||
return NULL;
|
||||
|
||||
s = (suite *)malloc(sizeof(suite));
|
||||
if (!s) return NULL;
|
||||
|
||||
s->first = NULL;
|
||||
s->l = NULL;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
suite_del(suite *s)
|
||||
{
|
||||
list *l;
|
||||
list *tmp;
|
||||
|
||||
if (!s) return;
|
||||
|
||||
l = s->first;
|
||||
while (l)
|
||||
{
|
||||
tmp = l->next;
|
||||
free(l->data);
|
||||
free(l);
|
||||
l = tmp;
|
||||
}
|
||||
|
||||
free(s);
|
||||
}
|
||||
|
||||
void
|
||||
suite_time_start()
|
||||
{
|
||||
QueryPerformanceCounter(&start);
|
||||
}
|
||||
|
||||
void
|
||||
suite_time_stop()
|
||||
{
|
||||
QueryPerformanceCounter(&end);
|
||||
}
|
||||
|
||||
double
|
||||
suite_time_get()
|
||||
{
|
||||
return (double)(end.QuadPart - start.QuadPart) / (double)freq.QuadPart;
|
||||
}
|
||||
|
||||
void
|
||||
suite_test_add(suite *s, const char *name, function fct)
|
||||
{
|
||||
test *t;
|
||||
list *l;
|
||||
|
||||
t = (test *)malloc(sizeof(test));
|
||||
if (!t) return;
|
||||
|
||||
l = (list *)malloc(sizeof(list));
|
||||
if (!l)
|
||||
{
|
||||
free(t);
|
||||
return;
|
||||
}
|
||||
|
||||
t->name = name;
|
||||
t->fct = fct;
|
||||
|
||||
l->data = t;
|
||||
l->next = NULL;
|
||||
|
||||
if (!s->first) s->first = l;
|
||||
|
||||
if (!s->l)
|
||||
s->l = l;
|
||||
else
|
||||
{
|
||||
s->l->next = l;
|
||||
s->l =l;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
suite_run(suite *s)
|
||||
{
|
||||
list *l;
|
||||
|
||||
l = s->first;
|
||||
while (l)
|
||||
{
|
||||
test *t;
|
||||
|
||||
t = (test *)l->data;
|
||||
printf("%s test\n", t->name);
|
||||
t->fct();
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test tests[] = {
|
||||
{ "memcpy", test_memcpy },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
suite *s;
|
||||
int i;
|
||||
|
||||
page_size = 2 * getpagesize();
|
||||
|
||||
buf1 = (unsigned char *)malloc(4 * getpagesize());
|
||||
if (!buf1) return EXIT_FAILURE;
|
||||
|
||||
buf2 = (unsigned char *)malloc(4 * getpagesize());
|
||||
if (!buf2)
|
||||
{
|
||||
free(buf1);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
memset (buf1, 0xa5, page_size);
|
||||
memset (buf2, 0x5a, page_size);
|
||||
|
||||
s = suite_new();
|
||||
if (!s)
|
||||
{
|
||||
free(buf2);
|
||||
free(buf1);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0; ; ++i)
|
||||
{
|
||||
if (!tests[i].name)
|
||||
break;
|
||||
|
||||
suite_test_add(s, tests[i].name, tests[i].fct);
|
||||
}
|
||||
|
||||
suite_run(s);
|
||||
|
||||
suite_del(s);
|
||||
free(buf2);
|
||||
free(buf1);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef __EVIL_SUITE_H__
|
||||
#define __EVIL_SUITE_H__
|
||||
|
||||
|
||||
typedef struct test test;
|
||||
typedef struct list list;
|
||||
typedef struct suite suite;
|
||||
|
||||
LARGE_INTEGER freq;
|
||||
LARGE_INTEGER start;
|
||||
LARGE_INTEGER end;
|
||||
|
||||
void suite_time_start();
|
||||
void suite_time_stop();
|
||||
double suite_time_get();
|
||||
|
||||
|
||||
#endif /* __EVIL_SUITE_H__ */
|
|
@ -0,0 +1,113 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include "suite.h"
|
||||
#include "test_memcpy.h"
|
||||
|
||||
|
||||
typedef void *(*memcpy_decl)(void *dest, const void *src, size_t n);
|
||||
|
||||
void *memcpy_glibc(void *dest, const void *src, size_t n);
|
||||
|
||||
|
||||
extern unsigned char *buf1;
|
||||
extern unsigned char *buf2;
|
||||
extern size_t page_size;
|
||||
|
||||
|
||||
static void
|
||||
test_memcpy_test_run(memcpy_decl fct, char *dst, const char *src, size_t len)
|
||||
{
|
||||
double start;
|
||||
double end;
|
||||
double best;
|
||||
int i;
|
||||
|
||||
best = 1000000000.0;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
double time;
|
||||
|
||||
suite_time_start();
|
||||
fct(dst, src, len);
|
||||
suite_time_stop();
|
||||
time = suite_time_get();
|
||||
if (time < best) best = time;
|
||||
}
|
||||
|
||||
printf (" %e", best);
|
||||
}
|
||||
|
||||
static void
|
||||
test_memcpy_tests_run(size_t align1, size_t align2, size_t len)
|
||||
{
|
||||
size_t i, j;
|
||||
char *s1, *s2;
|
||||
|
||||
printf ("running test..\n");
|
||||
|
||||
/* align1 &= 63; */
|
||||
/* if (align1 + len >= page_size) */
|
||||
/* return; */
|
||||
|
||||
/* align2 &= 63; */
|
||||
/* if (align2 + len >= page_size) */
|
||||
/* return; */
|
||||
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0, j = 1; i < len; i++, j += 23)
|
||||
s1[i] = j;
|
||||
|
||||
printf ("length: %6d, align %2d/%2d:", (int)len, align1, align2);
|
||||
|
||||
test_memcpy_test_run(memcpy, s2, s1, len);
|
||||
test_memcpy_test_run(memcpy_glibc, s2, s1, len);
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
void
|
||||
test_memcpy(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/* for (i = 0; i < 18; ++i) */
|
||||
/* { */
|
||||
/* test_memcpy_tests_run(0, 0, 1 << i); */
|
||||
/* test_memcpy_tests_run(i, 0, 1 << i); */
|
||||
/* test_memcpy_tests_run(0, i, 1 << i); */
|
||||
/* test_memcpy_tests_run(i, i, 1 << i); */
|
||||
/* } */
|
||||
|
||||
/* for (i = 0; i < 32; ++i) */
|
||||
/* { */
|
||||
/* test_memcpy_tests_run(0, 0, i); */
|
||||
/* test_memcpy_tests_run(i, 0, i); */
|
||||
/* test_memcpy_tests_run(0, i, i); */
|
||||
/* test_memcpy_tests_run(i, i, i); */
|
||||
/* } */
|
||||
|
||||
/* for (i = 3; i < 32; ++i) */
|
||||
/* { */
|
||||
/* if ((i & (i - 1)) == 0) */
|
||||
/* continue; */
|
||||
/* test_memcpy_tests_run(0, 0, 16 * i); */
|
||||
/* test_memcpy_tests_run(i, 0, 16 * i); */
|
||||
/* test_memcpy_tests_run(0, i, 16 * i); */
|
||||
/* test_memcpy_tests_run(i, i, 16 * i); */
|
||||
/* } */
|
||||
|
||||
test_memcpy_tests_run(0, 0, getpagesize ());
|
||||
test_memcpy_tests_run(0, 0, 2 * getpagesize ());
|
||||
test_memcpy_tests_run(0, 0, 4 * getpagesize ());
|
||||
test_memcpy_tests_run(0, 0, 8 * getpagesize ());
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef __EVIL_TEST_MEMCPY__
|
||||
#define __EVIL_TEST_MEMCPY__
|
||||
|
||||
|
||||
void test_memcpy(void);
|
||||
|
||||
|
||||
#endif /* __EVIL_TEST_MEMCPY__ */
|
|
@ -74,6 +74,10 @@ extern "C" {
|
|||
|
||||
#define PATH_MAX MAX_PATH
|
||||
|
||||
#include "evil_stdlib.h"
|
||||
#include "evil_unistd.h"
|
||||
#include "evil_util.h"
|
||||
|
||||
|
||||
#ifndef __CEGCC__
|
||||
|
||||
|
@ -132,7 +136,6 @@ extern "C" {
|
|||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
typedef int pid_t;
|
||||
typedef long ssize_t;
|
||||
typedef unsigned short mode_t;
|
||||
|
||||
|
@ -180,360 +183,9 @@ struct flock
|
|||
*/
|
||||
EAPI int fcntl(int fd, int cmd, ...);
|
||||
|
||||
/**
|
||||
* @brief Make temporay unique file name.
|
||||
*
|
||||
* @param template Template of the file to create.
|
||||
* @return A file descriptor on success, -1 otherwise.
|
||||
*
|
||||
* Take the given file name @p template and overwrite a portion of it
|
||||
* to create a file name. This file is guaranted not to exist at the
|
||||
* time invocation and is suitable for use by the function.
|
||||
*
|
||||
* The @p template parameter can be any file name with some number of
|
||||
* 'Xs' appended to it, for example @em baseXXXXXX, where @em base is
|
||||
* the part of the new file that you supply and eacg 'X' is a placeholder
|
||||
* for a character supplied by mkstemp(). The trailing 'Xs' are replaced
|
||||
* with a five-digit value; this value is a unique number. Each successful
|
||||
* call to mkstemp() modifes @p template.
|
||||
*
|
||||
* When mkstemp() succeeds, it creates and opens the template file for
|
||||
* reading and writing.
|
||||
*
|
||||
* On success, the function returns the file descriptor of the
|
||||
* temporary file. Otherwise, it returns -1 and errno is set to the
|
||||
* following values:
|
||||
* - EINVAL: @p template has an invalid format.
|
||||
* - EACCESS: Given path is a directory, or file is read-only, but an
|
||||
* open-for-writing operation was attempted.
|
||||
* - EEXISTS: File name already exists.
|
||||
* - EMFILE: No more file descriptors available.
|
||||
* - ENOENT: File or path not found.
|
||||
*
|
||||
* Conformity: Should follow BSD conformity.
|
||||
*
|
||||
* Supported OS: Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI int mkstemp(char *template);
|
||||
|
||||
/**
|
||||
* @brief Return the process identifier of the calling process.
|
||||
*
|
||||
* @return The process ID.
|
||||
*
|
||||
* Return the process identifier of the calling process. Until
|
||||
* the process terminates, the process identifier uniquely
|
||||
* identifies the process throughout the system.
|
||||
*
|
||||
* Conformity: Not appliclable.
|
||||
*
|
||||
* Supported OS: Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI pid_t getpid(void);
|
||||
|
||||
/**
|
||||
* @brief Create a shell link.
|
||||
*
|
||||
* @param oldpath The file name to be linked.
|
||||
* @param newpath The file name to create.
|
||||
* @return 0 on success, -1 otherwise.
|
||||
*
|
||||
* Create a shell link @p newpath to @p oldpath (@p newpath is the
|
||||
* name of the file created, @p oldpath is the string used in
|
||||
* creating the shell link).
|
||||
*
|
||||
* On success, this function returns 0. Otherwise, it returns -1 and
|
||||
* errno may be set to the following value:
|
||||
* - ENOMEM: Not enough memory.
|
||||
*
|
||||
* On Windows, the symbolic links do not exist. Nevertheless
|
||||
* shell links can be created. This function is named like the Unix
|
||||
* function for portability reasons.
|
||||
*
|
||||
* Conformity: None.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI int symlink(const char *oldpath, const char *newpath);
|
||||
|
||||
/**
|
||||
* @brief Read value of a shell link.
|
||||
*
|
||||
* @param path The file name to be linked.
|
||||
* @param buf The file name to create.
|
||||
* @param bufsiz The size of the buffer.
|
||||
* @return 0 on success, -1 otherwise.
|
||||
*
|
||||
* Place the content of the shell link @p path in the buffer
|
||||
* @p buf, which has size @p bufzsiz.
|
||||
*
|
||||
* On success, this function returns the count of characters
|
||||
* placed in the buffer. Otherwise, it returns -1 and errno may
|
||||
* be set to the following value:
|
||||
* - ENOMEM: Not enough memory.
|
||||
*
|
||||
* On Windows, the symbolic links do not exist. Nevertheless
|
||||
* shell links can be managed. This function is named like the Unix
|
||||
* function for portability reasons.
|
||||
*
|
||||
* Conformity: None.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI ssize_t readlink(const char *path, char *buf, size_t bufsiz);
|
||||
|
||||
/**
|
||||
* @brief Create, modify, or remove environment variables.
|
||||
*
|
||||
* @param name The name of the environment variable.
|
||||
* @param value The value of the environment variable to set.
|
||||
* @return 0 on success, -1 otherwise.
|
||||
*
|
||||
* Add the new environment variable @p name or modify its value if it
|
||||
* exists, and set it to @p value. Environment variables define the
|
||||
* environment in which a process executes. If @p value is @c NULL, the
|
||||
* variable is removed (unset) and that call is equivalent to unsetenv().
|
||||
* If the function succeeds, it returns 0, otherwise it returns -1.
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI int setenv(const char *name, const char *value);
|
||||
|
||||
/**
|
||||
* @brief Remove environment variables.
|
||||
*
|
||||
* @param name The name of the environment variable.
|
||||
* @return 0 on success, -1 otherwise.
|
||||
*
|
||||
* Remove the new environment variable @p name if it exists. That
|
||||
* function is equivalent to setenv() with its second parameter to
|
||||
* @c NULL. If the function succeeds, it returns 0, otherwise it
|
||||
* returns -1.
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI int unsetenv(const char *name);
|
||||
|
||||
#endif /* ! __CEGCC__ */
|
||||
|
||||
/**
|
||||
* @brief Return an absolute or full path name for a specified relative path name.
|
||||
*
|
||||
* @param file_name The absolute path name.
|
||||
* @param resolved_name The relative path name.
|
||||
* @return @c NULL on failure, a pointer to the absolute path name otherwise.
|
||||
*
|
||||
* The function expands the relative path name @p file_name to its
|
||||
* fully qualified or absolute path and store it in the buffer pointed
|
||||
* by @p resolved_name. The buffer is at most @c PATH_MAX bytes long.
|
||||
* If @p resolved_name is @c NULL, malloc() is used to allocate a
|
||||
* buffer of sufficient length to hold the path name. In that case, it
|
||||
* is the responsability of the caller to free this buffer with free().
|
||||
*
|
||||
* That function can be used to obtain the absolute path name for
|
||||
* relative paths (relPath) that include "./" or "../" in their names.
|
||||
*
|
||||
* Conformity: None.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI char *realpath(const char *file_name, char *resolved_name);
|
||||
|
||||
/**
|
||||
* @brief Initiates the use of Windows sockets.
|
||||
*
|
||||
* @return 1 on success, 0 otherwise.
|
||||
*
|
||||
* Initiates the use of Windows sockets. If the function succeeds,
|
||||
* it returns 1, otherwise it returns 0.
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI int evil_sockets_init(void);
|
||||
|
||||
/**
|
||||
* @brief Shutdown the Windows socket system.
|
||||
*
|
||||
* Shutdown the Windows socket system.
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI void evil_sockets_shutdown(void);
|
||||
|
||||
/**
|
||||
* @brief Create a pair of sockets.
|
||||
*
|
||||
* @param fds A pointer that contains two sockets.
|
||||
*
|
||||
* Create a pair of sockets that can be use with select().
|
||||
* Hence, evil_sockets_init() must have been caled at least
|
||||
* once before. Contrary to Unix, that functions does not
|
||||
* create a pair of file descriptors.
|
||||
*
|
||||
* Conformity: Not applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI int evil_pipe(int *fds);
|
||||
|
||||
/**
|
||||
* @brief Return a dir to store temporary files.
|
||||
*
|
||||
* @return The directory to store temporary files.
|
||||
*
|
||||
* Return a directory to store temporary files. The function gets
|
||||
* the value of the following environment variables, and in that order:
|
||||
* - TMP
|
||||
* - TEMP
|
||||
* - USERPROFILE
|
||||
* - WINDIR
|
||||
* and returns its value if it exists. If none exists, the function
|
||||
* returns "C:\".
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI const char *evil_tmpdir_get(void);
|
||||
|
||||
/**
|
||||
* @brief Return a dir to store personal files.
|
||||
*
|
||||
* @return The directory to store personal files.
|
||||
*
|
||||
* Return a directory to store personal files. The function gets
|
||||
* the value of the following environment variables, and in that order:
|
||||
* - HOME
|
||||
* - USERPROFILE
|
||||
* - WINDIR
|
||||
* and returns its value if it exists. If none exists, the function
|
||||
* returns "C:\".
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI const char *evil_homedir_get(void);
|
||||
|
||||
/**
|
||||
* @brief Get the current directory.
|
||||
*
|
||||
* @param buffer Buffer to store the current directory.
|
||||
* @param size Size of the buffer.
|
||||
* @return The current directory.
|
||||
*
|
||||
* On Windows desktop, use the _getcwd function in MSVCRT.
|
||||
*
|
||||
* On Windows CE, get the current directory by extracting the path
|
||||
* from the executable that is running and put the result in @p buffer
|
||||
* of length @p size. If @p size is less or equal than 0, return NULL.
|
||||
* If the current absolute path would require a buffer longer than
|
||||
* @p size elements, NULL is returned. If @p buffer is NULL, a buffer
|
||||
* of length @p size is allocated and is returned. If the allocation
|
||||
* fails, NULL is returned. On success, @p buffer is returned and
|
||||
* contains the current directory. The last '\' is not included.
|
||||
* If @p buffer is NULL, the returned value must be freed if not NULL.
|
||||
*
|
||||
* Specially usefull on WinCE where the current directory functionality
|
||||
* is not supported.
|
||||
*
|
||||
* Conformity: Almost POSIX.1 (no errno set)
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP, WinCE.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI char *evil_getcwd(char *buffer, size_t size);
|
||||
|
||||
#ifdef UNICODE
|
||||
|
||||
/**
|
||||
* @brief Convert a string from char * to wchar_t *.
|
||||
*
|
||||
* @param text The string to convert.
|
||||
* @return The converted string.
|
||||
*
|
||||
* Convert a string from char * to wchar_t * and return it. If the
|
||||
* allocation or conversion fails, NULL is returned. On success, the
|
||||
* returned value must be freed.
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI wchar_t *evil_char_to_wchar(const char *text);
|
||||
|
||||
/**
|
||||
* @brief Convert a string from wchar_t * to char *.
|
||||
*
|
||||
* @param text The string to convert.
|
||||
* @return The converted string.
|
||||
*
|
||||
* Convert a string from wchar_t * to char * and return it. If the
|
||||
* allocation or conversion fails, NULL is returned. On success, the
|
||||
* returned value must be freed.
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI char *evil_wchar_to_char(const wchar_t *text);
|
||||
|
||||
#endif /* UNICODE */
|
||||
|
||||
EAPI char *evil_last_error_get(void);
|
||||
|
||||
typedef int nl_item;
|
||||
|
||||
#define __NL_ITEM( CATEGORY, INDEX ) ((CATEGORY << 16) | INDEX)
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
SUBDIRS = . dlfcn mman pwd
|
||||
SUBDIRS = . dlfcn
|
||||
|
||||
lib_LTLIBRARIES = libevil.la
|
||||
|
||||
include_HEADERS = Evil.h
|
||||
libevil_la_SOURCES = evil.c
|
||||
include_HEADERS = Evil.h evil_stdlib.h evil_unistd.h evil_util.h
|
||||
nobase_include_HEADERS = sys/mman.h
|
||||
|
||||
libevil_la_SOURCES = \
|
||||
evil.c \
|
||||
evil_mman.c \
|
||||
evil_pwd.c \
|
||||
evil_stdlib.c \
|
||||
evil_unistd.c \
|
||||
evil_util.c
|
||||
|
||||
libevil_la_CFLAGS = @win32_cflags@
|
||||
libevil_la_LIBADD = @win32_libs@
|
||||
libevil_la_DEPENDENCIES = $(top_builddir)/config.h
|
||||
libevil_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@
|
||||
libevil_la_LDFLAGS = -no-undefined -Wl,--enable-auto-import -version-info @version_info@
|
||||
|
|
|
@ -9,4 +9,4 @@ libdl_la_SOURCES = dlfcn.c
|
|||
libdl_la_CFLAGS = @win32_cflags@
|
||||
libdl_la_LIBADD = $(top_builddir)/src/lib/libevil.la
|
||||
libdl_la_DEPENDENCIES = $(top_builddir)/src/lib/libevil.la
|
||||
libdl_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@
|
||||
libdl_la_LDFLAGS = -no-undefined -Wl,--enable-auto-import -version-info @version_info@
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#endif /* HAVE___ATTRIBUTE__ */
|
||||
|
||||
#include "Evil.h"
|
||||
#include "pwd/pwd.h"
|
||||
|
||||
|
||||
static struct passwd pw;
|
||||
|
@ -104,529 +103,8 @@ int fcntl(int fd, int cmd, ...)
|
|||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
mkstemp(char *template)
|
||||
{
|
||||
int fd;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
if (!_mktemp(template))
|
||||
return -1;
|
||||
|
||||
fd = _sopen(template, _O_RDWR | _O_BINARY | _O_CREAT | _O_EXCL, _SH_DENYNO, _S_IREAD | _S_IWRITE);
|
||||
#else
|
||||
if (_mktemp_s(template, _MAX_PATH) != 0)
|
||||
return -1;
|
||||
|
||||
_sopen_s(&fd, template, _O_RDWR | _O_BINARY | _O_CREAT, _SH_DENYNO, _S_IREAD | _S_IWRITE);
|
||||
#endif /* ! __MINGW32__ */
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
pid_t
|
||||
getpid(void)
|
||||
{
|
||||
return (pid_t)GetCurrentProcessId();
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwuid (uid_t uid)
|
||||
{
|
||||
static char user_name[PATH_MAX];
|
||||
DWORD length;
|
||||
BOOL res;
|
||||
|
||||
length = PATH_MAX;
|
||||
/* get from USERPROFILE for win 98 ? */
|
||||
res = GetUserName(user_name, &length);
|
||||
pw.pw_name = (res ? user_name : NULL);
|
||||
pw.pw_passwd = NULL;
|
||||
pw.pw_uid = uid;
|
||||
pw.pw_gid = 0;
|
||||
pw.pw_change = 0;
|
||||
pw.pw_class = NULL;
|
||||
pw.pw_gecos = (res ? user_name : NULL);
|
||||
pw.pw_dir = (char *)evil_homedir_get();
|
||||
pw.pw_shell = getenv("SHELL");
|
||||
if (pw.pw_shell == NULL)
|
||||
pw.pw_shell = "sh";
|
||||
pw.pw_expire = 0;
|
||||
pw.pw_fields = 0;
|
||||
|
||||
return &pw;
|
||||
}
|
||||
|
||||
/* REMARK: Windows has no symbolic link. */
|
||||
/* Nevertheless, it can create and read .lnk files */
|
||||
int
|
||||
symlink(const char *oldpath, const char *newpath)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
wchar_t new_path[MB_CUR_MAX];
|
||||
#endif /* UNICODE */
|
||||
IShellLink *pISL;
|
||||
IShellLink **shell_link;
|
||||
IPersistFile *pIPF;
|
||||
IPersistFile **persit_file;
|
||||
HRESULT res;
|
||||
|
||||
res = CoInitialize(NULL);
|
||||
if (FAILED(res))
|
||||
{
|
||||
if (res == E_OUTOFMEMORY)
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Hack to cleanly remove a warning */
|
||||
shell_link = &pISL;
|
||||
if (FAILED(CoCreateInstance(&CLSID_ShellLink,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
&IID_IShellLink,
|
||||
(void **)shell_link)))
|
||||
goto no_instance;
|
||||
|
||||
if (FAILED(pISL->lpVtbl->SetPath(pISL, oldpath)))
|
||||
goto no_setpath;
|
||||
|
||||
/* Hack to cleanly remove a warning */
|
||||
persit_file = &pIPF;
|
||||
if (FAILED(pISL->lpVtbl->QueryInterface(pISL, &IID_IPersistFile, (void **)persit_file)))
|
||||
goto no_queryinterface;
|
||||
|
||||
#ifdef UNICODE
|
||||
mbstowcs(new_path, newpath, MB_CUR_MAX);
|
||||
if (FAILED(pIPF->lpVtbl->Save(pIPF, new_path, FALSE)))
|
||||
goto no_save;
|
||||
#else
|
||||
if (FAILED(pIPF->lpVtbl->Save(pIPF, newpath, FALSE)))
|
||||
goto no_save;
|
||||
#endif /* ! UNICODE */
|
||||
|
||||
pIPF->lpVtbl->Release(pIPF);
|
||||
pISL->lpVtbl->Release(pISL);
|
||||
CoUninitialize();
|
||||
|
||||
return 0;
|
||||
|
||||
no_save:
|
||||
pIPF->lpVtbl->Release(pIPF);
|
||||
no_queryinterface:
|
||||
no_setpath:
|
||||
pISL->lpVtbl->Release(pISL);
|
||||
no_instance:
|
||||
CoUninitialize();
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
readlink(const char *path, char *buf, size_t bufsiz)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
wchar_t old_path[MB_CUR_MAX];
|
||||
#endif /* UNICODE */
|
||||
char new_path[PATH_MAX];
|
||||
IShellLink *pISL;
|
||||
IShellLink **shell_link;
|
||||
IPersistFile *pIPF;
|
||||
IPersistFile **persit_file;
|
||||
unsigned int length;
|
||||
HRESULT res;
|
||||
|
||||
res = CoInitialize(NULL);
|
||||
if (FAILED(res))
|
||||
{
|
||||
if (res == E_OUTOFMEMORY)
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Hack to cleanly remove a warning */
|
||||
persit_file = &pIPF;
|
||||
if (FAILED(CoCreateInstance(&CLSID_ShellLink,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
&IID_IPersistFile,
|
||||
(void **)persit_file)))
|
||||
goto no_instance;
|
||||
|
||||
#ifdef UNICODE
|
||||
mbstowcs(old_path, path, MB_CUR_MAX);
|
||||
if (FAILED(pIPF->lpVtbl->Load(pIPF, old_path, STGM_READWRITE)))
|
||||
goto no_load;
|
||||
#else
|
||||
if (FAILED(pIPF->lpVtbl->Load(pIPF, path, STGM_READWRITE)))
|
||||
goto no_load;
|
||||
#endif /* ! UNICODE */
|
||||
|
||||
shell_link = &pISL;
|
||||
if (FAILED(pIPF->lpVtbl->QueryInterface(pIPF, &IID_IShellLink, (void **)shell_link)))
|
||||
goto no_queryinterface;
|
||||
|
||||
if (FAILED(pISL->lpVtbl->GetPath(pISL, new_path, PATH_MAX, NULL, 0)))
|
||||
goto no_getpath;
|
||||
|
||||
length = strlen(new_path);
|
||||
if (length > bufsiz)
|
||||
length = bufsiz;
|
||||
|
||||
memcpy(buf, new_path, length);
|
||||
|
||||
pISL->lpVtbl->Release(pISL);
|
||||
pIPF->lpVtbl->Release(pIPF);
|
||||
CoUninitialize();
|
||||
|
||||
return length;
|
||||
|
||||
no_getpath:
|
||||
pISL->lpVtbl->Release(pISL);
|
||||
no_queryinterface:
|
||||
no_load:
|
||||
pIPF->lpVtbl->Release(pIPF);
|
||||
no_instance:
|
||||
CoUninitialize();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
setenv(const char *name, const char *value)
|
||||
{
|
||||
char *str;
|
||||
int length;
|
||||
int res;
|
||||
|
||||
length = strlen(name) + strlen(value) + 2;
|
||||
str = (char *)malloc(length);
|
||||
sprintf(str, "%s=%s", name, value);
|
||||
res = _putenv(str);
|
||||
free(str);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
unsetenv(const char *name)
|
||||
{
|
||||
char *str;
|
||||
int length;
|
||||
int res;
|
||||
|
||||
length = strlen(name) + 2;
|
||||
str = (char *)malloc(length);
|
||||
sprintf(str, "%s=", name);
|
||||
res = _putenv(str);
|
||||
free(str);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* ! __CEGCC__ */
|
||||
|
||||
char *
|
||||
realpath(const char *file_name, char *resolved_name)
|
||||
{
|
||||
#if ! ( defined(__CEGCC__) || defined(__MINGW32CE__) )
|
||||
return _fullpath(resolved_name, file_name, PATH_MAX);
|
||||
#else
|
||||
int length;
|
||||
|
||||
length = strlen(file_name);
|
||||
if ((length + 1) > PATH_MAX)
|
||||
length = PATH_MAX - 1;
|
||||
memcpy(resolved_name, file_name, length);
|
||||
resolved_name[length] = '\0';
|
||||
|
||||
return resolved_name;
|
||||
#endif /* __CEGCC__ || __MINGW32CE__ */
|
||||
}
|
||||
|
||||
int
|
||||
evil_sockets_init(void)
|
||||
{
|
||||
WSADATA wsa_data;
|
||||
|
||||
return (WSAStartup(MAKEWORD( 2, 2 ), &wsa_data) == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
evil_sockets_shutdown(void)
|
||||
{
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
/*
|
||||
* The code of the following functions has been kindly offered
|
||||
* by Tor Lillqvist.
|
||||
*/
|
||||
int
|
||||
evil_pipe(int *fds)
|
||||
{
|
||||
struct sockaddr_in saddr;
|
||||
struct timeval tv;
|
||||
SOCKET temp;
|
||||
SOCKET socket1 = INVALID_SOCKET;
|
||||
SOCKET socket2 = INVALID_SOCKET;
|
||||
u_long arg;
|
||||
fd_set read_set;
|
||||
fd_set write_set;
|
||||
int len;
|
||||
|
||||
temp = socket (AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (temp == INVALID_SOCKET)
|
||||
goto out0;
|
||||
|
||||
arg = 1;
|
||||
if (ioctlsocket (temp, FIONBIO, &arg) == SOCKET_ERROR)
|
||||
goto out0;
|
||||
|
||||
memset (&saddr, 0, sizeof (saddr));
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_port = 0;
|
||||
saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
||||
|
||||
if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)))
|
||||
goto out0;
|
||||
|
||||
if (listen (temp, 1) == SOCKET_ERROR)
|
||||
goto out0;
|
||||
|
||||
len = sizeof (saddr);
|
||||
if (getsockname (temp, (struct sockaddr *)&saddr, &len))
|
||||
goto out0;
|
||||
|
||||
socket1 = socket (AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (socket1 == INVALID_SOCKET)
|
||||
goto out0;
|
||||
|
||||
arg = 1;
|
||||
if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
|
||||
goto out1;
|
||||
|
||||
if ((connect (socket1, (struct sockaddr *)&saddr, len) == SOCKET_ERROR) &&
|
||||
(WSAGetLastError () != WSAEWOULDBLOCK))
|
||||
goto out1;
|
||||
|
||||
FD_ZERO (&read_set);
|
||||
FD_SET (temp, &read_set);
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select (0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR)
|
||||
goto out1;
|
||||
|
||||
if (!FD_ISSET (temp, &read_set))
|
||||
goto out1;
|
||||
|
||||
socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
|
||||
if (socket2 == INVALID_SOCKET)
|
||||
goto out1;
|
||||
|
||||
FD_ZERO (&write_set);
|
||||
FD_SET (socket1, &write_set);
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select (0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR)
|
||||
goto out2;
|
||||
|
||||
if (!FD_ISSET (socket1, &write_set))
|
||||
goto out2;
|
||||
|
||||
arg = 0;
|
||||
if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
|
||||
goto out2;
|
||||
|
||||
arg = 0;
|
||||
if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
|
||||
goto out2;
|
||||
|
||||
fds[0] = socket1;
|
||||
fds[1] = socket2;
|
||||
|
||||
closesocket (temp);
|
||||
|
||||
return 0;
|
||||
|
||||
out2:
|
||||
closesocket (socket2);
|
||||
out1:
|
||||
closesocket (socket1);
|
||||
out0:
|
||||
closesocket (temp);
|
||||
|
||||
fds[0] = INVALID_SOCKET;
|
||||
fds[1] = INVALID_SOCKET;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *
|
||||
evil_tmpdir_get(void)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
return "\\temp";
|
||||
#else
|
||||
char *tmpdir;
|
||||
|
||||
tmpdir = getenv("TMP");
|
||||
if (!tmpdir) tmpdir = getenv("TEMP");
|
||||
if (!tmpdir) tmpdir = getenv("USERPROFILE");
|
||||
if (!tmpdir) tmpdir = getenv("WINDIR");
|
||||
if (!tmpdir) tmpdir="C:\\";
|
||||
|
||||
return tmpdir;
|
||||
#endif /* ! _WIN32_WCE */
|
||||
}
|
||||
|
||||
const char *
|
||||
evil_homedir_get(void)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
return "\\my documents";
|
||||
#else
|
||||
char *homedir;
|
||||
|
||||
homedir = getenv("HOME");
|
||||
if (!homedir) homedir = getenv("USERPROFILE");
|
||||
if (!homedir) homedir = getenv("WINDIR");
|
||||
if (!homedir) homedir="C:\\";
|
||||
|
||||
return homedir;
|
||||
#endif /* ! _WIN32_WCE */
|
||||
}
|
||||
|
||||
char *
|
||||
evil_getcwd(char *buffer, size_t size)
|
||||
{
|
||||
#if defined(__CEGCC__) || defined(__MINGW32CE__)
|
||||
wchar_t wpath[PATH_MAX];
|
||||
char *cpath;
|
||||
char *delim;
|
||||
int ret = 0;
|
||||
|
||||
if (size <= 0)
|
||||
return NULL;
|
||||
|
||||
ret = GetModuleFileName(GetModuleHandle(NULL), (LPWSTR)&wpath, PATH_MAX);
|
||||
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
cpath = evil_wchar_to_char(wpath);
|
||||
if (!cpath)
|
||||
return NULL;
|
||||
|
||||
if (strlen(cpath) >= (size - 1))
|
||||
{
|
||||
free(cpath);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
delim = strrchr(cpath, '\\');
|
||||
if (delim)
|
||||
*delim = '\0';
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
buffer = (char *)malloc(sizeof(char) * size);
|
||||
if (!buffer)
|
||||
{
|
||||
free(cpath);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(buffer, cpath);
|
||||
free(cpath);
|
||||
|
||||
return buffer;
|
||||
#else
|
||||
return _getcwd(buffer, size);
|
||||
#endif /* ! __CEGCC__ && ! __MINGW32CE__ */
|
||||
}
|
||||
|
||||
#ifdef UNICODE
|
||||
|
||||
wchar_t *
|
||||
evil_char_to_wchar(const char *text)
|
||||
{
|
||||
wchar_t *wtext;
|
||||
int wsize;
|
||||
|
||||
wsize = MultiByteToWideChar(CP_ACP, 0, text, strlen(text) + 1, NULL, 0);
|
||||
if ((wsize == 0) ||
|
||||
(wsize > (int)(ULONG_MAX/sizeof(wchar_t))))
|
||||
return NULL;
|
||||
|
||||
wtext = malloc(wsize * sizeof(wchar_t));
|
||||
if (wtext)
|
||||
if (!MultiByteToWideChar(CP_ACP, 0, text, strlen(text) + 1, wtext, wsize))
|
||||
return NULL;
|
||||
|
||||
return wtext;
|
||||
}
|
||||
|
||||
char *
|
||||
evil_wchar_to_char(const wchar_t *text)
|
||||
{
|
||||
char * atext;
|
||||
int size;
|
||||
int asize;
|
||||
|
||||
size = wcslen(text) + 1;
|
||||
|
||||
asize = WideCharToMultiByte(CP_ACP, 0, text, size, NULL, 0, NULL, NULL);
|
||||
if (asize == 0)
|
||||
return NULL;
|
||||
|
||||
atext = (char*)malloc((asize + 1) * sizeof(char));
|
||||
|
||||
if (atext)
|
||||
if (!WideCharToMultiByte(CP_ACP, 0, text, size, atext, asize, NULL, NULL))
|
||||
return NULL;
|
||||
atext[asize] = '\0';
|
||||
|
||||
return atext;
|
||||
}
|
||||
|
||||
#endif /* UNICODE */
|
||||
|
||||
char *
|
||||
evil_last_error_get(void)
|
||||
{
|
||||
char str[PATH_MAX];
|
||||
LPTSTR str1;
|
||||
char *str2;
|
||||
DWORD err;
|
||||
|
||||
err = GetLastError();
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
err,
|
||||
0, // Default language
|
||||
(LPTSTR)&str1,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
#ifdef UNICODE
|
||||
str2 = evil_wchar_to_char(str1);
|
||||
LocalFree(str1);
|
||||
#else
|
||||
str2 = str1;
|
||||
#endif /* ! UNICODE */
|
||||
|
||||
snprintf(str, PATH_MAX, "(%ld) %s", err, str2);
|
||||
LocalFree(str2);
|
||||
|
||||
return strdup(str);
|
||||
}
|
||||
|
||||
static char *
|
||||
replace(char *prev, char *value)
|
||||
{
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# include <io.h>
|
||||
#endif /* ! __CEGCC__ */
|
||||
|
||||
#include "../Evil.h"
|
||||
#include "Evil.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "pwd.h"
|
||||
|
||||
|
||||
static struct passwd pw;
|
||||
|
||||
|
||||
#ifndef __CEGCC__
|
||||
|
||||
struct passwd *
|
||||
getpwuid (uid_t uid)
|
||||
{
|
||||
static char user_name[PATH_MAX];
|
||||
DWORD length;
|
||||
BOOL res;
|
||||
|
||||
length = PATH_MAX;
|
||||
/* get from USERPROFILE for win 98 ? */
|
||||
res = GetUserName(user_name, &length);
|
||||
pw.pw_name = (res ? user_name : NULL);
|
||||
pw.pw_passwd = NULL;
|
||||
pw.pw_uid = uid;
|
||||
pw.pw_gid = 0;
|
||||
pw.pw_change = 0;
|
||||
pw.pw_class = NULL;
|
||||
pw.pw_gecos = (res ? user_name : NULL);
|
||||
pw.pw_dir = (char *)evil_homedir_get();
|
||||
pw.pw_shell = getenv("SHELL");
|
||||
if (pw.pw_shell == NULL)
|
||||
pw.pw_shell = "sh";
|
||||
pw.pw_expire = 0;
|
||||
pw.pw_fields = 0;
|
||||
|
||||
return &pw;
|
||||
}
|
||||
|
||||
#endif /* ! __CEGCC__ */
|
|
@ -0,0 +1,268 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#ifndef __MINGW32CE__
|
||||
#include <errno.h>
|
||||
#endif /* ! __MINGW32CE__ */
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "Evil.h"
|
||||
|
||||
/*** Local ***/
|
||||
|
||||
static void
|
||||
_evil_stdlib_error_display(const char *fct,
|
||||
LONG res)
|
||||
{
|
||||
char *error;
|
||||
|
||||
error = evil_format_message(res);
|
||||
fprintf(stderr, "[Evil] [%s] ERROR: %ld\n", fct, error);
|
||||
free(error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Environment variable related functions
|
||||
*
|
||||
* char *getenv (const char *name);
|
||||
* int putenv (const char *string);
|
||||
* int setenv (const char *name, const char *value, int overwrite);
|
||||
* void unsetenv (const char *name);
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__CEGCC__) || defined(__MINGW32CE__)
|
||||
|
||||
static char _evil_stdlib_getenv_buffer[PATH_MAX];
|
||||
|
||||
char *
|
||||
getenv(const char *name)
|
||||
{
|
||||
HKEY key;
|
||||
wchar_t *wname;
|
||||
char *buffer;
|
||||
LONG res;
|
||||
DWORD type;
|
||||
DWORD size = PATH_MAX;
|
||||
|
||||
if (!name || !*name)
|
||||
return NULL;
|
||||
|
||||
if ((res = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||||
TEXT("Software\\Efl\\Environment"),
|
||||
0, 0,
|
||||
&key)) != ERROR_SUCCESS)
|
||||
{
|
||||
_evil_stdlib_error_display("getenv", res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wname = evil_char_to_wchar(name);
|
||||
if (!wname)
|
||||
{
|
||||
if ((res = RegCloseKey (key)) != ERROR_SUCCESS)
|
||||
_evil_stdlib_error_display("getenv", res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((res = RegQueryValueEx(key, wname,
|
||||
NULL, &type,
|
||||
(LPBYTE)&buffer,
|
||||
&size)) != ERROR_SUCCESS)
|
||||
{
|
||||
_evil_stdlib_error_display("getenv", res);
|
||||
if ((res = RegCloseKey (key)) != ERROR_SUCCESS)
|
||||
_evil_stdlib_error_display("getenv", res);
|
||||
free(wname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(wname);
|
||||
|
||||
if ((res = RegCloseKey (key)) != ERROR_SUCCESS)
|
||||
{
|
||||
_evil_stdlib_error_display("getenv", res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (buffer[0] == '\0')
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
return _evil_stdlib_getenv_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __CEGCC__ || __MINGW32CE__ */
|
||||
|
||||
#if ! defined(__CEGCC__)
|
||||
|
||||
int
|
||||
putenv(const char *string)
|
||||
{
|
||||
#if ! ( defined(__CEGCC__) || defined(__MINGW32CE__) )
|
||||
return _putenv(string);
|
||||
#else
|
||||
#endif /* __CEGCC__ || __MINGW32CE__ */
|
||||
}
|
||||
|
||||
#endif /* ! __CEGCC__ */
|
||||
|
||||
|
||||
|
||||
int
|
||||
setenv(const char *name,
|
||||
const char *value,
|
||||
int overwrite)
|
||||
{
|
||||
#if ! ( defined(__CEGCC__) || defined(__MINGW32CE__) )
|
||||
|
||||
char *old_name;
|
||||
char *str;
|
||||
int length;
|
||||
|
||||
if (!name || !*name)
|
||||
return -1;
|
||||
|
||||
/* if '=' is found, return EINVAL */
|
||||
if (strchr (name, '='))
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* if name is already set and overwrite is 0, we exit with success */
|
||||
old_name = getenv(name);
|
||||
if (!overwrite && oldname)
|
||||
return 0;
|
||||
|
||||
length = strlen(name) + strlen(value) + 2;
|
||||
str = (char *)malloc(length);
|
||||
if (!str)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
if (!value)
|
||||
sprintf(str, "%s=", name);
|
||||
else
|
||||
sprintf(str, "%s=%s", name, value);
|
||||
res = _putenv(str);
|
||||
free(str);
|
||||
|
||||
#else /* __CEGCC__ || __MINGW32CE__ */
|
||||
|
||||
HKEY key;
|
||||
LONG res;
|
||||
DWORD disposition;
|
||||
|
||||
if (!name || !*name)
|
||||
return -1;
|
||||
|
||||
/* if '=' is found, return an error */
|
||||
if (strchr (name, '='))
|
||||
return -1;
|
||||
|
||||
if ((res = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
||||
TEXT("Software\\Efl\\Environment"),
|
||||
0, NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
0, NULL,
|
||||
&key,
|
||||
&disposition)) != ERROR_SUCCESS)
|
||||
{
|
||||
_evil_stdlib_error_display("setenv", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* if name is already set and overwrite is 0, we exit with success */
|
||||
if (!overwrite && (disposition == REG_OPENED_EXISTING_KEY))
|
||||
return 0;
|
||||
|
||||
if ((res = RegSetValueEx (key,
|
||||
(LPCWSTR)name,
|
||||
0, REG_SZ,
|
||||
value,
|
||||
strlen(value) + 1)) != ERROR_SUCCESS)
|
||||
{
|
||||
_evil_stdlib_error_display("setenv", res);
|
||||
if ((res = RegCloseKey (key)) != ERROR_SUCCESS)
|
||||
_evil_stdlib_error_display("getenv", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((res = RegCloseKey (key)) != ERROR_SUCCESS)
|
||||
{
|
||||
_evil_stdlib_error_display("getenv", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* __CEGCC__ || __MINGW32CE__ */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if ! defined(__CEGCC__)
|
||||
|
||||
int
|
||||
unsetenv(const char *name)
|
||||
{
|
||||
setenv(name, NULL, 1);
|
||||
}
|
||||
|
||||
#endif /* ! __CEGCC__ */
|
||||
|
||||
|
||||
/*
|
||||
* Files related functions
|
||||
*
|
||||
*/
|
||||
|
||||
#if ! ( defined(__CEGCC__) || defined(__MINGW32CE__) )
|
||||
|
||||
int
|
||||
mkstemp(char *template)
|
||||
{
|
||||
int fd;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
if (!_mktemp(template))
|
||||
return -1;
|
||||
|
||||
fd = _sopen(template, _O_RDWR | _O_BINARY | _O_CREAT | _O_EXCL, _SH_DENYNO, _S_IREAD | _S_IWRITE);
|
||||
#else
|
||||
if (_mktemp_s(template, PATH_MAX) != 0)
|
||||
return -1;
|
||||
|
||||
_sopen_s(&fd, template, _O_RDWR | _O_BINARY | _O_CREAT, _SH_DENYNO, _S_IREAD | _S_IWRITE);
|
||||
#endif /* ! __MINGW32__ */
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
#endif /* ! ( __CEGCC__ || __MINGW32CE__ ) */
|
||||
|
||||
|
||||
char *
|
||||
realpath(const char *file_name, char *resolved_name)
|
||||
{
|
||||
#if ! ( defined(__CEGCC__) || defined(__MINGW32CE__) )
|
||||
return _fullpath(resolved_name, file_name, PATH_MAX);
|
||||
#else
|
||||
int length;
|
||||
|
||||
length = strlen(file_name);
|
||||
if ((length + 1) > PATH_MAX)
|
||||
length = PATH_MAX - 1;
|
||||
memcpy(resolved_name, file_name, length);
|
||||
resolved_name[length] = '\0';
|
||||
|
||||
return resolved_name;
|
||||
#endif /* __CEGCC__ || __MINGW32CE__ */
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
#ifndef __EVIL_STDLIB_H__
|
||||
#define __EVIL_STDLIB_H__
|
||||
|
||||
|
||||
/*
|
||||
* Environment variable related functions
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__CEGCC__) || defined(__MINGW32CE__)
|
||||
|
||||
EAPI char *getenv(const char *name);
|
||||
|
||||
#endif /* __CEGCC__ || __MINGW32CE__ */
|
||||
|
||||
|
||||
#if ! defined(__CEGCC__)
|
||||
|
||||
EAPI int putenv(const char *string);
|
||||
|
||||
#endif /* ! __CEGCC__ */
|
||||
|
||||
/**
|
||||
* @brief Create, modify, or remove environment variables.
|
||||
*
|
||||
* @param name The name of the environment variable.
|
||||
* @param value The value of the environment variable to set.
|
||||
* @return 0 on success, -1 otherwise.
|
||||
*
|
||||
* Add the new environment variable @p name or modify its value if it
|
||||
* exists, and set it to @p value. Environment variables define the
|
||||
* environment in which a process executes. If @p value is @c NULL, the
|
||||
* variable is removed (unset) and that call is equivalent to unsetenv().
|
||||
* If the function succeeds, it returns 0, otherwise it returns -1.
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI int setenv(const char *name,
|
||||
const char *value,
|
||||
int overwrite);
|
||||
|
||||
|
||||
#if ! defined(__CEGCC__)
|
||||
|
||||
/**
|
||||
* @brief Remove environment variables.
|
||||
*
|
||||
* @param name The name of the environment variable.
|
||||
* @return 0 on success, -1 otherwise.
|
||||
*
|
||||
* Remove the new environment variable @p name if it exists. That
|
||||
* function is equivalent to setenv() with its second parameter to
|
||||
* @c NULL and the third to 1. If the function succeeds, it returns 0,
|
||||
* otherwise it returns -1.
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI int unsetenv(const char *name);
|
||||
|
||||
#endif /* ! __CEGCC__ */
|
||||
|
||||
|
||||
/*
|
||||
* Files related functions
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Make temporay unique file name.
|
||||
*
|
||||
* @param template Template of the file to create.
|
||||
* @return A file descriptor on success, -1 otherwise.
|
||||
*
|
||||
* Take the given file name @p template and overwrite a portion of it
|
||||
* to create a file name. This file is guaranted not to exist at the
|
||||
* time invocation and is suitable for use by the function.
|
||||
*
|
||||
* The @p template parameter can be any file name with some number of
|
||||
* 'Xs' appended to it, for example @em baseXXXXXX, where @em base is
|
||||
* the part of the new file that you supply and eacg 'X' is a placeholder
|
||||
* for a character supplied by mkstemp(). The trailing 'Xs' are replaced
|
||||
* with a five-digit value; this value is a unique number. Each successful
|
||||
* call to mkstemp() modifes @p template.
|
||||
*
|
||||
* When mkstemp() succeeds, it creates and opens the template file for
|
||||
* reading and writing.
|
||||
*
|
||||
* On success, the function returns the file descriptor of the
|
||||
* temporary file. Otherwise, it returns -1 and errno is set to the
|
||||
* following values:
|
||||
* - EINVAL: @p template has an invalid format.
|
||||
* - EACCESS: Given path is a directory, or file is read-only, but an
|
||||
* open-for-writing operation was attempted.
|
||||
* - EEXISTS: File name already exists.
|
||||
* - EMFILE: No more file descriptors available.
|
||||
* - ENOENT: File or path not found.
|
||||
*
|
||||
* Conformity: Should follow BSD conformity.
|
||||
*
|
||||
* Supported OS: Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI int mkstemp(char *template);
|
||||
|
||||
/**
|
||||
* @brief Return an absolute or full path name for a specified relative path name.
|
||||
*
|
||||
* @param file_name The absolute path name.
|
||||
* @param resolved_name The relative path name.
|
||||
* @return @c NULL on failure, a pointer to the absolute path name otherwise.
|
||||
*
|
||||
* The function expands the relative path name @p file_name to its
|
||||
* fully qualified or absolute path and store it in the buffer pointed
|
||||
* by @p resolved_name. The buffer is at most @c PATH_MAX bytes long.
|
||||
* If @p resolved_name is @c NULL, malloc() is used to allocate a
|
||||
* buffer of sufficient length to hold the path name. In that case, it
|
||||
* is the responsability of the caller to free this buffer with free().
|
||||
*
|
||||
* That function can be used to obtain the absolute path name for
|
||||
* relative paths (relPath) that include "./" or "../" in their names.
|
||||
*
|
||||
* Conformity: None.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI char *realpath(const char *file_name, char *resolved_name);
|
||||
|
||||
|
||||
#endif /* __EVIL_STDLIB_H__ */
|
||||
|
|
@ -0,0 +1,396 @@
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "Evil.h"
|
||||
|
||||
/*
|
||||
* Process identifer related functions
|
||||
*
|
||||
*/
|
||||
|
||||
pid_t
|
||||
getpid(void)
|
||||
{
|
||||
return (pid_t)GetCurrentProcessId();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Symbolic links and directory related functions
|
||||
*
|
||||
*/
|
||||
|
||||
/* REMARK: Windows has no symbolic link. */
|
||||
/* Nevertheless, it can create and read .lnk files */
|
||||
int
|
||||
symlink(const char *oldpath, const char *newpath)
|
||||
{
|
||||
#if defined(__CEGCC__) || defined(__MINGW32CE__)
|
||||
wchar_t *w_oldpath;
|
||||
wchar_t *w_newpath;
|
||||
BOOL res;
|
||||
|
||||
w_oldpath = evil_char_to_wchar(oldpath);
|
||||
if (!w_oldpath)
|
||||
return -1;
|
||||
|
||||
w_newpath = evil_char_to_wchar(newpath);
|
||||
if (!w_newpath)
|
||||
{
|
||||
free(w_oldpath);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = SHCreateShortcutEx(w_newpath, w_oldpath, NULL, NULL);
|
||||
|
||||
free(w_oldpath);
|
||||
free(w_newpath);
|
||||
|
||||
return res ? 0 : -1;
|
||||
#else
|
||||
#ifdef UNICODE
|
||||
wchar_t new_path[MB_CUR_MAX];
|
||||
#endif /* UNICODE */
|
||||
IShellLink *pISL;
|
||||
IShellLink **shell_link;
|
||||
IPersistFile *pIPF;
|
||||
IPersistFile **persit_file;
|
||||
HRESULT res;
|
||||
|
||||
res = CoInitialize(NULL);
|
||||
if (FAILED(res))
|
||||
{
|
||||
if (res == E_OUTOFMEMORY)
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Hack to cleanly remove a warning */
|
||||
shell_link = &pISL;
|
||||
if (FAILED(CoCreateInstance(&CLSID_ShellLink,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
&IID_IShellLink,
|
||||
(void **)shell_link)))
|
||||
goto no_instance;
|
||||
|
||||
if (FAILED(pISL->lpVtbl->SetPath(pISL, oldpath)))
|
||||
goto no_setpath;
|
||||
|
||||
/* Hack to cleanly remove a warning */
|
||||
persit_file = &pIPF;
|
||||
if (FAILED(pISL->lpVtbl->QueryInterface(pISL, &IID_IPersistFile, (void **)persit_file)))
|
||||
goto no_queryinterface;
|
||||
|
||||
#ifdef UNICODE
|
||||
mbstowcs(new_path, newpath, MB_CUR_MAX);
|
||||
if (FAILED(pIPF->lpVtbl->Save(pIPF, new_path, FALSE)))
|
||||
goto no_save;
|
||||
#else
|
||||
if (FAILED(pIPF->lpVtbl->Save(pIPF, newpath, FALSE)))
|
||||
goto no_save;
|
||||
#endif /* ! UNICODE */
|
||||
|
||||
pIPF->lpVtbl->Release(pIPF);
|
||||
pISL->lpVtbl->Release(pISL);
|
||||
CoUninitialize();
|
||||
|
||||
return 0;
|
||||
|
||||
no_save:
|
||||
pIPF->lpVtbl->Release(pIPF);
|
||||
no_queryinterface:
|
||||
no_setpath:
|
||||
pISL->lpVtbl->Release(pISL);
|
||||
no_instance:
|
||||
CoUninitialize();
|
||||
return -1;
|
||||
#endif /* ! __CEGCC__ && ! __MINGW32CE__ */
|
||||
}
|
||||
|
||||
ssize_t
|
||||
readlink(const char *path, char *buf, size_t bufsiz)
|
||||
{
|
||||
#if defined(__CEGCC__) || defined(__MINGW32CE__)
|
||||
wchar_t *w_path;
|
||||
wchar_t w_newpath[MB_CUR_MAX];
|
||||
char *newpath;
|
||||
size_t length;
|
||||
BOOL res;
|
||||
|
||||
w_path = evil_char_to_wchar(path);
|
||||
if (!w_path)
|
||||
return -1;
|
||||
|
||||
res = SHGetShortcutTarget(w_path, w_newpath, MB_CUR_MAX);
|
||||
|
||||
free(w_path);
|
||||
|
||||
if (!res)
|
||||
return -1;
|
||||
|
||||
newpath = evil_wchar_to_char(w_newpath);
|
||||
if (!newpath)
|
||||
return -1;
|
||||
|
||||
length = strlen(newpath);
|
||||
if (length > bufsiz)
|
||||
length = bufsiz;
|
||||
|
||||
memcpy(buf, newpath, length);
|
||||
|
||||
free(newpath);
|
||||
|
||||
return length;
|
||||
#else
|
||||
#ifdef UNICODE
|
||||
wchar_t old_path[MB_CUR_MAX];
|
||||
#endif /* UNICODE */
|
||||
char new_path[PATH_MAX];
|
||||
IShellLink *pISL;
|
||||
IShellLink **shell_link;
|
||||
IPersistFile *pIPF;
|
||||
IPersistFile **persit_file;
|
||||
unsigned int length;
|
||||
HRESULT res;
|
||||
|
||||
res = CoInitialize(NULL);
|
||||
if (FAILED(res))
|
||||
{
|
||||
if (res == E_OUTOFMEMORY)
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Hack to cleanly remove a warning */
|
||||
persit_file = &pIPF;
|
||||
if (FAILED(CoCreateInstance(&CLSID_ShellLink,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
&IID_IPersistFile,
|
||||
(void **)persit_file)))
|
||||
goto no_instance;
|
||||
|
||||
#ifdef UNICODE
|
||||
mbstowcs(old_path, path, MB_CUR_MAX);
|
||||
if (FAILED(pIPF->lpVtbl->Load(pIPF, old_path, STGM_READWRITE)))
|
||||
goto no_load;
|
||||
#else
|
||||
if (FAILED(pIPF->lpVtbl->Load(pIPF, path, STGM_READWRITE)))
|
||||
goto no_load;
|
||||
#endif /* ! UNICODE */
|
||||
|
||||
shell_link = &pISL;
|
||||
if (FAILED(pIPF->lpVtbl->QueryInterface(pIPF, &IID_IShellLink, (void **)shell_link)))
|
||||
goto no_queryinterface;
|
||||
|
||||
if (FAILED(pISL->lpVtbl->GetPath(pISL, new_path, PATH_MAX, NULL, 0)))
|
||||
goto no_getpath;
|
||||
|
||||
length = strlen(new_path);
|
||||
if (length > bufsiz)
|
||||
length = bufsiz;
|
||||
|
||||
memcpy(buf, new_path, length);
|
||||
|
||||
pISL->lpVtbl->Release(pISL);
|
||||
pIPF->lpVtbl->Release(pIPF);
|
||||
CoUninitialize();
|
||||
|
||||
return length;
|
||||
|
||||
no_getpath:
|
||||
pISL->lpVtbl->Release(pISL);
|
||||
no_queryinterface:
|
||||
no_load:
|
||||
pIPF->lpVtbl->Release(pIPF);
|
||||
no_instance:
|
||||
CoUninitialize();
|
||||
return -1;
|
||||
#endif /* ! __CEGCC__ && ! __MINGW32CE__ */
|
||||
}
|
||||
|
||||
char *
|
||||
evil_getcwd(char *buffer, size_t size)
|
||||
{
|
||||
#if defined(__CEGCC__) || defined(__MINGW32CE__)
|
||||
wchar_t wpath[PATH_MAX];
|
||||
char *cpath;
|
||||
char *delim;
|
||||
int ret = 0;
|
||||
|
||||
if (size <= 0)
|
||||
return NULL;
|
||||
|
||||
ret = GetModuleFileName(GetModuleHandle(NULL), (LPWSTR)&wpath, PATH_MAX);
|
||||
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
cpath = evil_wchar_to_char(wpath);
|
||||
if (!cpath)
|
||||
return NULL;
|
||||
|
||||
if (strlen(cpath) >= (size - 1))
|
||||
{
|
||||
free(cpath);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
delim = strrchr(cpath, '\\');
|
||||
if (delim)
|
||||
*delim = '\0';
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
buffer = (char *)malloc(sizeof(char) * size);
|
||||
if (!buffer)
|
||||
{
|
||||
free(cpath);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(buffer, cpath);
|
||||
free(cpath);
|
||||
|
||||
return buffer;
|
||||
#else
|
||||
return _getcwd(buffer, size);
|
||||
#endif /* ! __CEGCC__ && ! __MINGW32CE__ */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sockets and pipe related functions
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
evil_sockets_init(void)
|
||||
{
|
||||
WSADATA wsa_data;
|
||||
|
||||
return (WSAStartup(MAKEWORD( 2, 2 ), &wsa_data) == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
evil_sockets_shutdown(void)
|
||||
{
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
/*
|
||||
* The code of the following functions has been kindly offered
|
||||
* by Tor Lillqvist.
|
||||
*/
|
||||
int
|
||||
evil_pipe(int *fds)
|
||||
{
|
||||
struct sockaddr_in saddr;
|
||||
struct timeval tv;
|
||||
SOCKET temp;
|
||||
SOCKET socket1 = INVALID_SOCKET;
|
||||
SOCKET socket2 = INVALID_SOCKET;
|
||||
u_long arg;
|
||||
fd_set read_set;
|
||||
fd_set write_set;
|
||||
int len;
|
||||
|
||||
temp = socket (AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (temp == INVALID_SOCKET)
|
||||
goto out0;
|
||||
|
||||
arg = 1;
|
||||
if (ioctlsocket (temp, FIONBIO, &arg) == SOCKET_ERROR)
|
||||
goto out0;
|
||||
|
||||
memset (&saddr, 0, sizeof (saddr));
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_port = 0;
|
||||
saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
||||
|
||||
if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)))
|
||||
goto out0;
|
||||
|
||||
if (listen (temp, 1) == SOCKET_ERROR)
|
||||
goto out0;
|
||||
|
||||
len = sizeof (saddr);
|
||||
if (getsockname (temp, (struct sockaddr *)&saddr, &len))
|
||||
goto out0;
|
||||
|
||||
socket1 = socket (AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (socket1 == INVALID_SOCKET)
|
||||
goto out0;
|
||||
|
||||
arg = 1;
|
||||
if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
|
||||
goto out1;
|
||||
|
||||
if ((connect (socket1, (struct sockaddr *)&saddr, len) == SOCKET_ERROR) &&
|
||||
(WSAGetLastError () != WSAEWOULDBLOCK))
|
||||
goto out1;
|
||||
|
||||
FD_ZERO (&read_set);
|
||||
FD_SET (temp, &read_set);
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select (0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR)
|
||||
goto out1;
|
||||
|
||||
if (!FD_ISSET (temp, &read_set))
|
||||
goto out1;
|
||||
|
||||
socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
|
||||
if (socket2 == INVALID_SOCKET)
|
||||
goto out1;
|
||||
|
||||
FD_ZERO (&write_set);
|
||||
FD_SET (socket1, &write_set);
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select (0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR)
|
||||
goto out2;
|
||||
|
||||
if (!FD_ISSET (socket1, &write_set))
|
||||
goto out2;
|
||||
|
||||
arg = 0;
|
||||
if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
|
||||
goto out2;
|
||||
|
||||
arg = 0;
|
||||
if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
|
||||
goto out2;
|
||||
|
||||
fds[0] = socket1;
|
||||
fds[1] = socket2;
|
||||
|
||||
closesocket (temp);
|
||||
|
||||
return 0;
|
||||
|
||||
out2:
|
||||
closesocket (socket2);
|
||||
out1:
|
||||
closesocket (socket1);
|
||||
out0:
|
||||
closesocket (temp);
|
||||
|
||||
fds[0] = INVALID_SOCKET;
|
||||
fds[1] = INVALID_SOCKET;
|
||||
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
#ifndef __EVIL_UNISTD_H__
|
||||
#define __EVIL_UNISTD_H__
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
typedef int pid_t;
|
||||
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
|
||||
/*
|
||||
* Process identifer related functions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return the process identifier of the calling process.
|
||||
*
|
||||
* @return The process ID.
|
||||
*
|
||||
* Return the process identifier of the calling process. Until
|
||||
* the process terminates, the process identifier uniquely
|
||||
* identifies the process throughout the system.
|
||||
*
|
||||
* Conformity: Not appliclable.
|
||||
*
|
||||
* Supported OS: Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI pid_t getpid(void);
|
||||
|
||||
|
||||
/*
|
||||
* Symbolic links and directory related functions
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Create a shell link.
|
||||
*
|
||||
* @param oldpath The file name to be linked.
|
||||
* @param newpath The file name to create.
|
||||
* @return 0 on success, -1 otherwise.
|
||||
*
|
||||
* Create a shell link @p newpath to @p oldpath (@p newpath is the
|
||||
* name of the file created, @p oldpath is the string used in
|
||||
* creating the shell link).
|
||||
*
|
||||
* On success, this function returns 0. Otherwise, it returns -1 and
|
||||
* errno may be set to the following value:
|
||||
* - ENOMEM: Not enough memory.
|
||||
*
|
||||
* On Windows, the symbolic links do not exist. Nevertheless
|
||||
* shell links can be created. This function is named like the Unix
|
||||
* function for portability reasons.
|
||||
*
|
||||
* Conformity: None.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI int symlink(const char *oldpath, const char *newpath);
|
||||
|
||||
/**
|
||||
* @brief Read value of a shell link.
|
||||
*
|
||||
* @param path The file name to be linked.
|
||||
* @param buf The file name to create.
|
||||
* @param bufsiz The size of the buffer.
|
||||
* @return 0 on success, -1 otherwise.
|
||||
*
|
||||
* Place the content of the shell link @p path in the buffer
|
||||
* @p buf, which has size @p bufzsiz.
|
||||
*
|
||||
* On success, this function returns the count of characters
|
||||
* placed in the buffer. Otherwise, it returns -1 and errno may
|
||||
* be set to the following value:
|
||||
* - ENOMEM: Not enough memory.
|
||||
*
|
||||
* On Windows, the symbolic links do not exist. Nevertheless
|
||||
* shell links can be managed. This function is named like the Unix
|
||||
* function for portability reasons.
|
||||
*
|
||||
* Conformity: None.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI ssize_t readlink(const char *path, char *buf, size_t bufsiz);
|
||||
|
||||
/**
|
||||
* @brief Get the current directory.
|
||||
*
|
||||
* @param buffer Buffer to store the current directory.
|
||||
* @param size Size of the buffer.
|
||||
* @return The current directory.
|
||||
*
|
||||
* On Windows desktop, use the _getcwd function in MSVCRT.
|
||||
*
|
||||
* On Windows CE, get the current directory by extracting the path
|
||||
* from the executable that is running and put the result in @p buffer
|
||||
* of length @p size. If @p size is less or equal than 0, return NULL.
|
||||
* If the current absolute path would require a buffer longer than
|
||||
* @p size elements, NULL is returned. If @p buffer is NULL, a buffer
|
||||
* of length @p size is allocated and is returned. If the allocation
|
||||
* fails, NULL is returned. On success, @p buffer is returned and
|
||||
* contains the current directory. The last '\' is not included.
|
||||
* If @p buffer is NULL, the returned value must be freed if not NULL.
|
||||
*
|
||||
* Specially usefull on WinCE where the current directory functionality
|
||||
* is not supported.
|
||||
*
|
||||
* Conformity: Almost POSIX.1 (no errno set)
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP, WinCE.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI char *evil_getcwd(char *buffer, size_t size);
|
||||
|
||||
|
||||
/*
|
||||
* Sockets and pipe related functions
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initiates the use of Windows sockets.
|
||||
*
|
||||
* @return 1 on success, 0 otherwise.
|
||||
*
|
||||
* Initiates the use of Windows sockets. If the function succeeds,
|
||||
* it returns 1, otherwise it returns 0.
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI int evil_sockets_init(void);
|
||||
|
||||
/**
|
||||
* @brief Shutdown the Windows socket system.
|
||||
*
|
||||
* Shutdown the Windows socket system.
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI void evil_sockets_shutdown(void);
|
||||
|
||||
/**
|
||||
* @brief Create a pair of sockets.
|
||||
*
|
||||
* @param fds A pointer that contains two sockets.
|
||||
*
|
||||
* Create a pair of sockets that can be use with select().
|
||||
* Hence, evil_sockets_init() must have been caled at least
|
||||
* once before. Contrary to Unix, that functions does not
|
||||
* create a pair of file descriptors.
|
||||
*
|
||||
* Conformity: Not applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI int evil_pipe(int *fds);
|
||||
|
||||
|
||||
#endif /* __EVIL_UNISTD_H__ */
|
|
@ -0,0 +1,137 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "Evil.h"
|
||||
|
||||
|
||||
wchar_t *
|
||||
evil_char_to_wchar(const char *text)
|
||||
{
|
||||
wchar_t *wtext;
|
||||
int wsize;
|
||||
|
||||
wsize = MultiByteToWideChar(CP_ACP, 0, text, strlen(text) + 1, NULL, 0);
|
||||
if ((wsize == 0) ||
|
||||
(wsize > (int)(ULONG_MAX / sizeof(wchar_t))))
|
||||
return NULL;
|
||||
|
||||
wtext = malloc(wsize * sizeof(wchar_t));
|
||||
if (wtext)
|
||||
if (!MultiByteToWideChar(CP_ACP, 0, text, strlen(text) + 1, wtext, wsize))
|
||||
return NULL;
|
||||
|
||||
return wtext;
|
||||
}
|
||||
|
||||
char *
|
||||
evil_wchar_to_char(const wchar_t *text)
|
||||
{
|
||||
char * atext;
|
||||
int size;
|
||||
int asize;
|
||||
|
||||
size = wcslen(text) + 1;
|
||||
|
||||
asize = WideCharToMultiByte(CP_ACP, 0, text, size, NULL, 0, NULL, NULL);
|
||||
if (asize == 0)
|
||||
return NULL;
|
||||
|
||||
atext = (char*)malloc((asize + 1) * sizeof(char));
|
||||
|
||||
if (atext)
|
||||
if (!WideCharToMultiByte(CP_ACP, 0, text, size, atext, asize, NULL, NULL))
|
||||
return NULL;
|
||||
atext[asize] = '\0';
|
||||
|
||||
return atext;
|
||||
}
|
||||
|
||||
char *
|
||||
evil_format_message(long err)
|
||||
{
|
||||
LPTSTR msg;
|
||||
char *str;
|
||||
char *disp;
|
||||
|
||||
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
err,
|
||||
0, // Default language
|
||||
(LPTSTR)&msg,
|
||||
0,
|
||||
NULL))
|
||||
return NULL;
|
||||
|
||||
#ifdef UNICODE
|
||||
str = evil_wchar_to_char(msg);
|
||||
#else
|
||||
str = strdup(msg);
|
||||
#endif /* UNICODE */
|
||||
|
||||
LocalFree(msg);
|
||||
|
||||
disp = (char *)malloc((strlen(str) + strlen("(00000) ") + 1) * sizeof(char));
|
||||
if (!disp)
|
||||
return NULL;
|
||||
|
||||
snprintf(disp, strlen(str) + strlen("(00000) ") + 1,
|
||||
"(%5d) %s", err, str);
|
||||
|
||||
free(str);
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
char *
|
||||
evil_last_error_get(void)
|
||||
{
|
||||
DWORD err;
|
||||
|
||||
err = GetLastError();
|
||||
return evil_format_message(err);
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
evil_tmpdir_get(void)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
return "\\temp";
|
||||
#else
|
||||
char *tmpdir;
|
||||
|
||||
tmpdir = getenv("TMP");
|
||||
if (!tmpdir) tmpdir = getenv("TEMP");
|
||||
if (!tmpdir) tmpdir = getenv("USERPROFILE");
|
||||
if (!tmpdir) tmpdir = getenv("WINDIR");
|
||||
if (!tmpdir) tmpdir="C:\\";
|
||||
|
||||
return tmpdir;
|
||||
#endif /* ! _WIN32_WCE */
|
||||
}
|
||||
|
||||
const char *
|
||||
evil_homedir_get(void)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
return "\\my documents";
|
||||
#else
|
||||
char *homedir;
|
||||
|
||||
homedir = getenv("HOME");
|
||||
if (!homedir) homedir = getenv("USERPROFILE");
|
||||
if (!homedir) homedir = getenv("WINDIR");
|
||||
if (!homedir) homedir="C:\\";
|
||||
|
||||
return homedir;
|
||||
#endif /* ! _WIN32_WCE */
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
#ifndef __EVIL_UTIL_H__
|
||||
#define __EVIL_UTIL_H__
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convert a string from char * to wchar_t *.
|
||||
*
|
||||
* @param text The string to convert.
|
||||
* @return The converted string.
|
||||
*
|
||||
* Convert a string from char * to wchar_t * and return it. If the
|
||||
* allocation or conversion fails, NULL is returned. On success, the
|
||||
* returned value must be freed.
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI wchar_t *evil_char_to_wchar(const char *text);
|
||||
|
||||
/**
|
||||
* @brief Convert a string from wchar_t * to char *.
|
||||
*
|
||||
* @param text The string to convert.
|
||||
* @return The converted string.
|
||||
*
|
||||
* Convert a string from wchar_t * to char * and return it. If the
|
||||
* allocation or conversion fails, NULL is returned. On success, the
|
||||
* returned value must be freed.
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI char *evil_wchar_to_char(const wchar_t *text);
|
||||
|
||||
EAPI char *evil_format_message(long err);
|
||||
|
||||
EAPI char *evil_last_error_get(void);
|
||||
|
||||
/**
|
||||
* @brief Return a dir to store temporary files.
|
||||
*
|
||||
* @return The directory to store temporary files.
|
||||
*
|
||||
* Return a directory to store temporary files. The function gets
|
||||
* the value of the following environment variables, and in that order:
|
||||
* - TMP
|
||||
* - TEMP
|
||||
* - USERPROFILE
|
||||
* - WINDIR
|
||||
* and returns its value if it exists. If none exists, the function
|
||||
* returns "C:\".
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI const char *evil_tmpdir_get(void);
|
||||
|
||||
/**
|
||||
* @brief Return a dir to store personal files.
|
||||
*
|
||||
* @return The directory to store personal files.
|
||||
*
|
||||
* Return a directory to store personal files. The function gets
|
||||
* the value of the following environment variables, and in that order:
|
||||
* - HOME
|
||||
* - USERPROFILE
|
||||
* - WINDIR
|
||||
* and returns its value if it exists. If none exists, the function
|
||||
* returns "C:\".
|
||||
*
|
||||
* Conformity: Non applicable.
|
||||
*
|
||||
* Supported OS: Windows 95, Windows 98, Windows Me, Windows NT, Windows 2000,
|
||||
* Windows XP.
|
||||
*
|
||||
* @ingroup Evil
|
||||
*/
|
||||
EAPI const char *evil_homedir_get(void);
|
||||
|
||||
|
||||
#endif /* __EVIL_UTIL_H__ */
|
|
@ -1,6 +0,0 @@
|
|||
.deps
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
*.la
|
||||
*.lo
|
|
@ -1,12 +0,0 @@
|
|||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
lib_LTLIBRARIES = libmman.la
|
||||
|
||||
nobase_include_HEADERS = sys/mman.h
|
||||
libmman_la_SOURCES = mman.c
|
||||
|
||||
libmman_la_CFLAGS = @win32_cflags@
|
||||
libmman_la_LIBADD = $(top_builddir)/src/lib/libevil.la
|
||||
libmman_la_DEPENDENCIES = $(top_builddir)/config.h $(top_builddir)/src/lib/libevil.la
|
||||
libmman_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
include_HEADERS = pwd.h
|
|
@ -192,6 +192,26 @@
|
|||
RelativePath="..\..\src\lib\evil.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\lib\evil_mman.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\lib\evil_pwd.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\lib\evil_stdlib.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\lib\evil_unistd.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\lib\evil_util.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
|
|
Loading…
Reference in New Issue