]>
code.delx.au - pulseaudio/blob - src/polyp/util.c
4 This file is part of polypaudio.
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
38 #include <sys/types.h>
58 #include <polyp/xmalloc.h>
59 #include <polypcore/log.h>
60 #include <polypcore/util.h>
70 /* Return the current username in the specified string buffer. */
71 char *pa_get_user_name(char *s
, size_t l
) {
81 if (!(p
= getenv("USER")) && !(p
= getenv("LOGNAME")) && !(p
= getenv("USERNAME"))) {
84 #ifdef HAVE_GETPWUID_R
85 if (getpwuid_r(getuid(), &pw
, buf
, sizeof(buf
), &r
) != 0 || !r
) {
87 /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X)
88 * that do not support getpwuid_r. */
89 if ((r
= getpwuid(getuid())) == NULL
) {
91 snprintf(s
, l
, "%lu", (unsigned long) getuid());
97 #elif defined(OS_IS_WIN32) /* HAVE_PWD_H */
98 DWORD size
= sizeof(buf
);
100 if (!GetUserName(buf
, &size
))
105 #else /* HAVE_PWD_H */
107 #endif /* HAVE_PWD_H */
110 return pa_strlcpy(s
, p
, l
);
113 /* Return the current hostname in the specified buffer. */
114 char *pa_get_host_name(char *s
, size_t l
) {
116 if (gethostname(s
, l
) < 0) {
117 pa_log(__FILE__
": gethostname(): %s", strerror(errno
));
124 /* Return the home directory of the current user */
125 char *pa_get_home_dir(char *s
, size_t l
) {
130 struct passwd pw
, *r
;
135 if ((e
= getenv("HOME")))
136 return pa_strlcpy(s
, e
, l
);
138 if ((e
= getenv("USERPROFILE")))
139 return pa_strlcpy(s
, e
, l
);
142 #ifdef HAVE_GETPWUID_R
143 if (getpwuid_r(getuid(), &pw
, buf
, sizeof(buf
), &r
) != 0 || !r
) {
144 pa_log(__FILE__
": getpwuid_r() failed");
146 /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X)
147 * that do not support getpwuid_r. */
148 if ((r
= getpwuid(getuid())) == NULL
) {
149 pa_log(__FILE__
": getpwuid_r() failed");
154 return pa_strlcpy(s
, r
->pw_dir
, l
);
155 #else /* HAVE_PWD_H */
160 struct timeval
*pa_gettimeofday(struct timeval
*tv
) {
161 #ifdef HAVE_GETTIMEOFDAY
164 return gettimeofday(tv
, NULL
) < 0 ? NULL
: tv
;
165 #elif defined(OS_IS_WIN32)
167 * Copied from implementation by Steven Edwards (LGPL).
168 * Found on wine mailing list.
171 #if defined(_MSC_VER) || defined(__BORLANDC__)
172 #define EPOCHFILETIME (116444736000000000i64)
174 #define EPOCHFILETIME (116444736000000000LL)
183 GetSystemTimeAsFileTime(&ft
);
184 li
.LowPart
= ft
.dwLowDateTime
;
185 li
.HighPart
= ft
.dwHighDateTime
;
186 t
= li
.QuadPart
; /* In 100-nanosecond intervals */
187 t
-= EPOCHFILETIME
; /* Offset to the Epoch time */
188 t
/= 10; /* In microseconds */
189 tv
->tv_sec
= (long)(t
/ 1000000);
190 tv
->tv_usec
= (long)(t
% 1000000);
194 #error "Platform lacks gettimeofday() or equivalent function."
198 /* Calculate the difference between the two specfified timeval
200 pa_usec_t
pa_timeval_diff(const struct timeval
*a
, const struct timeval
*b
) {
204 /* Check which whan is the earlier time and swap the two arguments if reuqired. */
205 if (pa_timeval_cmp(a
, b
) < 0) {
206 const struct timeval
*c
;
212 /* Calculate the second difference*/
213 r
= ((pa_usec_t
) a
->tv_sec
- b
->tv_sec
)* 1000000;
215 /* Calculate the microsecond difference */
216 if (a
->tv_usec
> b
->tv_usec
)
217 r
+= ((pa_usec_t
) a
->tv_usec
- b
->tv_usec
);
218 else if (a
->tv_usec
< b
->tv_usec
)
219 r
-= ((pa_usec_t
) b
->tv_usec
- a
->tv_usec
);
224 /* Compare the two timeval structs and return 0 when equal, negative when a < b, positive otherwse */
225 int pa_timeval_cmp(const struct timeval
*a
, const struct timeval
*b
) {
228 if (a
->tv_sec
< b
->tv_sec
)
231 if (a
->tv_sec
> b
->tv_sec
)
234 if (a
->tv_usec
< b
->tv_usec
)
237 if (a
->tv_usec
> b
->tv_usec
)
243 /* Return the time difference between now and the specified timestamp */
244 pa_usec_t
pa_timeval_age(const struct timeval
*tv
) {
248 return pa_timeval_diff(pa_gettimeofday(&now
), tv
);
251 /* Add the specified time inmicroseconds to the specified timeval structure */
252 void pa_timeval_add(struct timeval
*tv
, pa_usec_t v
) {
257 tv
->tv_sec
+= (unsigned long) secs
;
263 while (tv
->tv_usec
>= 1000000) {
265 tv
->tv_usec
-= 1000000;
269 /* Return the binary file name of the current process. Works on Linux
270 * only. This shoul be used for eyecandy only, don't rely on return
272 char *pa_get_binary_name(char *s
, size_t l
) {
279 /* This works on Linux only */
281 snprintf(path
, sizeof(path
), "/proc/%u/exe", (unsigned) getpid());
282 if ((i
= readlink(path
, s
, l
-1)) < 0)
287 #elif defined(OS_IS_WIN32)
289 if (!GetModuleFileName(NULL
, path
, PATH_MAX
))
291 pa_strlcpy(s
, pa_path_get_filename(path
), l
);
298 /* Return a pointer to the filename inside a path (which is the last
300 const char *pa_path_get_filename(const char *p
) {
303 if ((fn
= strrchr(p
, PATH_SEP
)))
306 return (const char*) p
;
309 /* Return the fully qualified domain name in *s */
310 char *pa_get_fqdn(char *s
, size_t l
) {
312 #ifdef HAVE_GETADDRINFO
313 struct addrinfo
*a
, hints
;
316 if (!pa_get_host_name(hn
, sizeof(hn
)))
319 #ifdef HAVE_GETADDRINFO
320 memset(&hints
, 0, sizeof(hints
));
321 hints
.ai_family
= AF_UNSPEC
;
322 hints
.ai_flags
= AI_CANONNAME
;
324 if (getaddrinfo(hn
, NULL
, &hints
, &a
) < 0 || !a
|| !a
->ai_canonname
|| !*a
->ai_canonname
)
325 return pa_strlcpy(s
, hn
, l
);
327 pa_strlcpy(s
, a
->ai_canonname
, l
);
331 return pa_strlcpy(s
, hn
, l
);
335 /* Wait t milliseconds */
336 int pa_msleep(unsigned long t
) {
340 #elif defined(HAVE_NANOSLEEP)
344 ts
.tv_nsec
= (t
% 1000) * 1000000;
346 return nanosleep(&ts
, NULL
);
348 #error "Platform lacks a sleep function."