static int str_unpack (lua_State *L) { Header h; const char *fmt = luaL_checkstring(L, 1); size_t ld; const char *data = luaL_checklstring(L, 2, &ld); size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1; int n = 0; /* number of results */ luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); initheader(L, &h); while (*fmt != '\0') { int size, ntoalign; KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2, "data string too short"); pos += ntoalign; /* skip alignment */ /* stack space for item + next position */ luaL_checkstack(L, 2, "too many results"); n++; switch (opt) { case Kint: case Kuint: { lua_Integer res = unpackint(L, data + pos, h.islittle, size, (opt == Kint)); lua_pushinteger(L, res); break; } case Kfloat: { volatile Ftypes u; lua_Number num; copywithendian(u.buff, data + pos, size, h.islittle); if (size == sizeof(u.f)) num = (lua_Number)u.f; else if (size == sizeof(u.d)) num = (lua_Number)u.d; else num = u.n; lua_pushnumber(L, num); break; } case Kchar: { lua_pushlstring(L, data + pos, size); break; } case Kstring: { size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short"); lua_pushlstring(L, data + pos + size, len); pos += len; /* skip string */ break; } case Kzstr: { size_t len = (int)strlen(data + pos); luaL_argcheck(L, pos + len < ld, 2, "unfinished string for format 'z'"); lua_pushlstring(L, data + pos, len); pos += len + 1; /* skip string plus final '\0' */ break; } case Kpaddalign: case Kpadding: case Knop: n--; /* undo increment */ break; } pos += size; } lua_pushinteger(L, pos + 1); /* next position */ return n + 1; }
/****** gdi/request_internal/sge_gdi_packet_unpack() ************************* * NAME * sge_gdi_packet_unpack() -- unpacks a GDI packet * * SYNOPSIS * bool * sge_gdi_packet_unpack(sge_gdi_packet_class_t **packet, * lList **answer_list, sge_pack_buffer *pb) * * FUNCTION * This functions unpacks all data representing a single or multi * GDI request. The information is parsed from the given packing * buffer "pb" and ist stored into "packet". Necessary memory will * be allocated. * * INPUTS * sge_gdi_packet_class_t ** packet - new GDI packet * lList **answer_list - answer_list * sge_pack_buffer *pb - packing buffer * * RESULT * bool - error state * true - success * false - error * * NOTES * MT-NOTE: sge_gdi_packet_unpack() is MT safe * * SEE ALSO * gdi/request_internal/sge_gdi_packet_get_pb_size() * gdi/request_internal/sge_gdi_packet_pack_task() * gdi/request_internal/sge_gdi_packet_pack() *******************************************************************************/ bool sge_gdi_packet_unpack(sge_gdi_packet_class_t **packet, lList **answer_list, sge_pack_buffer *pb) { bool aret = true; bool has_next; int pack_ret; DENTER(TOP_LAYER, "sge_gdi_packet_unpack"); *packet = sge_gdi_packet_create_base(answer_list); if (*packet != NULL) { bool first = true; do { u_long32 target = 0; u_long32 command = 0; lList *data_list = NULL; u_long32 version = 0; lList *a_list = NULL; lCondition *condition = NULL; lEnumeration *enumeration = NULL; char *auth_info = NULL; u_long32 task_id = 0; u_long32 packet_id = 0; u_long32 has_next_int = 0; if ((pack_ret = unpackint(pb, &(command)))) { goto error_with_mapping; } if ((pack_ret = unpackint(pb, &(target)))) { goto error_with_mapping; } if ((pack_ret = unpackint(pb, &(version)))) { goto error_with_mapping; } /* JG: TODO (322): At this point we should check the version! ** The existent check function sge_gdi_packet_verify_version ** cannot be called as neccesary data structures are ** available here (e.g. answer list). ** Better do these changes at a more general place ** together with (hopefully coming) further communication ** redesign. */ if ((pack_ret = cull_unpack_list(pb, &(data_list)))) { goto error_with_mapping; } if ((pack_ret = cull_unpack_list(pb, &(a_list)))) { goto error_with_mapping; } if ((pack_ret = cull_unpack_cond(pb, &(condition)))) { goto error_with_mapping; } if ((pack_ret = cull_unpack_enum(pb, &(enumeration)))) { goto error_with_mapping; } if ((pack_ret = unpackstr(pb, &(auth_info)))) { goto error_with_mapping; } if ((pack_ret = unpackint(pb, &(task_id)))) { goto error_with_mapping; } if ((pack_ret = unpackint(pb, &(packet_id)))) { goto error_with_mapping; } if ((pack_ret = unpackint(pb, &has_next_int))) { goto error_with_mapping; } has_next = (has_next_int > 0) ? true : false; if (first) { (*packet)->id = packet_id; (*packet)->version = version; (*packet)->auth_info = auth_info; auth_info = NULL; first = false; } else { auth_info = (char *) sge_free((char *) auth_info); } /* EB: TODO: ST: cleanup - set last parameter to true */ aret = sge_gdi_packet_append_task(*packet, &a_list, target, command, &data_list, &a_list, &condition, &enumeration, false, false); if (aret == false) { goto error; } } while (has_next); } DRETURN(aret); error_with_mapping: aret = sge_gdi_map_pack_errors(pack_ret, answer_list); error: sge_gdi_packet_free(packet); DRETURN(aret); }
/* return 0 reaped a task cleanly 1 no message (asynchronuous mode) -1 got an error NOTES MT-NOTE: rcv_from_execd() is not MT safe */ static int rcv_from_execd(sge_gdi_ctx_class_t *ctx, int options, int tag) { int ret; char *msg = NULL; u_long32 msg_len = 0; sge_pack_buffer pb; u_short from_id; char host[1024]; lListElem *rt_rcv; u_long32 exit_status=0; sge_tid_t tid = NULL; DENTER(TOP_LAYER, "rcv_from_execd"); host[0] = '\0'; from_id = 1; do { /* FIX_CONST */ ret = gdi2_receive_message(ctx, (char*)prognames[EXECD], &from_id, host, &tag, &msg, &msg_len, (options & OPT_SYNCHRON) ? 1:0); if (ret != CL_RETVAL_OK && ret != CL_RETVAL_SYNC_RECEIVE_TIMEOUT) { sprintf(lasterror, MSG_GDI_MESSAGERECEIVEFAILED_SI , cl_get_error_text(ret), ret); DEXIT; return -1; } } while (options&OPT_SYNCHRON && ret == CL_RETVAL_SYNC_RECEIVE_TIMEOUT); if (ret==CL_RETVAL_SYNC_RECEIVE_TIMEOUT) { DEXIT; return 1; } ret = init_packbuffer_from_buffer(&pb, msg, msg_len); if(ret != PACK_SUCCESS) { sprintf(lasterror, MSG_GDI_ERRORUNPACKINGGDIREQUEST_S, cull_pack_strerror(ret)); DEXIT; return -1; } switch (tag) { case TAG_TASK_EXIT: unpackstr(&pb, &tid); unpackint(&pb, &exit_status); break; case TAG_JOB_EXECUTION: unpackstr(&pb, &tid); break; default: break; } clear_packbuffer(&pb); switch (tag) { case TAG_TASK_EXIT: /* change state in exited task */ if (!(rt_rcv = lGetElemStr(remote_task_list, RT_tid, tid))) { sprintf(lasterror, MSG_GDI_TASKNOTFOUND_S, tid); sge_free(&tid); DEXIT; return -1; } lSetUlong(rt_rcv, RT_status, exit_status); lSetUlong(rt_rcv, RT_state, RT_STATE_EXITED); break; case TAG_JOB_EXECUTION: /* search task without taskid */ if (!(rt_rcv = lGetElemStr(remote_task_list, RT_tid, "none"))) { sprintf(lasterror, MSG_GDI_TASKNOTFOUNDNOIDGIVEN_S , tid); DEXIT; return -1; } lSetString(rt_rcv, RT_tid, tid); break; default: break; } sge_free(&tid); DEXIT; return 0; }