summaryrefslogtreecommitdiff
path: root/avsys-common.c
diff options
context:
space:
mode:
authorKibum Kim <kb0929.kim@samsung.com>2012-02-27 21:15:48 +0900
committerKibum Kim <kb0929.kim@samsung.com>2012-02-27 21:15:48 +0900
commitb8e758c1624a163a988aa868fbf3da19e2612f6c (patch)
tree15744098f716f394766a5ee2947aed8946f04d2f /avsys-common.c
downloadavsystem-b8e758c1624a163a988aa868fbf3da19e2612f6c.tar.gz
avsystem-b8e758c1624a163a988aa868fbf3da19e2612f6c.tar.bz2
avsystem-b8e758c1624a163a988aa868fbf3da19e2612f6c.zip
tizen beta release
Diffstat (limited to 'avsys-common.c')
-rw-r--r--avsys-common.c368
1 files changed, 368 insertions, 0 deletions
diff --git a/avsys-common.c b/avsys-common.c
new file mode 100644
index 0000000..91f080e
--- /dev/null
+++ b/avsys-common.c
@@ -0,0 +1,368 @@
+/*
+ * avsystem
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "avsys-common.h"
+#include "avsys-debug.h"
+#include "avsys-error.h"
+
+#include <stdio.h>
+#include <memory.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <time.h>
+
+#define RETRY_EINTR
+#include <fcntl.h>
+#include <semaphore.h>
+
+void * avsys_malloc(size_t size)
+{
+ char *allocated;
+ allocated = (char*) malloc(size + 12);
+
+ if(!allocated) {
+ return NULL;
+ }
+ memset(allocated, 0, size+8);
+ memcpy(allocated, AVSYS_MAGIC_START, 4);
+ (*(int*)(allocated+4)) = size;
+ memcpy(allocated+size+8, AVSYS_MAGIC_END, 4);
+
+ return (void*)(allocated + 8);
+}
+
+void avsys_free(void *ptr)
+{
+ char *allocated = (char*)ptr;
+ if(allocated) {
+ if(avsys_mem_check(allocated)) {
+ free(allocated-8);
+ }
+ }
+}
+
+int avsys_create_shm(const avsys_shm_param_t* param)
+{
+ int shmid = -1;
+ int *segptr = NULL;
+ key_t key;
+
+ if (!param) {
+ return AVSYS_STATE_ERR_NULL_POINTER;
+ }
+ if (param->size < 1 || param->key_path == NULL || access(param->key_path, R_OK) != 0) {
+ return AVSYS_STATE_ERR_INVALID_VALUE;
+ }
+
+ key = ftok(param->key_path, param->key_prefix);
+
+ if ((shmid = shmget(key, param->size, IPC_CREAT|IPC_EXCL|0666)) == -1) {
+ if (errno == EEXIST) {
+ avsys_error(AVAUDIO,"Already initialized.\n");
+ if ((shmid = shmget(key, param->size, 0)) == -1) {
+ avsys_error(AVAUDIO, "Initialization fail.\n");
+ } else {
+ segptr = shmat(shmid, 0, 0);
+ avsys_assert_r(segptr != NULL);
+ }
+ } else {
+ if(errno == EACCES)
+ avsys_error_r(AVAUDIO, "Require ROOT permission.\n");
+ else if(errno == ENOMEM)
+ avsys_critical_r(AVAUDIO, "System memory is empty.\n");
+ else if(errno == ENOSPC)
+ avsys_critical_r(AVAUDIO, "Resource is empty.\n");
+ }
+ } else {
+ shmctl(shmid, SHM_LOCK, 0);
+ segptr = shmat(shmid, 0, 0);
+ avsys_assert_r(segptr != NULL);
+ memset((void*)segptr, 0, param->size);
+ }
+
+ if (shmid != -1) {
+ return AVSYS_STATE_SUCCESS;
+ } else {
+ return AVSYS_STATE_ERR_INTERNAL;
+ }
+}
+
+int avsys_remove_shm(const avsys_shm_param_t* param)
+{
+ int shmid = -1;
+ key_t key;
+
+ if (!param) {
+ return AVSYS_STATE_ERR_NULL_POINTER;
+ }
+ if (param->size < 1 || param->key_path == NULL || access(param->key_path, R_OK) != 0) {
+ return AVSYS_STATE_ERR_INVALID_VALUE;
+ }
+
+ key = ftok(param->key_path, param->key_prefix);
+
+ if ((shmid = shmget(key, param->size, 0)) == -1) {
+ if(errno == ENOENT)
+ avsys_error_r(AVAUDIO, "Not initialized.\n");
+ else if(errno == EACCES)
+ avsys_error_r(AVAUDIO, "Require ROOT permission.\n");
+ else if(errno == ENOSPC)
+ avsys_critical_r(AVAUDIO, "Resource is empty.\n");
+ } else {
+ avsys_assert_r(shmctl(shmid, IPC_RMID, 0) == 0);
+ }
+
+ if (shmid != -1) {
+ return AVSYS_STATE_SUCCESS;
+ } else {
+ return AVSYS_STATE_ERR_INTERNAL;
+ }
+}
+
+void* avsys_get_shm(const avsys_shm_param_t* param)
+{
+ int shmid = -1;
+ void *ptr = NULL;
+ key_t key;
+
+ if (!param) {
+ return NULL;
+ }
+ if (param->size < 1 || param->key_path == NULL || access(param->key_path, R_OK) != 0) {
+ return NULL;
+ }
+
+ key = ftok(param->key_path, param->key_prefix);
+
+ if ((shmid = shmget(key, param->size, 0)) == -1) {
+ if(errno == ENOENT)
+ avsys_error_r(AVAUDIO, "Not initialized.\n");
+ else if(errno == EACCES)
+ avsys_error_r(AVAUDIO, "Require ROOT permission.\n");
+ else if(errno == ENOSPC)
+ avsys_critical_r(AVAUDIO, "Resource is empty.\n");
+ return NULL;
+ }
+
+ ptr = shmat(shmid, 0, 0);
+ if(ptr == (void*)-1) {
+ if(errno == EACCES)
+ avsys_error_r(AVAUDIO,"no permission\n");
+ else if(errno == EINVAL)
+ avsys_error_r(AVAUDIO,"invalid shmid\n");
+ else if(errno == ENOMEM)
+ avsys_error_r(AVAUDIO,"can not allocate memory\n");
+ else
+ avsys_error_r(AVAUDIO,"shmat() failed %d\n", errno);
+ ptr = NULL;
+ }
+ return ptr;
+}
+
+int avsys_create_sync(const avsys_sync_param_t *param)
+{
+ sem_t *sem = NULL;
+ sem = sem_open(param->key_path, O_CREAT, 0666, 1);
+ if (sem == SEM_FAILED) {
+ switch(errno)
+ {
+ case EACCES:
+ avsys_error(AVAUDIO,
+ "The semaphore already exist, but caller does not have permission %s\n",param->key_path);
+ break;
+ case ENOMEM:
+ avsys_error(AVAUDIO,"Insufficient memory in %s (%d)\n",__func__,__LINE__);
+ break;
+ case ENFILE:
+ avsys_error(AVAUDIO,"Too many open files in system %s (%d)\n",__func__,__LINE__);
+ break;
+ default:
+ avsys_critical(AVAUDIO, "Semaphore create fail! (name:%s, errno %d)\n", param->key_path, errno);
+ break;
+ }
+ return AVSYS_STATE_ERR_INTERNAL;
+ }
+ return AVSYS_STATE_SUCCESS;
+}
+
+int avsys_remove_sync(const avsys_sync_param_t *param)
+{
+ int err = 0;
+
+ err = sem_unlink(param->key_path);
+ if (err == -1) {
+ avsys_critical(AVAUDIO, "Semaphore destroy Fail! (name:%s, errno %d)\n", param->key_path, errno);
+ return AVSYS_STATE_ERR_INTERNAL;
+ }
+
+ return AVSYS_STATE_SUCCESS;
+}
+
+int avsys_lock_sync(const avsys_sync_param_t *param)
+{
+ sem_t *sem = NULL;
+ int ret;
+ int err = AVSYS_STATE_SUCCESS;
+ struct timespec wait_time;
+
+ sem = sem_open(param->key_path, O_CREAT, 0666, 1);
+ if (sem == SEM_FAILED) {
+ avsys_critical(AVAUDIO, "Semaphore open Fail! (name:%s, errno %d)\n", param->key_path, errno);
+ return AVSYS_STATE_ERR_INTERNAL;
+ }
+retry_lock:
+ wait_time.tv_sec = (long int)(time(NULL)) + LOCK_TIMEOUT_SEC;
+ wait_time.tv_nsec = 0;
+ ret = sem_timedwait(sem, &wait_time);
+ if(ret == -1) {
+ switch(errno)
+ {
+ case EINTR:
+ avsys_critical(AVAUDIO, "Lock RETRY LOCK\n");
+ goto retry_lock;
+ break;
+ case EINVAL:
+ avsys_critical(AVAUDIO, "Invalid semaphore\n");
+ err = AVSYS_STATE_ERR_INTERNAL;
+ break;
+ case EAGAIN:
+ avsys_critical(AVAUDIO, "EAGAIN\n");
+ err = AVSYS_STATE_ERR_INTERNAL;
+ break;
+ case ETIMEDOUT:
+ avsys_critical(AVAUDIO, "sem_wait leached %d seconds timeout.\n", LOCK_TIMEOUT_SEC);
+ {
+ /* Recovery of sem_wait lock....in abnormal condition */
+ int sem_value = -1;
+ if (0 == sem_getvalue(sem, &sem_value)) {
+ avsys_critical(AVAUDIO,"%s sem value is %d\n",param->key_path, sem_value);
+ if (sem_value == 0) {
+ ret = sem_post(sem);
+ if (ret == -1) {
+ avsys_critical(AVAUDIO,"sem_post error %s : %d\n", param->key_path, sem_value);
+ } else {
+ avsys_critical_r(AVAUDIO,"lock recovery success...try lock again\n");
+ goto retry_lock;
+ }
+ } else {
+ avsys_critical(AVAUDIO,"sem value is not 0. but failed sem_timedwait so retry.. : %s\n",param->key_path);
+ usleep(5);
+ goto retry_lock;
+ }
+ } else {
+ avsys_critical(AVAUDIO,"sem_getvalue failed : %s\n",param->key_path);
+ }
+ }
+ err = AVSYS_STATE_ERR_INTERNAL;
+ break;
+ }
+ }
+ sem_close(sem);
+ return err;
+}
+
+int avsys_unlock_sync(const avsys_sync_param_t *param)
+{
+ sem_t *sem = NULL;
+ int ret;
+ int err = AVSYS_STATE_SUCCESS;
+
+ sem = sem_open(param->key_path, O_CREAT, 0666, 1);
+ if (sem == SEM_FAILED) {
+ avsys_critical(AVAUDIO, "Semaphore open Fail! (name:%s, errno %d)\n", param->key_path, errno);
+ return AVSYS_STATE_ERR_INTERNAL;
+ }
+
+ ret = sem_post(sem);
+ if (ret == -1) {
+ avsys_critical(AVAUDIO, "UNLOCK FAIL\n");
+ err = AVSYS_STATE_ERR_INTERNAL;
+ }
+
+ sem_close(sem);
+ return err;
+}
+
+int avsys_check_root_privilege()
+{
+ uid_t uid;
+ uid = getuid();
+ if(0 != uid) {
+ /* code from man page */
+ struct passwd pwd;
+ struct passwd *result;
+ char *buf;
+ size_t bufsize;
+ int s = 0;
+
+ bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (bufsize == -1) /* Value was indeterminate */
+ bufsize = 16384; /* Should be more than enough */
+
+ buf = malloc(bufsize);
+ if (buf == NULL) {
+ perror("malloc");
+ } else {
+ s= getpwuid_r (uid, &pwd, buf, bufsize, &result);
+ if (result == NULL) {
+ if (s == 0)
+ printf("Not found\n");
+ else {
+ errno = s;
+ perror("getpwnam_r");
+ }
+ } else {
+ avsys_error_r(AVAUDIO,"super user privilege check failed (%s)\n", pwd.pw_name);
+ }
+ free (buf);
+ }
+ return AVSYS_STATE_ERR_PRIVILEGE;
+ }
+ return AVSYS_STATE_SUCCESS;
+}
+
+int avsys_dump_sync (const avsys_sync_param_t *param)
+{
+ int err = AVSYS_STATE_SUCCESS;
+
+ sem_t *sem = NULL;
+ int ret;
+ int sem_value = -1;
+
+ sem = sem_open(param->key_path, O_CREAT, 0666, 1);
+ if (sem == SEM_FAILED) {
+ avsys_critical(AVAUDIO, "Semaphore open Fail! (name:%s, errno %d)\n", param->key_path, errno);
+ return AVSYS_STATE_ERR_INTERNAL;
+ }
+
+ if(0 == sem_getvalue(sem, &sem_value)) {
+ fprintf (stdout, " * [%d] sem value for [%s]\n", sem_value, param->key_path);
+ } else {
+ avsys_critical(AVAUDIO,"sem_getvalue failed : %s\n",param->key_path);
+ }
+
+ sem_close(sem);
+ return err;
+}