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."