flush
authorMichael Wallner <mike@php.net>
Thu, 12 Nov 2015 13:37:00 +0000 (14:37 +0100)
committerMichael Wallner <mike@php.net>
Thu, 12 Nov 2015 13:37:00 +0000 (14:37 +0100)
config.m4
src/context.c
src/module.c
src/parser.h
tests/stat/stat.psi

index 647b0a9..8382435 100644 (file)
--- a/config.m4
+++ b/config.m4
@@ -236,6 +236,26 @@ if test "$PHP_PSI" != "no"; then
                ])
                PSI_STRUCTS="{\"$1\", $psi_struct_size, {$psi_struct_members}}, $PSI_STRUCTS"
        ])
+       
+       AC_PROG_NM
+       AC_PROG_AWK
+       PSI_FUNCS=
+       dnl PSI_FUNC(fn, decl)
+       AC_DEFUN(PSI_FUNC, [
+               AC_CHECK_FUNC($1, [
+                       AC_MSG_CHECKING(for redirection of function $1)
+                       psi_symbol=$1
+                       psi_symbol_redirect=
+                       AC_TRY_LINK_FUNC($1, [
+                               psi_symbol_redirect=`$NM -g conftest$ac_exeext | $AWK -F" *|@" '/_main/ {next} / U / {print$[]3}'`
+                       ])
+                       AC_MSG_RESULT($psi_symbol_redirect)
+                       if test "$psi_symbol_redirect" && test "$psi_symbol_redirect" != "$psi_symbol"
+                       then
+                               PSI_FUNCS="{\"$psi_symbol\", (void *) $psi_symbol}, $PSI_FUNCS"
+                       fi
+               ])
+       ])
 
        AC_TYPE_INT8_T
        AC_CHECK_ALIGNOF(int8_t)
@@ -364,6 +384,22 @@ if test "$PHP_PSI" != "no"; then
        PSI_CONST(RAND_MAX, int)
        PSI_CONST(MB_CUR_MAX, int)
        dnl sys/stat.h
