File:  [ELWIX - Embedded LightWeight unIX -] / libaitrpc / src / blob.c
Revision 1.1.2.15: download - view: text, annotated - select for diffs - revision graph
Tue Mar 15 15:13:22 2011 UTC (13 years, 3 months ago) by misho
Branches: rpc1_0
made fix for openbsd errno

    1: #include "global.h"
    2: 
    3: 
    4: /*
    5:  * rpc_srv_blobCreate() Create map blob to memory region and return object
    6:  * @srv = RPC Server instance
    7:  * @len = BLOB length object
    8:  * return: NULL error or !=NULL allocated BLOB object
    9:  */
   10: inline rpc_blob_t *
   11: rpc_srv_blobCreate(rpc_srv_t * __restrict srv, int len)
   12: {
   13: 	rpc_blob_t *blob = NULL;
   14: 	char szFName[MAXPATHLEN];
   15: 	int f;
   16: 	u_int rnd;
   17: 
   18: 	srandomdev();
   19: again:
   20: 	rnd = random() % UINT_MAX;
   21: 
   22: 	memset(szFName, 0, MAXPATHLEN);
   23: 	snprintf(szFName, MAXPATHLEN, BLOB_FILE, srv->srv_blob.dir, rnd);
   24: 	f = open(szFName, O_CREAT | O_EXCL | O_RDWR, 0600);
   25: 	if (f == -1) {
   26: 		if (errno == EEXIST)
   27: 			goto again;
   28: 
   29: 		LOGERR;
   30: 		return NULL;
   31: 	}
   32: 	if (lseek(f, len - 1, SEEK_SET) == -1) {
   33: 		LOGERR;
   34: 		close(f);
   35: 		unlink(szFName);
   36: 		return NULL;
   37: 	} else
   38: 		write(f, "", 1);
   39: 
   40: 	blob = malloc(sizeof(rpc_blob_t));
   41: 	if (!blob) {
   42: 		LOGERR;
   43: 		close(f);
   44: 		unlink(szFName);
   45: 		return NULL;
   46: 	}
   47: 
   48: 	blob->blob_data = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, f, 0);
   49: 	if (blob->blob_data == MAP_FAILED) {
   50: 		LOGERR;
   51: 		free(blob);
   52: 		close(f);
   53: 		unlink(szFName);
   54: 		return NULL;
   55: 	} else
   56: 		close(f);
   57: 
   58: 	blob->blob_len = len;
   59: 	blob->blob_var = rnd;
   60: 	return blob;
   61: }
   62: 
   63: /*
   64:  * rpc_srv_blobMap() Map blob to memory region 
   65:  * @srv = RPC Server instance
   66:  * @blob = Map to this BLOB element
   67:  * return: -1 error or 0 ok
   68:  */
   69: inline int
   70: rpc_srv_blobMap(rpc_srv_t * __restrict srv, rpc_blob_t * __restrict blob)
   71: {
   72: 	int f;
   73: 	char szFName[MAXPATHLEN];
   74: 
   75: 	if (!blob) {
   76: 		rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
   77: 		return -1;
   78: 	}
   79: 
   80: 	memset(szFName, 0, MAXPATHLEN);
   81: 	snprintf(szFName, MAXPATHLEN, BLOB_FILE, srv->srv_blob.dir, blob->blob_var);
   82: 	f = open(szFName, O_RDWR);
   83: 	if (f == -1) {
   84: 		LOGERR;
   85: 		return -1;
   86: 	}
   87: 
   88: 	blob->blob_data = mmap(NULL, blob->blob_len, PROT_READ | PROT_WRITE, MAP_SHARED, f, 0);
   89: 	if (blob->blob_data == MAP_FAILED) {
   90: 		LOGERR;
   91: 		close(f);
   92: 		blob->blob_data = NULL;
   93: 		return -1;
   94: 	} else {
   95: 		close(f);
   96: 
   97: 		madvise(blob->blob_data, blob->blob_len, MADV_SEQUENTIAL);
   98: 	}
   99: 
  100: 	return 0;
  101: }
  102: 
  103: /*
  104:  * rpc_srv_blobUnmap() Unmap blob memory region 
  105:  * @blob = Mapped BLOB element
  106:  * return: none
  107:  */
  108: inline void
  109: rpc_srv_blobUnmap(rpc_blob_t * __restrict blob)
  110: {
  111: 	if (!blob || !blob->blob_data)
  112: 		rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
  113: 	else {
  114: 		munmap(blob->blob_data, blob->blob_len);
  115: 		blob->blob_data = NULL;
  116: 	}
  117: }
  118: 
  119: /*
  120:  * rpc_srv_blobFree() Free blob from disk & memory
  121:  * @srv = RPC Server instance
  122:  * @blob = Mapped BLOB element
  123:  * return: -1 error or 0 ok
  124:  */
  125: inline int
  126: rpc_srv_blobFree(rpc_srv_t * __restrict srv, rpc_blob_t * __restrict blob)
  127: {
  128: 	char szFName[MAXPATHLEN];
  129: 
  130: 	if (!blob) {
  131: 		rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
  132: 		return -1;
  133: 	}
  134: 
  135: 	if (blob->blob_data)
  136: 		rpc_srv_blobUnmap(blob);
  137: 
  138: 	memset(szFName, 0, MAXPATHLEN);
  139: 	snprintf(szFName, MAXPATHLEN, BLOB_FILE, srv->srv_blob.dir, blob->blob_var);
  140: 	if (remove(szFName) == -1) {
  141: 		LOGERR;
  142: 		return -1;
  143: 	}
  144: 
  145: 	return 0;
  146: }
  147: 
  148: // ------------------------------------------------------------
  149: 
  150: /*
  151:  * rpc_srv_sendBLOB() Send mapped BLOB to client
  152:  * @cli = Client instance
  153:  * @blob = Mapped BLOB element
  154:  * return: -1 error, 0 ok
  155:  */
  156: int
  157: rpc_srv_sendBLOB(rpc_cli_t * __restrict cli, rpc_blob_t * __restrict blob)
  158: {
  159: 	int ret, len;
  160: 	uint8_t *pos;
  161: 
  162: 	if (!cli || !blob || !blob->blob_data) {
  163: 		rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
  164: 		return -1;
  165: 	}
  166: 
  167: 	for (ret = blob->blob_len, pos = blob->blob_data; ret > 0; ret -= len, pos += len)
  168: 		if ((len = send(cli->cli_sock, pos, ret > BLOBSIZ ? BLOBSIZ : ret, 0)) == -1) {
  169: 			LOGERR;
  170: 			return -1;
  171: 		}
  172: 
  173: 	return ret;
  174: }
  175: 
  176: /*
  177:  * rpc_srv_recvBLOB() Receive BLOB from client
  178:  * @cli = Client instance
  179:  * @blob = Mapped BLOB element
  180:  * return: -1 error, 0 ok, >0 unreceived data from client, may be error?
  181:  */
  182: int
  183: rpc_srv_recvBLOB(rpc_cli_t * __restrict cli, rpc_blob_t * __restrict blob)
  184: {
  185: 	int ret, len;
  186: 	uint8_t *pos;
  187: 	fd_set fds;
  188: 	struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
  189: 
  190: 	if (!cli || !blob || !blob->blob_data) {
  191: 		rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
  192: 		return -1;
  193: 	}
  194: 
  195: 	for (ret = blob->blob_len, pos = blob->blob_data; ret > 0; ret -= len, pos += len) {
  196: 		FD_ZERO(&fds);
  197: 		FD_SET(cli->cli_sock, &fds);
  198: 		len = select(cli->cli_sock + 1, &fds, NULL, NULL, &tv);
  199: 		if (len < 1) {
  200: 			LOGERR;
  201: 			return -1;
  202: 		}
  203: 
  204: 		if ((len = recv(cli->cli_sock, pos, BLOBSIZ, 0)) == -1) {
  205: 			LOGERR;
  206: 			return -1;
  207: 		}
  208: 	}
  209: 
  210: 	return ret;
  211: }
  212: 
  213: // ------------------------------------------------------------
  214: 
  215: /*
  216:  * rpc_cli_sendBLOB() Send BLOB to server
  217:  * @cli = Client instance
  218:  * @var = BLOB variable
  219:  * @data = BLOB data
  220:  * return: -1 error, 0 ok, 1 remote error
  221:  */
  222: int
  223: rpc_cli_sendBLOB(rpc_cli_t * __restrict cli, rpc_val_t * __restrict var, void * __restrict data)
  224: {
  225: 	int ret, len;
  226: 	uint8_t *pos;
  227: 	struct tagBLOBHdr hdr;
  228: 	fd_set fds;
  229: 	struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
  230: 
  231: 	if (!cli || !var || !data) {
  232: 		rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
  233: 		return -1;
  234: 	}
  235: 
  236: 	memcpy(&hdr.hdr_session, cli->cli_parent, sizeof(rpc_sess_t));
  237: 	hdr.hdr_cmd = set;
  238: 	hdr.hdr_var = 0;
  239: 	hdr.hdr_ret = 0;
  240: 	hdr.hdr_len = var->val_len;
  241: 	if (send(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
  242: 		LOGERR;
  243: 		return -1;
  244: 	}
  245: 
  246: 	for (ret = var->val_len, pos = data; ret > 0; ret -= len, pos += len)
  247: 		if ((len = send(cli->cli_sock, pos, ret > BLOBSIZ ? BLOBSIZ : ret, 0)) == -1) {
  248: 			LOGERR;
  249: 			return -1;
  250: 		}
  251: 
  252: 	FD_ZERO(&fds);
  253: 	FD_SET(cli->cli_sock, &fds);
  254: 	switch (select(cli->cli_sock + 1, &fds, NULL, NULL, &tv)) {
  255: 		case -1:
  256: 			LOGERR;
  257: 			return -1;
  258: 		case 0:
  259: 			rpc_SetErr(ETIMEDOUT, "Error:: Timeout reached! Server not responde ...\n");
  260: 			return -1;
  261: 	}
  262: 	if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
  263: 		LOGERR;
  264: 		return -1;
  265: 	}
  266: 	if (hdr.hdr_cmd != error) {
  267: 		if (hdr.hdr_len != var->val_len) {
  268: 			rpc_SetErr(ECANCELED, "Error:: Bad return length packet ...\n");
  269: 			return -1;
  270: 		}
  271: 
  272: 		var->val.blob = hdr.hdr_var;
  273: 	}
  274: 
  275: 	return hdr.hdr_cmd == error;
  276: }
  277: 
  278: /*
  279:  * rpc_cli_recvBLOB() Receive BLOB from server
  280:  * @cli = Client instance
  281:  * @var = BLOB variable
  282:  * @data = BLOB data, must be free after use!
  283:  * return: -1 error, 0 ok, 1 remote error
  284:  */
  285: int
  286: rpc_cli_recvBLOB(rpc_cli_t * __restrict cli, rpc_val_t * __restrict var, void ** data)
  287: {
  288: 	int ret, len;
  289: 	uint8_t *pos;
  290: 	fd_set fds;
  291: 	struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
  292: 	struct tagBLOBHdr hdr;
  293: 
  294: 	if (!cli || !var || !data) {
  295: 		rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
  296: 		return -1;
  297: 	}
  298: 
  299: 	*data = malloc(var->val_len);
  300: 	if (!*data) {
  301: 		LOGERR;
  302: 		return -1;
  303: 	} else
  304: 		memset(*data, 0, var->val_len);
  305: 
  306: 	memcpy(&hdr.hdr_session, cli->cli_parent, sizeof(rpc_sess_t));
  307: 	hdr.hdr_cmd = get;
  308: 	hdr.hdr_var = (uint32_t) RPC_GET_BLOB(var);
  309: 	hdr.hdr_ret = 0;
  310: 	hdr.hdr_len = 0;
  311: 	if (send(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
  312: 		LOGERR;
  313: 		free(*data);
  314: 		*data = NULL;
  315: 		return -1;
  316: 	}
  317: 
  318: 	for (ret = var->val_len, pos = *data; ret > 0; ret -= len, pos += len) {
  319: 		FD_ZERO(&fds);
  320: 		FD_SET(cli->cli_sock, &fds);
  321: 		len = select(cli->cli_sock + 1, &fds, NULL, NULL, &tv);
  322: 		if (len < 1) {
  323: 			LOGERR;
  324: 			free(*data);
  325: 			*data = NULL;
  326: 			return -1;
  327: 		}
  328: 
  329: 		if ((len = recv(cli->cli_sock, pos, BLOBSIZ, 0)) == -1) {
  330: 			LOGERR;
  331: 			free(*data);
  332: 			*data = NULL;
  333: 			return -1;
  334: 		}
  335: 	}
  336: 
  337: 	FD_ZERO(&fds);
  338: 	FD_SET(cli->cli_sock, &fds);
  339: 	switch (select(cli->cli_sock + 1, &fds, NULL, NULL, &tv)) {
  340: 		case -1:
  341: 			LOGERR;
  342: 			free(*data);
  343: 			*data = NULL;
  344: 			return -1;
  345: 		case 0:
  346: 			rpc_SetErr(ETIMEDOUT, "Error:: Timeout reached! Server not responde ...\n");
  347: 			free(*data);
  348: 			*data = NULL;
  349: 			return -1;
  350: 	}
  351: 	if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
  352: 		LOGERR;
  353: 		free(*data);
  354: 		*data = NULL;
  355: 		return -1;
  356: 	}
  357: 	if (hdr.hdr_cmd != error) {
  358: 		if (hdr.hdr_len != var->val_len) {
  359: 			rpc_SetErr(ECANCELED, "Error:: Bad return length packet ...\n");
  360: 			free(*data);
  361: 			*data = NULL;
  362: 			return -1;
  363: 		}
  364: 	}
  365: 
  366: 	return hdr.hdr_cmd == error;
  367: }
  368: 
  369: /*
  370:  * rpc_cli_delBLOB() Delete BLOB from server
  371:  * @cli = Client instance
  372:  * @var = BLOB variable
  373:  * return: -1 error, 0 ok, 1 remote error
  374:  */
  375: int
  376: rpc_cli_delBLOB(rpc_cli_t * __restrict cli, rpc_val_t * __restrict var)
  377: {
  378: 	struct tagBLOBHdr hdr;
  379: 	fd_set fds;
  380: 	struct timeval tv = { DEF_RPC_TIMEOUT, 0 };
  381: 
  382: 	if (!cli || !var) {
  383: 		rpc_SetErr(EINVAL, "Error:: invalid arguments ...\n");
  384: 		return -1;
  385: 	}
  386: 
  387: 	memcpy(&hdr.hdr_session, cli->cli_parent, sizeof(rpc_sess_t));
  388: 	hdr.hdr_cmd = unset;
  389: 	hdr.hdr_var = (uint32_t) RPC_GET_BLOB(var);
  390: 	hdr.hdr_ret = 0;
  391: 	hdr.hdr_len = 0;
  392: 	if (send(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
  393: 		LOGERR;
  394: 		return -1;
  395: 	}
  396: 
  397: 	FD_ZERO(&fds);
  398: 	FD_SET(cli->cli_sock, &fds);
  399: 	switch (select(cli->cli_sock + 1, &fds, NULL, NULL, &tv)) {
  400: 		case -1:
  401: 			LOGERR;
  402: 			return -1;
  403: 		case 0:
  404: 			rpc_SetErr(ETIMEDOUT, "Error:: Timeout reached! Server not responde ...\n");
  405: 			return -1;
  406: 	}
  407: 	if (recv(cli->cli_sock, &hdr, sizeof hdr, 0) == -1) {
  408: 		LOGERR;
  409: 		return -1;
  410: 	}
  411: 
  412: 	return hdr.hdr_cmd == error;
  413: }
  414: 
  415: /*
  416:  * rpc_cli_getBLOB() Receive BLOB from server and Delete after that
  417:  * @cli = Client instance
  418:  * @var = BLOB variable
  419:  * @data = BLOB data, must be free after use!
  420:  * return: -1 error, 0 ok, 1 remote error
  421:  */
  422: inline int
  423: rpc_cli_getBLOB(rpc_cli_t * __restrict cli, rpc_val_t * __restrict var, void ** data)
  424: {
  425: 	int ret;
  426: 
  427: 	ret = rpc_cli_recvBLOB(cli, var, data);
  428: 	ret |= rpc_cli_delBLOB(cli, var) > 0 ? 2 : 0;
  429: 
  430: 	return ret;
  431: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>