| 1512 | } |
| 1513 | |
| 1514 | void evalGenericCommand(client *c, int evalsha) { |
| 1515 | lua_State *lua = server.lua; |
| 1516 | char funcname[43]; |
| 1517 | long long numkeys; |
| 1518 | long long initial_server_dirty = server.dirty; |
| 1519 | int delhook = 0, err; |
| 1520 | |
| 1521 | /* When we replicate whole scripts, we want the same PRNG sequence at |
| 1522 | * every call so that our PRNG is not affected by external state. */ |
| 1523 | redisSrand48(0); |
| 1524 | |
| 1525 | /* We set this flag to zero to remember that so far no random command |
| 1526 | * was called. This way we can allow the user to call commands like |
| 1527 | * SRANDMEMBER or RANDOMKEY from Lua scripts as far as no write command |
| 1528 | * is called (otherwise the replication and AOF would end with non |
| 1529 | * deterministic sequences). |
| 1530 | * |
| 1531 | * Thanks to this flag we'll raise an error every time a write command |
| 1532 | * is called after a random command was used. */ |
| 1533 | server.lua_random_dirty = 0; |
| 1534 | server.lua_write_dirty = 0; |
| 1535 | server.lua_replicate_commands = server.lua_always_replicate_commands; |
| 1536 | server.lua_multi_emitted = 0; |
| 1537 | server.lua_repl = PROPAGATE_AOF|PROPAGATE_REPL; |
| 1538 | |
| 1539 | /* Get the number of arguments that are keys */ |
| 1540 | if (getLongLongFromObjectOrReply(c,c->argv[2],&numkeys,NULL) != C_OK) |
| 1541 | return; |
| 1542 | if (numkeys > (c->argc - 3)) { |
| 1543 | addReplyError(c,"Number of keys can't be greater than number of args"); |
| 1544 | return; |
| 1545 | } else if (numkeys < 0) { |
| 1546 | addReplyError(c,"Number of keys can't be negative"); |
| 1547 | return; |
| 1548 | } |
| 1549 | |
| 1550 | /* We obtain the script SHA1, then check if this function is already |
| 1551 | * defined into the Lua state */ |
| 1552 | funcname[0] = 'f'; |
| 1553 | funcname[1] = '_'; |
| 1554 | if (!evalsha) { |
| 1555 | /* Hash the code if this is an EVAL call */ |
| 1556 | sha1hex(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr)); |
| 1557 | } else { |
| 1558 | /* We already have the SHA if it is an EVALSHA */ |
| 1559 | int j; |
| 1560 | char *sha = c->argv[1]->ptr; |
| 1561 | |
| 1562 | /* Convert to lowercase. We don't use tolower since the function |
| 1563 | * managed to always show up in the profiler output consuming |
| 1564 | * a non trivial amount of time. */ |
| 1565 | for (j = 0; j < 40; j++) |
| 1566 | funcname[j+2] = (sha[j] >= 'A' && sha[j] <= 'Z') ? |
| 1567 | sha[j]+('a'-'A') : sha[j]; |
| 1568 | funcname[42] = '\0'; |
| 1569 | } |
| 1570 | |
| 1571 | /* Push the pcall error handler function on the stack. */ |
no test coverage detected