File:  [ELWIX - Embedded LightWeight unIX -] / libaitrpc / src / blob.c
Revision 1.1.2.10: download - view: text, annotated - select for diffs - revision graph
Wed Jul 7 15:18:22 2010 UTC (14 years ago) by misho
Branches: rpc1_0
fix args mess and other things

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

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