Merge branch 'tizen_2.4_merge' into tizen
[sdk/target/sdbd.git] / src / utils.c
1 /*
2  * Copyright (c) 2011 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 "utils.h"
18 #include <stdarg.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 #include <sys/wait.h>
25 #include <errno.h>
26
27 #define STRING_MAXLEN 1024
28 char*
29 buff_addc (char*  buff, char*  buffEnd, int  c)
30 {
31     int  avail = buffEnd - buff;
32
33     if (avail <= 0)  /* already in overflow mode */
34         return buff;
35
36     if (avail == 1) {  /* overflowing, the last byte is reserved for zero */
37         buff[0] = 0;
38         return buff + 1;
39     }
40
41     buff[0] = (char) c;  /* add char and terminating zero */
42     buff[1] = 0;
43     return buff + 1;
44 }
45
46 char*
47 buff_adds (char*  buff, char*  buffEnd, const char*  s)
48 {
49     int  slen = strlen(s);
50
51     return buff_addb(buff, buffEnd, s, slen);
52 }
53
54 char*
55 buff_addb (char*  buff, char*  buffEnd, const void*  data, int  len)
56 {
57     int  avail = (buffEnd - buff);
58
59     if (avail <= 0 || len <= 0)  /* already overflowing */
60         return buff;
61
62     if (len > avail)
63         len = avail;
64
65     memcpy(buff, data, len);
66
67     buff += len;
68
69     /* ensure there is a terminating zero */
70     if (buff >= buffEnd) {  /* overflow */
71         buff[-1] = 0;
72     } else
73         buff[0] = 0;
74
75     return buff;
76 }
77
78 char*
79 buff_add  (char*  buff, char*  buffEnd, const char*  format, ... )
80 {
81     int      avail;
82
83     avail = (buffEnd - buff);
84
85     if (avail > 0) {
86         va_list  args;
87         int      nn;
88
89         va_start(args, format);
90         nn = vsnprintf( buff, avail, format, args);
91         va_end(args);
92
93         if (nn < 0) {
94             /* some C libraries return -1 in case of overflow,
95              * but they will also do that if the format spec is
96              * invalid. We assume SDB is not buggy enough to
97              * trigger that last case. */
98             nn = avail;
99         }
100         else if (nn > avail) {
101             nn = avail;
102         }
103
104         buff += nn;
105
106         /* ensure that there is a terminating zero */
107         if (buff >= buffEnd)
108             buff[-1] = 0;
109         else
110             buff[0] = 0;
111     }
112     return buff;
113 }
114
115 char *str_trim(const char* string)
116 {
117     const char* s = string;
118     const char* e = string + (strlen(string) - 1);
119     char* ret;
120
121     while(*s == ' ' || *s == '\t') // ltrim
122         s++;
123     while(*e == ' ' || *e == '\t') // rtrim
124         e--;
125
126     ret = strdup(s);
127     if(ret == NULL) {
128         return NULL;
129     }
130     ret[e - s + 1] = 0;
131
132     return  ret;
133 }
134
135 int spawn(char* program, char** arg_list)
136 {
137     pid_t pid;
138     int ret;
139
140     if ((pid = fork()) < 0) {
141         fprintf(stderr, "couldn't fork: %d\n", errno);
142         exit(1);
143     } else if (pid == 0) {
144             if ((pid = fork()) < 0) {
145                 fprintf(stderr, "couldn't fork: %d\n", errno);
146                 exit(1);
147             } else if (pid > 0) {
148                 // init takes the process, and the process is not able to be zombie
149                 exit(0);
150             }
151             execvp (program, arg_list);
152             fprintf(stderr, "failed to spawn: never reach here!:%s\n", program);
153             exit(0);
154     }
155     if (waitpid(pid, &ret, 0) != pid) {
156         fprintf(stderr, "failed to wait pid\n");
157     }
158
159     return pid;
160 }
161
162 char** str_split(char* a_str, const char a_delim) {
163         char** result = 0;
164         size_t count = 0;
165         char* tmp = a_str;
166         char* last_comma = 0;
167         char delim[2];
168         delim[0] = a_delim;
169         delim[1] = 0;
170         char *ptr;
171
172         /* Count how many elements will be extracted. */
173         while (*tmp) {
174                 if (a_delim == *tmp) {
175                         count++;
176                         last_comma = tmp;
177                 }
178                 tmp++;
179         }
180
181         /* Add space for trailing token. */
182         count += last_comma < (a_str + strlen(a_str) - 1);
183
184         /* Add space for terminating null string so caller
185          knows where the list of returned strings ends. */
186         count++;
187
188         result = malloc(sizeof(char*) * count);
189
190         if (result) {
191                 size_t idx = 0;
192                 char* token = strtok_r(a_str, delim, &ptr);
193
194                 while (token) {
195                         //assert(idx < count);
196                         *(result + idx++) = strdup(token);
197                         token = strtok_r(0, delim, &ptr);
198                 }
199                 //assert(idx == count - 1);
200                 *(result + idx) = 0;
201         }
202
203         return result;
204 }
205