Use the same type to compare values
[platform/framework/web/download-provider.git] / provider / download-provider-ipc.c
1 /*
2  * Copyright (c) 2013 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 <stdio.h>
18 #include <stdlib.h>
19 #include <sys/socket.h> // shutdown
20 #include <time.h>
21 #include <errno.h>
22
23 #include "download-provider-log.h"
24 #include "download-provider-ipc.h"
25
26 int dp_ipc_check_stderr(int basecode)
27 {
28         int errorcode = basecode;
29         if (errno == EPIPE) {
30                 TRACE_ERROR("[EPIPE:%d] Broken Pipe", errno);
31                 errorcode = DP_ERROR_IO_ERROR;
32         } else if (errno == EAGAIN) {
33                 TRACE_ERROR("[EAGAIN:%d]", errno);
34                 errorcode = DP_ERROR_IO_EAGAIN;
35         } else if (errno == EINTR) {
36                 TRACE_ERROR("[EINTR:%d]", errno);
37                 errorcode = DP_ERROR_IO_EINTR;
38         } else if (errno == ENOENT) {
39                 TRACE_ERROR("[ENOENT:%d]", errno);
40                 errorcode = DP_ERROR_IO_ERROR;
41         } else {
42                 TRACE_ERROR("[errno:%d]", errno);
43         }
44         return errorcode;
45 }
46
47 int dp_ipc_write(int sock, void *value, size_t type_size)
48 {
49         if (sock < 0) {
50                 TRACE_ERROR("[ERROR] check sock:%d", sock);
51                 return -1;
52         } else if (value == NULL) {
53                 TRACE_ERROR("[ERROR] check buffer sock:%d", sock);
54                 return -1;
55         } else if (write(sock, value, type_size) <= 0) {
56                 TRACE_ERROR("[IPC.Write] exception sock:%d", sock);
57                 return -1;
58         }
59         TRACE_INFO("[IPC.Write] succeed sock:%d", sock);
60         return 0;
61 }
62
63 ssize_t dp_ipc_read(int sock, void *value, size_t type_size,
64         const char *func)
65 {
66         int errorcode = DP_ERROR_NONE;
67         ssize_t recv_bytes = 0;
68
69         if (sock < 0) {
70                 TRACE_ERROR("[ERROR] %s check sock:%d", func, sock);
71                 return -1;
72         }
73         if (value == NULL) {
74                 TRACE_ERROR("[ERROR] %s check buffer sock:%d", func, sock);
75                 return -1;
76         }
77
78         int tryagain = 3;
79         do {
80                 errorcode = DP_ERROR_NONE;
81                 recv_bytes = read(sock, value, type_size);
82                 if (recv_bytes < 0) {
83                         TRACE_ERROR("[IPC.Read] %s exception sock:%d", func, sock);
84                         errorcode = dp_ipc_check_stderr(DP_ERROR_IO_ERROR);
85                 } else if (recv_bytes == 0) {
86                         TRACE_ERROR("[ERROR] %s closed peer sock:%d", func, sock);
87                         errorcode = DP_ERROR_IO_ERROR;
88                 }
89         } while (sock >= 0 && (errorcode == DP_ERROR_IO_EAGAIN ||
90                 errorcode == DP_ERROR_IO_EINTR) && (--tryagain > 0));
91         return recv_bytes;
92 }
93
94 dp_ipc_fmt *dp_ipc_get_fmt(int sock)
95 {
96         dp_ipc_fmt *ipc_info = malloc(sizeof(dp_ipc_fmt));
97         if (ipc_info == NULL) {
98                 TRACE_ERROR("[ERROR] Fail to malloc");
99                 return NULL;
100         }
101         memset(ipc_info, 0x00, sizeof(dp_ipc_fmt));
102
103         int errorcode = DP_ERROR_NONE;
104         int tryagain = 5;
105
106         do {
107                 ssize_t recv_size = read(sock, ipc_info, sizeof(dp_ipc_fmt));
108                 if (recv_size <= 0 || recv_size != sizeof(dp_ipc_fmt)) {
109                         TRACE_ERROR("socket read ipcinfo read size:%zd, errno:%d", recv_size, errno);
110                         errorcode = dp_ipc_check_stderr(errno);
111                 } else {
112                         errorcode = DP_ERROR_NONE;
113                 }
114         } while (sock >= 0 && (errorcode == DP_ERROR_IO_EAGAIN ||
115                 errorcode == DP_ERROR_IO_EINTR) && (--tryagain > 0));
116
117         if (errorcode != DP_ERROR_NONE) {
118                 TRACE_ERROR("Failed to read sock[%d]", sock);
119                 free(ipc_info);
120                 return NULL;
121         }
122
123         return ipc_info;
124 }
125
126 int dp_ipc_query(int sock, int download_id, short section,
127         unsigned property, int error, size_t size)
128 {
129         dp_ipc_fmt ipc_info;
130         memset(&ipc_info, 0x00, sizeof(dp_ipc_fmt));
131         ipc_info.section = section;
132         ipc_info.property = property;
133         ipc_info.id = download_id;
134         ipc_info.errorcode = error;
135         ipc_info.size = size;
136         if (dp_ipc_write(sock, &ipc_info, sizeof(dp_ipc_fmt)) < 0)
137                 return -1;
138         return 0;
139 }
140
141 int dp_ipc_socket_free(int sockfd)
142 {
143         if (sockfd < 0)
144                 return -1;
145         close(sockfd);
146         return 0;
147 }