Refactoring CoreRuntime and plugin (#247)
[platform/core/dotnet/launcher.git] / NativeLauncher / util / log_manager.cc
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <pthread.h>
20
21 #include "log.h"
22 #include "log_manager.h"
23
24 static int __pfd[2];
25 static pthread_t __loggingThread;
26 static bool __isInit = false;
27
28 static void *stdlog(void*)
29 {
30         ssize_t readSize;
31         char buf[1024];
32
33         while ((readSize = read(__pfd[0], buf, sizeof buf - 1)) > 0) {
34                 if (buf[readSize - 1] == '\n') {
35                         --readSize;
36                 }
37
38                 buf[readSize] = 0;
39
40                 _LOGX("%s", buf);
41         }
42
43         close(__pfd[0]);
44         close(__pfd[1]);
45
46         return 0;
47 }
48
49 int initializeLogManager()
50 {
51         __isInit = true;
52
53         if (setvbuf(stdout, NULL, _IOLBF, 0) < 0) {
54                 _ERR("fail to make stdout line-buffered");
55                 return -1;
56         }
57
58         if (setvbuf(stderr, NULL, _IONBF, 0) < 0) {
59                 _ERR("make stderr unbuffered");
60                 return -1;
61         }
62
63         /* create the pipe and redirect stdout and stderr */
64         if (pipe(__pfd) < 0) {
65                 _ERR("fail to create pipe for logging");
66                 return -1;
67         }
68
69         /* redirect stdout and stderr */
70         if (redirectFD() < 0) {
71                 return -1;
72         }
73
74         /* spawn the logging thread */
75         if (pthread_create(&__loggingThread, 0, stdlog, 0) != 0) {
76                 _ERR("fail to create pthread");
77                 return -1;
78         }
79
80         if (pthread_detach(__loggingThread) != 0) {
81                 _ERR("fail to detach pthread");
82                 return -1;
83         }
84
85         return 0;
86 }
87
88 // launchpad override stdout and stderr to journalctl before launch application.
89 // So, even though fd redirection is done in initializeLogManager, we do it again before launch.
90 // if LogManager is not initialized, it will return 0;
91 int redirectFD()
92 {
93         if (!__isInit)
94                 return 0;
95
96         if (__pfd[1] < 0) {
97                 _ERR("fail to create pipe for logging");
98                 return -1;
99         }
100
101         // stdout
102         if (dup2(__pfd[1], 1) == -1) {
103                 _ERR("fail to duplicate fd to stdout");
104                 return -1;
105         }
106
107         // stderr
108         if (dup2(__pfd[1], 2) == -1) {
109                 _ERR("fail to duplicate fd to stderr");
110                 return -1;
111         }
112
113         return 0;
114 }