xref: /nrf52832-nimble/rt-thread/components/utilities/logtrace/log_file.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * Copyright (c) 2006-2018, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  *                Bernard      the first version
9  * 2013-06-26     Grissiom     refactor
10  */
11 #include <rtthread.h>
12 #include <log_trace.h>
13 
14 #ifdef RT_USING_DFS
15 
16 #include <dfs_posix.h>
17 
18 struct file_device
19 {
20     struct rt_device parent;
21 
22     int  fd;
23     char *filename;
24 };
25 
26 /* file device for log trace */
27 static struct file_device _file_device;
28 
29 /* common device interface */
fdevice_open(rt_device_t dev,rt_uint16_t oflag)30 static rt_err_t fdevice_open(rt_device_t dev, rt_uint16_t oflag)
31 {
32     int fd;
33     struct file_device *fdev = (struct file_device *)dev;
34 
35     if (fdev->fd >= 0)
36         return -RT_EBUSY;
37 
38     /* test and open */
39     fd = open(fdev->filename, O_RDONLY, 0);
40     if (fd >= 0)
41     {
42         close(fd);
43         fd = open(fdev->filename, O_WRONLY | O_APPEND, 0);
44     }
45     else
46     {
47         /* file not exists */
48         fd = open(fdev->filename, O_WRONLY | O_CREAT, 0);
49     }
50     fdev->fd = fd;
51 
52     return RT_EOK;
53 }
54 
fdevice_close(rt_device_t dev)55 static rt_err_t fdevice_close(rt_device_t dev)
56 {
57     rt_err_t result;
58     struct file_device *fdev = (struct file_device *)dev;
59 
60     if (fdev->fd < 0)
61         return -RT_EBUSY;
62 
63     result = close(fdev->fd);
64     if (result == 0)
65     {
66         fdev->fd = -1;
67     }
68 
69     return result;
70 }
71 
fdevice_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)72 static rt_size_t fdevice_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
73 {
74     struct file_device *fdev = (struct file_device *)dev;
75 
76     if (fdev->fd < 0)
77         return 0;
78 
79     return write(fdev->fd, buffer, size);
80 }
81 
fdevice_control(rt_device_t dev,int cmd,void * arg)82 static rt_err_t fdevice_control(rt_device_t dev, int cmd, void *arg)
83 {
84     struct file_device *fdev = (struct file_device *)dev;
85 
86     if (fdev->fd < 0)
87         return 0;
88 
89     switch (cmd)
90     {
91     case LOG_TRACE_CTRL_FLUSH:
92         if (fsync(fdev->fd) != 0)
93             return RT_ERROR;
94         break;
95     default:
96         break;
97     }
98     return RT_EOK;
99 }
100 
101 #ifdef RT_USING_DEVICE_OPS
102 const static struct rt_device_ops log_trace_ops =
103 {
104     RT_NULL,
105     fdevice_open,
106     fdevice_close,
107     RT_NULL,
108     fdevice_write,
109     fdevice_control
110 };
111 #endif
112 
log_trace_file_init(const char * filename)113 void log_trace_file_init(const char *filename)
114 {
115     rt_device_t device;
116 
117     device = rt_device_find("logfile");
118     if (device == RT_NULL)
119     {
120         rt_memset(&_file_device, 0x00, sizeof(_file_device));
121 
122         _file_device.parent.type  = RT_Device_Class_Char;
123 
124 #ifdef RT_USING_DEVICE_OPS
125         _file_device.parent.ops     = &log_trace_ops;
126 #else
127         _file_device.parent.init    = RT_NULL;
128         _file_device.parent.open    = fdevice_open;
129         _file_device.parent.close   = fdevice_close;
130         _file_device.parent.write   = fdevice_write;
131         _file_device.parent.control = fdevice_control;
132 #endif
133 
134         rt_device_register(&_file_device.parent, "logfile", O_RDWR);
135     }
136 
137     _file_device.filename = rt_strdup(filename);
138     _file_device.fd = -1;
139 }
140 
log_trace_set_file(const char * filename)141 void log_trace_set_file(const char *filename)
142 {
143     log_trace_file_init(filename);
144     log_trace_set_device("logfile");
145 }
146 #ifdef RT_USING_FINSH
147 #include <finsh.h>
148 FINSH_FUNCTION_EXPORT_ALIAS(log_trace_set_file, log_file, set output filename of log trace);
149 #endif
150 
151 #endif /* RT_USING_DFS */
152