/** Composes the name of an input file, based on target Takes a data directory and an executable name, and tries to open an input file based on these variables. If a file is found in neither of two locattions derived from these variables, this method tries to fall back on /dev/null. Source file locations: - [data_dir]/manual/in/[target].in - [data_dir]/tutorial/in/[target].in - /dev/null @param data_dir the path of the reference data directory @param target the name of executable being run @returns the name of the file */ char* input_name (const char* data_dir, const char* target) { char* fname = 0; int stat_result = 0; struct stat sb; assert (0 != target); if (data_dir && *data_dir) { /* Try data_dir/manual/in/target.in */ fname = reference_name (data_dir, "manual", "in"); stat_result = stat (fname, &sb); if (0 == stat_result) return fname; free (fname); /* Try data_dir/tutorial/in/target.in */ fname = reference_name (data_dir, "tutorial", "in"); stat_result = stat (fname, &sb); if (0 == stat_result) return fname; free (fname); } /* If we didn't find a source file, use /dev/null */ fname = (char*)RW_MALLOC (sizeof DEV_NULL); strcpy (fname, DEV_NULL); return fname; }
char* output_name (const char* target) { const char* suffix = "out"; const size_t sfx_len = strlen (suffix); const size_t exe_len = strlen (target) - exe_suffix_len; char* const tmp_name = (char*)RW_MALLOC (exe_len + sfx_len + 2); memcpy (tmp_name, target, exe_len); *(tmp_name + exe_len) = suffix_sep; memcpy (tmp_name + exe_len + 1, suffix, sfx_len + 1); return tmp_name; }
char* reference_name (const char* data_dir, const char* subdir, const char* mode) { size_t root_len, cmp_len, dir_len, mode_len, net_len; char* ref_name; char* tail; const char* const target_name = get_target (); assert (0 != target_name); assert (0 != subdir); assert (0 != mode); root_len = data_dir ? strlen (data_dir) : 0; cmp_len = strlen (target_name) - exe_suffix_len; dir_len = strlen (subdir); mode_len = strlen (mode); net_len = root_len + cmp_len + dir_len + mode_len * 2 + 5; /* 5 comes from 3 path seperator characters, the suffix seperator character, and the trailing null */ tail = ref_name = (char*)RW_MALLOC (net_len); memcpy (tail, data_dir, root_len); tail += root_len; *tail++ = default_path_sep; memcpy (tail , subdir, dir_len); tail += dir_len; *tail++ = default_path_sep; memcpy (tail , mode, mode_len); tail += mode_len; *tail++ = default_path_sep; memcpy (tail , target_name, cmp_len); tail += cmp_len; *tail++ = suffix_sep; memcpy (tail , mode, mode_len); tail += mode_len; *tail = '\0'; return ref_name; }
/** Helper function to parse a ulimit value string @param opts ulimit value string to pares @see child_limits */ static bool parse_limit_opts (const char* opts, struct target_opts* defaults) { static const struct { rw_rlimit** limit; const char* name; const char* caps; const char* mixd; size_t len; } limits[] = { { #ifdef RLIMIT_CORE &defaults->core, #else 0, #endif /* RLIMIT_CORE */ "core", "CORE", "Core", 4 }, { #ifdef RLIMIT_CPU &defaults->cpu, #else 0, #endif /* RLIMIT_CPU */ "cpu", "CPU", "Cpu", 3 }, { #ifdef RLIMIT_DATA &defaults->data, #else 0, #endif /* RLIMIT_DATA */ "data", "DATA", "Data", 4 }, { #ifdef RLIMIT_FSIZE &defaults->fsize, #else 0, #endif /* RLIMIT_FSIZE */ "fsize", "FSIZE", "Fsize", 5 }, { #ifdef RLIMIT_NOFILE &defaults->nofile, #else 0, #endif /* RLIMIT_NOFILE */ "nofile", "NOFILE", "Nofile", 6 }, { #ifdef RLIMIT_STACK &defaults->stack, #else 0, #endif /* RLIMIT_STACK */ "stack", "STACK", "Stack", 5 }, { #ifdef RLIMIT_AS &defaults->as, #else 0, #endif /* RLIMIT_AS */ "as", "AS", "As", 2 }, { 0, 0, 0, 0, 0 } }; const char* arg = opts; assert (0 != opts); while (arg && *arg) { const size_t arglen = strlen (arg); for (size_t i = 0; limits [i].name; ++i) { if ( limits [i].len < arglen && ( 0 == memcmp (limits [i].name, arg, limits [i].len) || 0 == memcmp (limits [i].caps, arg, limits [i].len) || 0 == memcmp (limits [i].mixd, arg, limits [i].len)) && ':' == arg [limits [i].len]) { /* determine whether the hard limit and/or the soft limit should be set. */ const bool hard = 0 != isupper (arg [0]); const bool soft = 0 != islower (arg [1]); arg += limits [i].len + 1; if (!isdigit (*arg)) { return 1; } char *end; const long lim = strtol (arg, &end, 10); arg = end; if ('\0' != *arg && ',' != *arg) break; if (limits [i].limit) { if (!*limits [i].limit) { (*limits [i].limit) = (rw_rlimit*)RW_MALLOC (sizeof (rw_rlimit)); (*limits [i].limit)->rlim_cur = RLIM_SAVED_CUR; (*limits [i].limit)->rlim_max = RLIM_SAVED_MAX; } if (soft) (*limits [i].limit)->rlim_cur = lim; if (hard) (*limits [i].limit)->rlim_max = lim; } else warn ("Unable to process %s limit: Not supported\n", limits [i].name); break; } } if (',' == *arg) { ++arg; } else if ('\0' != *arg) { return 1; } } return 0; }
// This will be supported after sharding support // //LCOV_EXCL_START rw_status_t rwdts_kv_update_db_xact_precommit(rwdts_member_data_object_t *mobj, RWDtsQueryAction action) { rwdts_api_t *apih; rwdts_member_registration_t *reg; ProtobufCMessage *msg; uint8_t *payload; size_t payload_len; rw_status_t status; rwdts_kv_table_handle_t *kv_tab_handle = NULL; rwdts_shard_info_detail_t *shard_key1; uint8_t *local_ks_binpath = NULL; size_t local_ks_binpath_len; rw_keyspec_path_t *local_keyspec = NULL; /* Build the shard-key to get the shard-id and DB number */ char str[15] = "banana"; reg = mobj->reg; RW_ASSERT_TYPE(reg, rwdts_member_registration_t); apih = reg->apih; RW_ASSERT(apih); RW_ASSERT(action != RWDTS_QUERY_INVALID); msg = mobj->msg; shard_key1 = RW_MALLOC0_TYPE(sizeof(rwdts_shard_info_detail_t), rwdts_shard_info_detail_t); shard_key1->shard_key_detail.u.byte_key.k.key = (void *)RW_MALLOC(sizeof(str)); memcpy((char *)shard_key1->shard_key_detail.u.byte_key.k.key, &str[0], strlen(str)); shard_key1->shard_key_detail.u.byte_key.k.key_len = strlen(str); /* Get the shard-id and DB number */ rwdts_shard_db_num_info_t *shard_db_num_info = RW_MALLOC0(sizeof(rwdts_shard_db_num_info_t)); status = rw_keyspec_path_create_dup(reg->keyspec, &apih->ksi , &local_keyspec); RW_ASSERT(status == RW_STATUS_SUCCESS); status = rw_keyspec_path_get_binpath(local_keyspec, &apih->ksi , (const uint8_t **)&local_ks_binpath, &local_ks_binpath_len); RW_ASSERT(status == RW_STATUS_SUCCESS); rwdts_member_get_shard_db_info_keyspec(apih, local_keyspec, shard_key1, shard_db_num_info); if (shard_db_num_info->shard_db_num_cnt > 0) { mobj->db_number = shard_db_num_info->shard_db_num[0].db_number; mobj->shard_id = shard_db_num_info->shard_db_num[0].shard_chunk_id; /* Search for KV table handle */ status = RW_SKLIST_LOOKUP_BY_KEY(&(apih->kv_table_handle_list), &mobj->db_number, (void *)&kv_tab_handle); if (!kv_tab_handle) { kv_tab_handle = rwdts_kv_light_register_table(apih->handle, mobj->db_number); RW_ASSERT(kv_tab_handle); status = RW_SKLIST_INSERT(&(apih->kv_table_handle_list), kv_tab_handle); RW_ASSERT(status == RW_STATUS_SUCCESS); } mobj->kv_tab_handle = kv_tab_handle; RWDTS_CREATE_SHARD(reg->reg_id, apih->client_path, apih->router_path); /* Perform KV xact operation */ if (apih->db_up && ((action == RWDTS_QUERY_CREATE) || (RWDTS_QUERY_UPDATE == action))) { RW_ASSERT(msg); payload = protobuf_c_message_serialize(NULL, msg, &payload_len); rwdts_kv_light_table_xact_insert(kv_tab_handle, 0, shard, (void *)mobj->key, mobj->key_len, payload, payload_len, (void *)rwdts_kv_light_insert_xact_obj_cb, (void *)mobj); } else if (apih->db_up && (action == RWDTS_QUERY_DELETE)) { rwdts_kv_light_table_xact_delete(kv_tab_handle, 0, (void *)mobj->key, mobj->key_len, (void *)rwdts_kv_light_delete_xact_obj_cb, (void *)mobj); } } if (shard_db_num_info->shard_db_num_cnt) { free(shard_db_num_info->shard_db_num); } RW_FREE(shard_db_num_info); rw_keyspec_path_free(local_keyspec, NULL); RW_FREE(shard_key1->shard_key_detail.u.byte_key.k.key); RW_FREE_TYPE(shard_key1, rwdts_shard_info_detail_t); return RW_STATUS_SUCCESS; }