struct expression * convert_args(struct stack *mimic_stack, unsigned long nr_args, struct vm_method *method) { struct expression *args_list = NULL; unsigned long nr_total_args; unsigned long i; nr_total_args = nr_args; if (vm_method_is_jni(method)) { if (vm_method_is_static(method)) nr_total_args++; nr_total_args++; } if (nr_total_args == 0) { args_list = no_args_expr(); goto out; } /* * We scan the args map in reverse order, since the order of arguments * is already reversed. */ for (i = 0; i < nr_args; i++) { struct expression *expr = stack_pop(mimic_stack); if (vm_type_is_pair(expr->vm_type)) i++; if (i >= nr_args) break; args_list = insert_arg(args_list, expr, method, nr_total_args - i - 1); } if (vm_method_is_jni(method)) { struct expression *expr; if (vm_method_is_static(method)) { expr = value_expr(J_REFERENCE, (unsigned long) method->class->object); if (!expr) goto error; args_list = insert_arg(args_list, expr, method, 1); } /* * JNI methods also need a pointer to JNI environment. That's * done in jni_trampoline automagically which is why we never * use method index zero here for JNI methods. */ } out: return args_list; error: expr_put(args_list); return NULL; }
struct expression *convert_args(struct stack *mimic_stack, unsigned long nr_args, struct vm_method *method) { struct expression *args_list = NULL; unsigned long i; if (nr_args == 0) { args_list = no_args_expr(); goto out; } /* * We scan the args map in reverse order, * since the order of arguments is already reversed. */ for (i = 0; i < nr_args; i++) { struct expression *expr = stack_pop(mimic_stack); args_list = insert_arg(args_list, expr, method, nr_args - i - 1); } out: return args_list; }
void possible_command::insert_args(string s) { const char *p = s.contents(); const char *end = p + s.length(); int l = 0; if (p >= end) return; // find the total number of arguments in our string do { l++; p = strchr(p, '\0') + 1; } while (p < end); // now insert each argument preserving the order for (int i = l - 1; i >= 0; i--) { p = s.contents(); for (int j = 0; j < i; j++) p = strchr(p, '\0') + 1; insert_arg(p); } }
/* Read a single string from the output, escape characters and quotes, insert $ args */ int read_string(const char **pin, char **pout, int sargc, char **sargv) { int in_quote = 0; const char *in = *pin; char *out = *pout; int len = 0; int error = 0; while(isspace(*in)) { in++; } if(*in == 0) { *pin = in; return 0; } while((*in != 0) && (error == 0)) { /* Escape character */ if(*in == '\\') { if(in_quote == '\'') { *out++ = *in++; if(*in) { *out++ = *in++; } } else { /* Skip the escape */ in++; switch(*in) { case 'n': *out++ = 10; in++; break; case 'r': *out++ = 13; in++; break; case '0': /* Octal */ { int i; unsigned char ch; in++; i = decode_oct(in, &ch); if((i == 0) || (i == 1)) { error = 1; break; } in += i; *out++ = ch; } break; case 'x': /* Hexadecimal */ { int i; unsigned char ch; in++; i = decode_hex(in, &ch); if((i == 0) || (i == 1)) { error = 1; break; } in += i; *out++ = ch; } break; case 0 : break; /* End of string */ default : *out++ = *in++; break; }; } } else { if((isspace(*in)) && (in_quote == 0)) { while(isspace(*in)) { in++; } break; } else if((*in == '>') && (in_quote == 0)) { break; } else if((*in == '"') || (*in == '\'')) { if(in_quote) { if(*in == in_quote) { in_quote = 0; in++; } else { *out++ = *in++; } } else { in_quote = *in; in++; } } else { if((*in == '$') && (in_quote != '\'')) { in++; insert_arg(&in, &out, sargc, sargv); } else { *out++ = *in++; } } } } if(in_quote) { printf("Missing matching quote %c\n", in_quote); } else if(error) { printf("Error in command line\n"); } else { *out++ = 0; len = out - *pout; } *pin = in; *pout = out; return len; }
/*===========================================================================* * patch_stack * *===========================================================================*/ static int patch_stack( struct vnode *vp, /* pointer for open script file */ char stack[ARG_MAX], /* pointer to stack image within VFS */ vir_bytes *stk_bytes /* size of initial stack */ ) { /* Patch the argument vector to include the path name of the script to be * interpreted, and all strings on the #! line. Returns the path name of * the interpreter. */ enum { INSERT=FALSE, REPLACE=TRUE }; int n, r; off_t pos; char *sp, *interp = NULL; u64_t new_pos; unsigned int cum_io; char buf[_MAX_BLOCK_SIZE]; /* Make user_fullpath the new argv[0]. */ if (!insert_arg(stack, stk_bytes, user_fullpath, REPLACE)) { printf("VFS: patch_stack: insert_arg for argv[0] failed\n"); return(ENOMEM); } pos = 0; /* Read from the start of the file */ /* Issue request */ r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, cvul64(pos), READING, VFS_PROC_NR, buf, _MAX_BLOCK_SIZE, &new_pos, &cum_io); if (r != OK) return(r); n = vp->v_size; if (n > _MAX_BLOCK_SIZE) n = _MAX_BLOCK_SIZE; if (n < 2) return ENOEXEC; sp = &(buf[2]); /* just behind the #! */ n -= 2; if (n > PATH_MAX) n = PATH_MAX; /* Use the user_fullpath variable for temporary storage */ memcpy(user_fullpath, sp, n); if ((sp = memchr(user_fullpath, '\n', n)) == NULL) /* must be a proper line */ return(ENOEXEC); /* Move sp backwards through script[], prepending each string to stack. */ for (;;) { /* skip spaces behind argument. */ while (sp > user_fullpath && (*--sp == ' ' || *sp == '\t')) {} if (sp == user_fullpath) break; sp[1] = 0; /* Move to the start of the argument. */ while (sp > user_fullpath && sp[-1] != ' ' && sp[-1] != '\t') --sp; interp = sp; if (!insert_arg(stack, stk_bytes, sp, INSERT)) { printf("VFS: patch_stack: insert_arg failed\n"); return(ENOMEM); } } if(!interp) return ENOEXEC; /* Round *stk_bytes up to the size of a pointer for alignment contraints. */ *stk_bytes= ((*stk_bytes + PTRSIZE - 1) / PTRSIZE) * PTRSIZE; if (interp != user_fullpath) memmove(user_fullpath, interp, strlen(interp)+1); return(OK); }