+       PSI_FUNC(chmod)
+       PSI_FUNC(fchmod)
+       PSI_FUNC(fchmodat)
+       PSI_FUNC(fstat)
+       PSI_FUNC(fstatat)
+       PSI_FUNC(futimens)
+       PSI_FUNC(lstat)
+       PSI_FUNC(mkdir)
+       PSI_FUNC(mkdirat)
+       PSI_FUNC(mkfifo)
+       PSI_FUNC(mkfifoat)
+       PSI_FUNC(mknod)
+       PSI_FUNC(mknodat)
+       PSI_FUNC(stat)
+       PSI_FUNC(umask)
+       PSI_FUNC(utimensat)
        PSI_STRUCT(stat, [
                [st_dev],
                [st_ino],
@@ -426,6 +462,7 @@ if test "$PHP_PSI" != "no"; then
        PSI_CONST(ITIMER_VIRTUAL, int, sys/time.h)
        PSI_CONST(ITIMER_PROF, int, sys/time.h)
        dnl sys/times.h
+       PSI_FUNC(times)
        PSI_STRUCT(tms, [
                [tms_utime],
                [tms_stime],
@@ -454,6 +491,7 @@ if test "$PHP_PSI" != "no"; then
        PSI_TYPE(timer_t, int)
        PSI_TYPE(uid_t)
        dnl sys/utsname.h
+       PSI_FUNC(uname)
        PSI_STRUCT(utsname, [
                [sysname],
                [nodename],
@@ -498,6 +536,7 @@ if test "$PHP_PSI" != "no"; then
        ])
 
 
+       AC_DEFINE_UNQUOTED(PHP_PSI_FUNCS, $PSI_FUNCS, Redirected functions)
        AC_DEFINE_UNQUOTED(PHP_PSI_TYPES, $PSI_TYPES, Predefined types)
        AC_DEFINE_UNQUOTED(PHP_PSI_CONSTS, $PSI_CONSTS, Predefined constants)
        AC_DEFINE_UNQUOTED(PHP_PSI_STRUCTS, $PSI_STRUCTS, Predefined structs)
index 00126c7..7d353be 100644 (file)
@@ -57,6 +57,15 @@ static const psi_predef_struct psi_predef_structs[] = {
 };
 #define psi_predef_struct_count() psi_predef_count(_struct)
 
+typedef struct psi_predef_func {
+       const char *name;
+       void (*func)(void);
+} psi_predef_func;
+static psi_predef_func psi_predef_funcs[] = {
+       PHP_PSI_FUNCS{0}
+};
+#define psi_predef_func_count() psi_predef_count(_func)
+
 static int validate_lib(PSI_Data *data, void **dlopened) {
        char lib[MAXPATHLEN];
        const char *ptr = data->psi.file.ln;
@@ -230,8 +239,20 @@ static inline int validate_decl_func(PSI_Data *data, void *dl, decl *decl, decl_
 #endif
        decl->dlptr = dlsym(dl ?: RTLD_NEXT, func->var->name);
        if (!decl->dlptr) {
-               data->error(PSI_WARNING, "Failed to locate symbol '%s': %s",
-                       func->var->name, dlerror());
+               size_t i;
+
+               for (i = 0; i < psi_predef_func_count(); ++i) {
+                       psi_predef_func *pre = &psi_predef_funcs[i];
+
+                       if (!strcmp(func->var->name, pre->name)) {
+                               decl->dlptr = pre->func;
+                               break;
+                       }
+               }
+               if (!decl->dlptr) {
+                       data->error(PSI_WARNING, "Failed to locate symbol '%s': %s",
+                               func->var->name, dlerror());
+               }
        }
        return 1;
 }
@@ -271,6 +292,8 @@ static inline decl_arg *locate_struct_member(decl_struct *s, decl_var *var) {
 }
 static inline int validate_set_value(PSI_Data *data, set_value *set, decl_arg *ref) {
        size_t i;
+       decl_type *ref_type = real_decl_type(ref->type);
+       decl_var *set_var = set->vars->vars[0];
 
        switch (set->func->type) {
        case PSI_T_TO_BOOL:
@@ -291,22 +314,22 @@ static inline int validate_set_value(PSI_Data *data, set_value *set, decl_arg *r
        EMPTY_SWITCH_DEFAULT_CASE();
        }
 
-       if (strcmp(set->vars->vars[0]->name, ref->var->name)) {
+       if (strcmp(set_var->name, ref->var->name)) {
                return 0;
        }
 
-       if (set->count && (set->func->type != PSI_T_TO_ARRAY || real_decl_type(ref->type)->type != PSI_T_STRUCT)) {
+       if (set->count && (set->func->type != PSI_T_TO_ARRAY || ref_type->type != PSI_T_STRUCT)) {
                data->error(E_WARNING, "Inner `set` statement casts only work with to_array() casts on structs");
                return 0;
        }
        for (i = 0; i < set->count; ++i) {
-               decl_arg *sub_ref = locate_struct_member(real_decl_type(ref->type)->strct, set->inner[i]->vars->vars[0]);
+               decl_var *sub_var = set->inner[i]->vars->vars[0];
+               decl_arg *sub_ref = locate_struct_member(ref_type->strct, sub_var);
 
-               if (!sub_ref) {
-                       return 0;
-               }
-               if (!validate_set_value(data, set->inner[i], sub_ref)) {
-                       return 0;
+               if (sub_ref) {
+                       if (!validate_set_value(data, set->inner[i], sub_ref)) {
+                               return 0;
+                       }
                }
        }
 
index b8d2300..508fdea 100644 (file)
@@ -360,17 +360,20 @@ void psi_to_array(zval *return_value, token_t t, impl_val *ret_val, set_value *s
                                set_value *sub_set = set->inner[i];
                                decl_var *sub_var = sub_set->vars->vars[0];
                                decl_arg *sub_arg = sub_var->arg;
-                               token_t t = real_decl_type(sub_arg->type)->type;
-                               void *ptr = malloc(sub_arg->layout->len);
-
-                               memcpy(ptr, (char *) ret_val->ptr + sub_arg->layout->pos,
-                                               sub_arg->layout->len);
-                               tmp_ptr = enref_impl_val(ptr, sub_arg->var);
-                               sub_set->func->handler(&ztmp, t, tmp_ptr, sub_set, sub_var);
-                               add_assoc_zval(return_value, sub_var->name, &ztmp);
-                               free(tmp_ptr);
-                               if (tmp_ptr != ptr) {
-                                       free(ptr);
+
+                               if (sub_arg) {
+                                       token_t t = real_decl_type(sub_arg->type)->type;
+                                       void *ptr = malloc(sub_arg->layout->len);
+
+                                       memcpy(ptr, (char *) ret_val->ptr + sub_arg->layout->pos,
+                                                       sub_arg->layout->len);
+                                       tmp_ptr = enref_impl_val(ptr, sub_arg->var);
+                                       sub_set->func->handler(&ztmp, t, tmp_ptr, sub_set, sub_var);
+                                       add_assoc_zval(return_value, sub_var->name, &ztmp);
+                                       free(tmp_ptr);
+                                       if (tmp_ptr != ptr) {
+                                               free(ptr);
+                                       }
                                }
                        }
                }
index 3b4c77f..6dcd6bf 100644 (file)
@@ -356,7 +356,7 @@ static inline impl_val *enref_impl_val(void *ptr, decl_var *var) {
        impl_val *val, *val_ptr;
        unsigned i;
 
-       if (!var->pointer_level) {
+       if (!var->pointer_level && real_decl_type(var->arg->type)->type != PSI_T_STRUCT) {
                return ptr;
        }
        val = val_ptr = calloc(var->pointer_level, sizeof(void *));
index 0017565..e5d8eba 100644 (file)
@@ -1,8 +1,48 @@
-extern int __xstat64(int ver, char *path, struct stat *buf);
+extern int stat(char *path, struct stat *buf);
 function psi\stat(string $path, array &$buf = NULL) : int {
-       let ver = NULL;
        let path = strval($path);
        let buf = calloc(1, struct stat);
-       return to_int(__xstat64);
-       set $buf = to_array(*buf);
+       return to_int(stat);
+       set $buf = to_array(*buf,
+               to_int(st_dev),
+               to_int(st_ino),
+               to_int(st_mode),
+               to_int(st_nlink),
+               to_int(st_uid),
+               to_int(st_gid),
+               to_int(st_rdev),
+               to_int(st_size),
+               to_array(st_atim,
+                       to_int(tv_sec),
+                       to_int(tv_nsec)
+               ), 
+               to_array(st_atimespec,
+                       to_int(tv_sec),
+                       to_int(tv_nsec)
+               ),
+               to_array(st_mtim,
+                       to_int(tv_sec),
+                       to_int(tv_nsec)
+               ), 
+               to_array(st_mtimespec,
+                       to_int(tv_sec),
+                       to_int(tv_nsec)
+               ),
+               to_array(st_ctim,
+                       to_int(tv_sec),
+                       to_int(tv_nsec)
+               ), 
+               to_array(st_ctimespec,
+                       to_int(tv_sec),
+                       to_int(tv_nsec)
+               ),
+               to_array(st_birthtimespec,
+                       to_int(tv_sec),
+                       to_int(tv_nsec)
+               ),
+               to_int(st_blksize),
+               to_int(st_blocks),
+               to_int(st_flags),
+               to_int(st_gen)
+       );
 }