diff options
| author | vvvv <[email protected]> | 2024-11-01 15:41:40 +0300 | 
|---|---|---|
| committer | vvvv <[email protected]> | 2024-11-01 15:55:52 +0300 | 
| commit | 3325f745e67f7f442790822b5c9c5e9996708be7 (patch) | |
| tree | f7318d68bbe8990092715436444b05297ce35777 /yql/essentials/utils/signals/utils.cpp | |
| parent | 6dce3f1c71786f2694b73b1a5155efc58f4557dd (diff) | |
Moved yql/utils YQL-19206
Также была выделена жирная зависимость из yql/utils в yql/utils/network, в результате library/cpp/getopt была добавлена явно в те проекты, которые ее ранее наследовали, а не указывали явно
commit_hash:36aa4c41f807b4cbbf70a3ed7ac0a1a5079bb75d
Diffstat (limited to 'yql/essentials/utils/signals/utils.cpp')
| -rw-r--r-- | yql/essentials/utils/signals/utils.cpp | 122 | 
1 files changed, 122 insertions, 0 deletions
| diff --git a/yql/essentials/utils/signals/utils.cpp b/yql/essentials/utils/signals/utils.cpp new file mode 100644 index 00000000000..b1de131b30f --- /dev/null +++ b/yql/essentials/utils/signals/utils.cpp @@ -0,0 +1,122 @@ +#include "utils.h" + +#include <util/generic/yexception.h> +#include <util/string/subst.h> + +#include <google/protobuf/text_format.h> + +#include <library/cpp/protobuf/json/proto2json.h> +#include <library/cpp/json/yson/json2yson.h> + +#include <string.h> + +extern char** environ; + +namespace NYql { + +static char** g_OriginalArgv = nullptr; +static char* g_OriginalArgvLast = nullptr; + +/* + * To change the process title in Linux and Darwin we have to set argv[1] + * to NULL and to copy the title to the same place where the argv[0] points to. + * However, argv[0] may be too small to hold a new title. Fortunately, Linux + * and Darwin store argv[] and environ[] one after another. So we should + * ensure that is the continuous memory and then we allocate the new memory + * for environ[] and copy it. After this we could use the memory starting + * from argv[0] for our process title. + * + *               continuous memory block for process title + *  ________________________________/\____________________________________ + * /                                                                      \ + * +---------+---------+-----+------+------------+------------+-----+------+ + * | argv[0] | argv[1] | ... | NULL | environ[0] | environ[1] | ... | NULL | + * +---------+---------+-----+------+------------+------------+-----+------+ + *                                   \_________________  _________________/ + *                                                     \/ + *                                         must be relocated elsewhere + */ +void ProcTitleInit(int argc, const char* argv[]) +{ +    Y_UNUSED(argc); +    Y_ABORT_UNLESS(!g_OriginalArgv, "ProcTitleInit() was already called"); + +    g_OriginalArgv = const_cast<char**>(argv); + +    size_t size = 0; +    for (int i = 0; environ[i]; i++) { +        size += strlen(environ[i]) + 1; +    } + +    char* newEnviron = new char[size]; +    g_OriginalArgvLast = g_OriginalArgv[0]; + +    for (int i = 0; g_OriginalArgv[i]; i++) { +        if (g_OriginalArgvLast == g_OriginalArgv[i]) { +            g_OriginalArgvLast = g_OriginalArgv[i] + strlen(g_OriginalArgv[i]) + 1; +        } +    } + +    for (int i = 0; environ[i]; i++) { +        if (g_OriginalArgvLast == environ[i]) { +            size_t size = strlen(environ[i]) + 1; +            g_OriginalArgvLast = environ[i] + size; + +            strncpy(newEnviron, environ[i], size); +            environ[i] = newEnviron; +            newEnviron += size; +        } +    } + +    g_OriginalArgvLast--; +} + +void SetProcTitle(const char* title) +{ +    if (!g_OriginalArgv) return; + +    char* p = g_OriginalArgv[0]; +    p += strlcpy(p, "yqlworker: ", g_OriginalArgvLast - p); +    p += strlcpy(p, title, g_OriginalArgvLast - p); + +    if (g_OriginalArgvLast - p > 0) { +        memset(p, 0, g_OriginalArgvLast - p); +    } + +    g_OriginalArgv[1] = nullptr; +} + +void AddProcTitleSuffix(const char* suffix) +{ +    if (!g_OriginalArgv) return; + +    char* p = g_OriginalArgv[0]; +    p += strlcat(p, " ", g_OriginalArgvLast - p); +    p += strlcat(p, suffix, g_OriginalArgvLast - p); +} + +const char* GetProcTitle() +{ +    return g_OriginalArgv ? g_OriginalArgv[0] : "UNKNOWN"; +} + +TString PbMessageToStr(const google::protobuf::Message& msg) +{ +    TString str; +    ::google::protobuf::TextFormat::Printer printer; +    printer.SetSingleLineMode(true); +    printer.PrintToString(msg, &str); +    return str; +} + +TString Proto2Yson(const google::protobuf::Message& proto) { +    NJson::TJsonValue json; +    NProtobufJson::Proto2Json(proto, json); + +    TString ysonResult; +    TStringOutput stream(ysonResult); +    NJson2Yson::SerializeJsonValueAsYson(json, &stream); +    return ysonResult; +} + +} // namespace NYql | 
