*
* Connection Manager
*
- * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <config.h>
#endif
+#define _GNU_SOURCE
+#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
off_t ptrlen, keylen;
int fd;
- fd = open(pathname, O_RDONLY);
+ fd = open(pathname, O_RDONLY | O_CLOEXEC);
if (fd < 0)
return NULL;
void *dst_map;
int fd, result;
- fd = open(pathname, O_RDONLY);
+ fd = open(pathname, O_RDONLY | O_CLOEXEC);
if (fd < 0)
return -1;
subpath, d->d_name);
if (compare_file(src_map, src_st, pathname) == 0) {
- closedir(dir);
- return g_strdup_printf("%s/%s",
+ str = g_strdup_printf("%s/%s",
subpath, d->d_name);
+ closedir(dir);
+ return str;
}
break;
case DT_DIR:
DBG("sysconfig zone %s", zone);
- fd = open(ETC_LOCALTIME, O_RDONLY);
+ fd = open(ETC_LOCALTIME, O_RDONLY | O_CLOEXEC);
if (fd < 0) {
g_free(zone);
return NULL;
return zone;
}
+static int write_file(void *src_map, struct stat *src_st, const char *pathname)
+{
+ struct stat st;
+ int fd;
+ ssize_t written;
+
+ DBG("pathname %s", pathname);
+
+ if (lstat(pathname, &st) == 0) {
+ if (S_ISLNK(st.st_mode))
+ unlink(pathname);
+ }
+
+ fd = open(pathname, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
+ if (fd < 0)
+ return -EIO;
+
+ written = write(fd, src_map, src_st->st_size);
+
+ close(fd);
+
+ if (written < 0)
+ return -EIO;
+
+ return 0;
+}
+
+int __connman_timezone_change(const char *zone)
+{
+ struct stat st;
+ char *map, pathname[PATH_MAX];
+ int fd, err;
+
+ DBG("zone %s", zone);
+
+ snprintf(pathname, PATH_MAX, "%s/%s", USR_SHARE_ZONEINFO, zone);
+
+ fd = open(pathname, O_RDONLY | O_CLOEXEC);
+ if (fd < 0)
+ return -EINVAL;
+
+ if (fstat(fd, &st) < 0) {
+ close(fd);
+ return -EIO;
+ }
+
+ map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (map == NULL || map == MAP_FAILED) {
+ close(fd);
+ return -EIO;
+ }
+
+ err = write_file(map, &st, ETC_LOCALTIME);
+
+ munmap(map, st.st_size);
+
+ close(fd);
+
+ return err;
+}
+
static guint inotify_watch = 0;
static gboolean inotify_data(GIOChannel *channel, GIOCondition cond,
return FALSE;
}
- DBG("bytes read %ld", bytes_read);
+ DBG("bytes read %zd", bytes_read);
while (bytes_read > 0) {
struct inotify_event *event = ptr;
dirname = g_path_get_dirname(ETC_LOCALTIME);
wd = inotify_add_watch(fd, dirname, IN_DONT_FOLLOW |
- IN_MODIFY | IN_MOVED_TO);
+ IN_CLOSE_WRITE | IN_MOVED_TO);
g_free(dirname);
+ if (wd < 0)
+ return -EIO;
+
return 0;
}