HIPC  0.5
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
client.c
Go to the documentation of this file.
1 #include <assert.h>
2 #include <errno.h>
3 #include <limits.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 
8 #include <hipc/client.h>
9 
10 static const char *hipc_errstr[HIPC_N_ERR] = {
11  "HIPC_SUCCESS: No error",
12 
13  "HIPC_ERR_S_INV_UDATA: Invalid user data",
14  "HIPC_ERR_S_INV_MSG_TYPE: Invalid message type",
15  "HIPC_ERR_S_INV_STRUNO: Invalid structure number",
16  "HIPC_ERR_S_INV_RW_RANGE: Invalid read/write range",
17  "HIPC_ERR_S_V_UNINIT_MSG: Virtually uninitialized HIPC message",
18  "HIPC_ERR_S_IO_READ: I/O read error",
19  "HIPC_ERR_S_IO_WRITE: I/O write error",
20  "HIPC_ERR_S_INV_CFG: Invalid Configuration",
21  "HIPC_ERR_S_INV_NULL: Invalid NULL value",
22  "HIPC_ERR_S_BUF_SHTG: Buffer shortage",
23  "HIPC_ERR_S_OVERSIZED_STRU: Oversized structure size",
24  "HIPC_ERR_S_PBANK_STAT_MISMATCH: pbank status mismatch",
25 
26  "HIPC_ERR_C_STD: C standard library error",
27  "HIPC_ERR_INTERNAL_ERROR: Internal error in HIPC library",
28  "HIPC_ERR_IO_READ: I/O read error",
29  "HIPC_ERR_IO_WRITE: I/O write error",
30  "HIPC_ERR_PROTOCOL_VIOLATION: Protocol violation",
31  "HIPC_ERR_INV_ENDIAN: Invalid endian",
32  "HIPC_ERR_INV_ID_STR: Invalid ID string",
33  "HIPC_ERR_INV_BASE_CLIENT: Invalid base client",
34  "HIPC_ERR_MBR_SIZE_MISMATCH: Structure member size mismatch",
35  "HIPC_ERR_SESS_STATE_MISMATCH: Session state mismatch",
36 
37  "HIPC_ERR_FOR_TESTING: Error only for testing",
38  "HIPC_ERR_TEST_LIB_INTERNAL: Internal error in a library only for testing",
39 };
40 
49 static void *hipcClientMalloc(struct HIPC_client *const cl_p, size_t size)
50 {
51  struct HIPC_ptr_link_list *pllist_p;
52  void *tmp_p;
53 
54  tmp_p = malloc(size);
55  if (NULL == tmp_p) {
56  cl_p->std_errno = errno;
57  cl_p->hipc_errno = HIPC_ERR_C_STD;
58  return NULL;
59  }
60 
61  pllist_p = malloc(sizeof(struct HIPC_ptr_link_list));
62  if (NULL == pllist_p) {
63  cl_p->std_errno = errno;
64  cl_p->hipc_errno = HIPC_ERR_C_STD;
65  return NULL;
66  }
67 
68  pllist_p->ptr = tmp_p;
69  pllist_p->next = cl_p->pllist_p;
70  cl_p->pllist_p = pllist_p;
71 
72  return tmp_p;
73 }
74 
84 static void *hipcClientCalloc(struct HIPC_client *const cl_p, size_t nmemb,
85  size_t size)
86 {
87  struct HIPC_ptr_link_list *pllist_p;
88  void *tmp_p;
89 
90  tmp_p = calloc(nmemb, size);
91  if (NULL == tmp_p) {
92  cl_p->std_errno = errno;
93  cl_p->hipc_errno = HIPC_ERR_C_STD;
94  return NULL;
95  }
96 
97  pllist_p = malloc(sizeof(struct HIPC_ptr_link_list));
98  if (NULL == pllist_p) {
99  cl_p->std_errno = errno;
100  cl_p->hipc_errno = HIPC_ERR_C_STD;
101  return NULL;
102  }
103 
104  pllist_p->ptr = tmp_p;
105  pllist_p->next = cl_p->pllist_p;
106  cl_p->pllist_p = pllist_p;
107 
108  return tmp_p;
109 }
110 
119 void hipcClientSetStdErrno(struct HIPC_client *const cl_p)
120 {
121  cl_p->std_errno = errno;
122  return;
123 }
124 
131 int hipcClientGetStdErrno(const struct HIPC_client *const cl_p)
132 {
133  return cl_p->std_errno;
134 }
135 
142 enum HIPC_errno
143 hipcClientGetHipcErrno(const struct HIPC_client *const cl_p)
144 {
145  return cl_p->hipc_errno;
146 }
147 
155 const char *hipcClientGetErrStr(const struct HIPC_client *const cl_p)
156 {
157  if (0 <= cl_p->hipc_errno && HIPC_N_ERR > cl_p->hipc_errno) {
158  return hipc_errstr[cl_p->hipc_errno];
159  } else {
160  return "Unknown HIPC errorno value";
161  }
162 }
163 
171 const char *hipcClientGetErrDtlStr(const struct HIPC_client *const cl_p)
172 {
173  return cl_p->err_detail_str;
174 }
175 
195 static void
197  char const *const str0,
198  char const *const str1, size_t ls1)
199 {
200  size_t ls0;
201 
202  if (NULL == str0) {
203  return;
204  }
205 
206  ls0 = strlen(str0);
207 
208  if (ls0 >= sizeof(cl_p->err_detail_str)) {
209  memcpy(cl_p->err_detail_str, str0,
210  sizeof(cl_p->err_detail_str) - 1);
211  cl_p->err_detail_str[sizeof(cl_p->err_detail_str) - 1] = '\0';
212  } else {
213  memcpy(cl_p->err_detail_str, str0, ls0 + 1);
214  if (NULL != str1) {
215  if (0 == ls1) {
216  ls1 = strlen(str1);
217  }
218  if (ls0 + ls1 >= sizeof(cl_p->err_detail_str)) {
219  memcpy(cl_p->err_detail_str + ls0,
220  str1, sizeof(cl_p->err_detail_str) - ls0 - 1);
221  cl_p->err_detail_str[sizeof(cl_p->err_detail_str) - 1] =
222  '\0';
223  } else {
224  memcpy(cl_p->err_detail_str + ls0, str1, ls1);
225  cl_p->err_detail_str[ls0 + ls1] = '\0';
226  }
227  }
228  }
229  return;
230 }
231 
240 enum HIPC_errno hipcClientSetError(struct HIPC_client *const cl_p,
241  enum HIPC_errno hipc_errno,
242  char const *const str)
243 {
244  cl_p->hipc_errno = hipc_errno;
245  hipcClientSetErrDtlStr(cl_p, str, NULL, 0);
246 
247  return hipc_errno;
248 }
249 
259 void
260 hipcClientSetCimg(struct HIPC_client *const cl_p,
261  const unsigned char struno, void *cimg_p)
262 {
263  assert(NULL != cl_p->cimg_pp);
264  cl_p->cimg_pp[struno] = cimg_p;
265 
266  return;
267 }
268 
278 void
280  const unsigned char struno,
281  enum HIPC_errno (*hndlr_p) (struct HIPC_client *,
282  const hipc_msg, void *,
283  void *), void *const arg)
284 {
285  assert(NULL != cl_p->hndlr_pp);
286  assert(NULL != cl_p->hdarg_pp);
287  cl_p->hndlr_pp[struno] = hndlr_p;
288  cl_p->hdarg_pp[struno] = arg;
289 
290  return;
291 }
292 
302 enum HIPC_errno
304  const unsigned char struno, const hipc_msg msgR)
305 {
306  enum HIPC_errno retval;
307 
308  assert(NULL != cl_p->hndlr_pp);
309  assert(NULL != cl_p->cimg_pp);
310 
311  retval = HIPC_SUCCESS;
312  if (NULL != cl_p->hndlr_pp[struno]) {
313  retval =
314  cl_p->hndlr_pp[struno] (cl_p, msgR, cl_p->cimg_pp[struno],
315  cl_p->hdarg_pp[struno]);
316  }
317  return retval;
318 }
319 
326 unsigned char hipcClientGetNsysmsg(struct HIPC_client const *const cl_p)
327 {
328  return cl_p->indp_p->n_sysmsg;
329 }
330 
338 enum HIPC_errno
339 hipcClientInit(struct HIPC_client *const cl_p,
340  struct HIPC_client const *const clbase_p)
341 {
342  void *tmp_p;
343  unsigned int i;
344 
345  if (NULL == clbase_p) {
346  cl_p->pllist_p = NULL; /* hipcClientTerminate() may be called. */
348  "clbase_p is NULL");
349  }
350  *cl_p = *clbase_p;
351 
352  cl_p->std_errno = 0;
353  cl_p->hipc_errno = HIPC_SUCCESS;
354  cl_p->err_detail_str[0] = '\0';
355 
356  cl_p->pllist_p = NULL;
357 
358  if (NULL == cl_p->indp_p) {
360  "cl_p->indp_p is NULL");
361  }
362  if (NULL == cl_p->cmdp_p) {
364  "cl_p->cmdp_p is NULL");
365  }
366  cl_p->cmdp_p->endian = hipcEndian();
367  if (0x6f /* 'o' */ == cl_p->cmdp_p->endian) {
369  "cl_p->cmdp_p->endian is 'o'");
370  }
371 
372  cl_p->cimg_pp =
373  hipcClientCalloc(cl_p,
374  cl_p->indp_p->n_struct, sizeof(*(cl_p->cimg_pp)));
375  if (NULL == cl_p->cimg_pp) {
376  return cl_p->hipc_errno;
377  }
378 
379  tmp_p = hipcClientCalloc(cl_p, cl_p->indp_p->n_struct,
380  sizeof(*(cl_p->simg_pp)));
381  if (NULL == tmp_p) {
382  return cl_p->hipc_errno;
383  }
384  cl_p->simg_pp = tmp_p;
385 
386  cl_p->hndlr_pp =
387  hipcClientCalloc(cl_p,
388  cl_p->indp_p->n_struct,
389  sizeof(*(cl_p->hndlr_pp)));
390  if (NULL == cl_p->hndlr_pp) {
391  return cl_p->hipc_errno;
392  }
393 
394  tmp_p = hipcClientCalloc(cl_p, cl_p->indp_p->n_struct,
395  sizeof(*(cl_p->hdarg_pp)));
396  if (NULL == tmp_p) {
397  return cl_p->hipc_errno;
398  }
399  cl_p->hdarg_pp = tmp_p;
400 
401  if (NULL == clbase_p->smdp_p) {
402  cl_p->smdp_p =
403  hipcClientCalloc(cl_p, 1, sizeof(struct HIPC_cl_dp));
404  if (NULL == cl_p->smdp_p) {
405  return cl_p->hipc_errno;
406  }
407  cl_p->smdp_p->struct_p =
408  hipcClientCalloc(cl_p, cl_p->indp_p->n_struct,
409  sizeof(struct HIPC_cl_dp_stru));
410  if (NULL == cl_p->smdp_p->struct_p) {
411  return cl_p->hipc_errno;
412  }
413  } else {
414  if (cl_p->smdp_p->endian == cl_p->cmdp_p->endian) {
415  cl_p->endian_convert = 0;
416  } else {
417  cl_p->endian_convert = 1;
418  }
419 
420  for (i = 0; i < cl_p->indp_p->n_struct; ++i) {
421  assert(NULL != cl_p->smdp_p->struct_size_p);
422  tmp_p = hipcClientMalloc(cl_p, cl_p->smdp_p->struct_size_p[i]);
423  if (NULL == tmp_p) {
424  return cl_p->hipc_errno;
425  }
426  cl_p->simg_pp[i] = tmp_p;
427  }
428  }
429 
430  return HIPC_SUCCESS;
431 }
432 
438 void hipcClientTerminate(struct HIPC_client *const cl_p)
439 {
440  struct HIPC_ptr_link_list *pllist_p;
441 
442  while (NULL != cl_p->pllist_p) {
443  pllist_p = cl_p->pllist_p;
444  cl_p->pllist_p = pllist_p->next;
445  free(pllist_p->ptr);
446  free(pllist_p);
447  }
448  return;
449 }
450 
459 {
460  unsigned int i;
461  unsigned int j;
462  const struct HIPC_cl_indp_stru *mis_p;
463 
464  assert(NULL != cl_p->smdp_p->struct_p);
465  for (j = 0; j < cl_p->indp_p->n_struct; ++j) {
466  assert(NULL != cl_p->smdp_p->struct_p[j].size_p);
467  mis_p = &(cl_p->indp_p->struct_p[j]);
468  for (i = 0; i < mis_p->n_member; ++i) {
469  if (HIPC_MBR_SIMPLE == mis_p->mbr_p[i].type ||
470  (HIPC_MBR_ARRAY == mis_p->mbr_p[i].type &&
471  HIPC_MBR_SIMPLE == mis_p->mbr_p[i].elm_type)) {
472  if (cl_p->cmdp_p->struct_p[j].size_p[i] !=
473  cl_p->smdp_p->struct_p[j].size_p[i]) {
474 #ifdef DEBUG
475  fprintf(stderr,
476  "MBR_SIZE_MISMATCH: "
477  "%s.%s; "
478  "struno/mbrnum %d/%d; "
479  "client-side size/server-side size %d/%d\n",
480  mis_p->name,
481  mis_p->mbr_p[i].name,
482  j, i,
483  cl_p->cmdp_p->struct_p[j].size_p[i],
484  cl_p->smdp_p->struct_p[j].size_p[i]);
485 #endif
487  "The member size in server is not the same as the size in client; member name: ",
488  mis_p->mbr_p[i].name, 0);
490  return cl_p->hipc_errno;
491  }
492  }
493  }
494  }
495  return HIPC_SUCCESS;
496 }
497 
508 enum HIPC_errno
510  const unsigned char struno,
511  const size_t offset, const size_t rngsize)
512 {
513  if (struno >= cl_p->indp_p->n_struct) {
514 #ifdef DEBUG
515  fprintf(stderr,
516  "INV_STRUNO: (struno=)%d >= %d(=cl_p->indp_p->n_struct)\n",
517  struno, cl_p->indp_p->n_struct);
518 
519 #endif
521  "INV_STRUNO: The structure number is equal to or more than cl_p->indp_p->n_struct");
522  }
523  if (offset >= cl_p->smdp_p->struct_size_p[struno]) {
524 #ifdef DEBUG
525  fprintf(stderr,
526  "INV_OFFSET: (offset=)%ld >= %d(=cl_p->smdp_p->struct_size_p[struno])\n",
527  offset, cl_p->smdp_p->struct_size_p[struno]);
528 #endif
530  "INV_OFFSET: The offest value is equal to or more than cl_p->smdp_p->struct_size_p[struno]");
531  }
532  if (rngsize > cl_p->smdp_p->struct_size_p[struno]) {
533 #ifdef DEBUG
534  fprintf(stderr,
535  "INV_SIZE: (rngsize=)%ld > %d(=cl_p->smdp_p->struct_size_p[struno])\n",
536  rngsize, cl_p->smdp_p->struct_size_p[struno]);
537 #endif
539  "INV_RNGSIZE: The rngsize is more than cl_p->smdp_p->struct_size_p[struno]");
540  }
541  if (offset + rngsize > cl_p->smdp_p->struct_size_p[struno]) {
542 #ifdef DEBUG
543  fprintf(stderr,
544  "INV_OFFSET_RNGSIZE: (offset=)%ld+(rngsize=)%ld > %d(=ccl_p->smdp_p->struct_size_p[struno])\n",
545  offset, rngsize, cl_p->smdp_p->struct_size_p[struno]);
546 #endif
548  "INV_OFFSET_SIZE: The sum of offset and rngsizeis is more than cl_p->smdp_p->struct_size_p[struno]");
549  }
550 
551  return HIPC_SUCCESS;
552 }
553 
564 static enum HIPC_errno
565 GetStrutpl_mbr(struct HIPC_client *const cl_p,
566  char const *const str, struct HIPC_cl_indp_mbr
567  const *const mbr_p, size_t * offset_p, size_t * size_p)
568 {
569  size_t n;
570  unsigned long ary_idx;
571  enum HIPC_errno retval;
572  unsigned int i;
573  char *end_p;
574  struct HIPC_cl_indp_stru const *indstc_p;
575  struct HIPC_cl_dp_stru const *rmdstc_p;
576  struct HIPC_cl_indp_mbr nxtmbr;
577 
578  switch (mbr_p->type) {
579  case HIPC_MBR_SIMPLE:
580  hipcClientSetErrDtlStr(cl_p, "Inappropriate string: ", str, 0);
582  return cl_p->hipc_errno;
583  break;
584  case HIPC_MBR_STRUCT:
585  if ('.' != str[0]) {
587  "No period before the member name: ",
588  str, 0);
590  return cl_p->hipc_errno;
591  }
592 
593  n = strcspn(str + 1, ".[");
594 
595  indstc_p = &cl_p->indp_p->struct_p[mbr_p->struno];
596  rmdstc_p = &cl_p->smdp_p->struct_p[mbr_p->struno];
597  for (i = 0;; ++i) {
598  if (i >= indstc_p->n_member) {
599  hipcClientSetErrDtlStr(cl_p, "Unknown member name: ",
600  str + 1, n);
602  return cl_p->hipc_errno;
603  }
604  if (0 == strncmp(str + 1, indstc_p->mbr_p[i].name, n)) {
605  break;
606  }
607  }
608 
609  *offset_p += rmdstc_p->offset_p[i];
610  *size_p = rmdstc_p->size_p[i];
611  if ('\0' == str[n + 1]) {
612  return HIPC_SUCCESS;
613  }
614 
615  retval =
616  GetStrutpl_mbr(cl_p, &str[n + 1], &indstc_p->mbr_p[i],
617  offset_p, size_p);
618  if (HIPC_SUCCESS != retval) {
619  return retval;
620  }
621  break;
622  case HIPC_MBR_ARRAY:
623  if ('[' != str[0]) {
625  "No left bracket following the array name: ",
626  str, 0);
628  return cl_p->hipc_errno;
629  }
630  ary_idx = strtoul(&str[1], &end_p, 10);
631  if (ULONG_MAX == ary_idx || &str[1] == end_p) {
633  "Failed to extract index from: ",
634  str, 0);
636  return cl_p->hipc_errno;
637  }
638  if (']' != *end_p) {
640  "No right bracket following the index number: ",
641  str, 0);
643  return cl_p->hipc_errno;
644  }
645 
646  if (0 == mbr_p->ary_dim) {
648  "Number of dimensions is zero: mbr_p->ary_dim is zero");
649  }
650  if (ary_idx >= mbr_p->ary_max_idxs[mbr_p->ary_dim - 1]) {
652  "The index is out of range: ", str, 0);
654  return cl_p->hipc_errno;
655  }
656 
657  *size_p /= mbr_p->ary_max_idxs[mbr_p->ary_dim - 1];
658  *offset_p += (*size_p) * ary_idx;
659  if ('\0' == *(end_p + 1)) {
660  return HIPC_SUCCESS;
661  }
662 
663  if (1 == mbr_p->ary_dim) {
664  nxtmbr.type = mbr_p->elm_type;
665  nxtmbr.struno = mbr_p->elm_struno;
666  } else {
667  nxtmbr = *mbr_p;
668  nxtmbr.ary_dim -= 1;
669  }
670 
671  retval =
672  GetStrutpl_mbr(cl_p, &str[(end_p - str) + 1], &nxtmbr,
673  offset_p, size_p);
674  if (HIPC_SUCCESS != retval) {
675  return retval;
676  }
677  break;
678  default:
680  "Invalid member type: invalid value in mbr_p->type");
681  break;
682  }
683 
684  return HIPC_SUCCESS;
685 }
686 
697 enum HIPC_errno
699  char const *const str,
700  unsigned char *struno_p,
701  size_t * offset_p, size_t * size_p)
702 {
703  unsigned int i;
704  size_t n;
705  struct HIPC_cl_indp_mbr mbr;
706  enum HIPC_errno retval;
707 
708  n = strcspn(str, ".");
709 
710  for (i = 0;; ++i) {
711  if (i >= cl_p->indp_p->n_struct) {
712  hipcClientSetErrDtlStr(cl_p, "Unknown structure name: ",
713  str, n);
715  return cl_p->hipc_errno;
716  }
717  if (0 == strncmp(str, cl_p->indp_p->struct_p[i].name, n)) {
718  break;
719  }
720  }
721 
722  *struno_p = i;
723  if ('\0' == str[n]) {
724  *offset_p = 0;
725  *size_p = cl_p->smdp_p->struct_size_p[i];
726  } else {
727  mbr.type = HIPC_MBR_STRUCT;
728  mbr.struno = i;
729  *offset_p = 0;
730 
731  retval = GetStrutpl_mbr(cl_p, str + n, &mbr, offset_p, size_p);
732  if (HIPC_SUCCESS != retval) {
733  return retval;
734  }
735  }
736 
737  return hipcClientCheckStrutpl(cl_p, *struno_p, *offset_p, *size_p);
738 }
739 
755 enum HIPC_errno
756 hipcClientEachMbr(struct HIPC_client *const cl_p,
757  struct HIPC_cl_indp_mbr const *const
758  mbr_p,
759  unsigned char *const begin, unsigned char *const end,
760  unsigned char *const scur_p, unsigned char *const ccur_p,
761  const size_t ssize, const size_t csize,
762  void (*fnc_p) (void *const ccur_p, void *const scur_p,
763  const size_t n))
764 {
765  size_t i;
766  struct HIPC_cl_indp_stru const *indstc_p;
767  struct HIPC_cl_dp_stru const *rmdstc_p;
768  struct HIPC_cl_dp_stru const *lmdstc_p;
769  struct HIPC_cl_indp_mbr elm;
770  unsigned char *stmp_p;
771  unsigned char *ctmp_p;
772  size_t celm_size;
773  size_t selm_size;
774  enum HIPC_errno retval;
775 
776  switch (mbr_p->type) {
777  case HIPC_MBR_SIMPLE:
778  if ((begin <= scur_p) && (end >= scur_p + ssize)) {
779  fnc_p(scur_p, ccur_p, ssize);
780  }
781  break;
782  case HIPC_MBR_STRUCT:
783  indstc_p = &cl_p->indp_p->struct_p[mbr_p->struno];
784  rmdstc_p = &cl_p->smdp_p->struct_p[mbr_p->struno];
785  lmdstc_p = &cl_p->cmdp_p->struct_p[mbr_p->struno];
786  for (i = 0; i < indstc_p->n_member; ++i) {
787  if (end <= scur_p + rmdstc_p->offset_p[i]) {
788  return HIPC_SUCCESS;
789  }
790  if ((end > scur_p + rmdstc_p->offset_p[i]) &&
791  (begin <
792  scur_p + rmdstc_p->offset_p[i] + rmdstc_p->size_p[i])) {
793  retval =
794  hipcClientEachMbr(cl_p, &indstc_p->mbr_p[i],
795  begin, end,
796  scur_p + rmdstc_p->offset_p[i],
797  ccur_p + lmdstc_p->offset_p[i],
798  rmdstc_p->size_p[i],
799  lmdstc_p->size_p[i], fnc_p);
800  if (HIPC_SUCCESS != retval) {
801  return retval;
802  }
803  }
804  }
805  break;
806  case HIPC_MBR_ARRAY:
807  celm_size = csize;
808  selm_size = ssize;
809  for (i = 0; i < mbr_p->ary_dim; ++i) {
810  celm_size /= mbr_p->ary_max_idxs[i];
811  selm_size /= mbr_p->ary_max_idxs[i];
812  }
813  if (0 == celm_size) {
815  "ZERO_SIZE: celm_size is zero");
816  }
817  if (0 == selm_size) {
819  "ZERO_SIZE: selm_size is zero");
820  }
821  elm.type = mbr_p->elm_type;
822  elm.struno = mbr_p->elm_struno;
823 
824  if (begin <= scur_p) {
825  stmp_p = scur_p;
826  ctmp_p = ccur_p;
827  } else {
828  stmp_p = begin - ((begin - scur_p) % selm_size);
829  ctmp_p =
830  ccur_p + (((stmp_p - scur_p) / selm_size) * celm_size);
831  }
832  while (end > stmp_p && scur_p + ssize > stmp_p) {
833  retval = hipcClientEachMbr(cl_p, &elm, begin, end,
834  stmp_p, ctmp_p, selm_size,
835  celm_size, fnc_p);
836  if (HIPC_SUCCESS != retval) {
837  return retval;
838  }
839  stmp_p += selm_size;
840  ctmp_p += celm_size;
841  }
842  break;
843  default:
845  "Invalid member type: invalid value in mbr_p->type");
846  break;
847  }
848 
849  return HIPC_SUCCESS;
850 }
851 
852 static void memcpy_wrapper(void *const scur_p, void *const ccur_p,
853  const size_t n)
854 {
855  memcpy(scur_p, ccur_p, n);
856  return;
857 }
858 
859 static void contra_memcpy(void *const scur_p, void *const ccur_p,
860  const size_t n)
861 {
862  memcpy(ccur_p, scur_p, n);
863  return;
864 }
865 
866 static void convert_endian(void *const scur_p, void *const ccur_p,
867  const size_t n)
868 {
869  size_t i;
870 
871  for (i = 0; i < n; ++i) {
872  ((unsigned char *) scur_p)[i] =
873  ((unsigned char *) ccur_p)[n - 1 - i];
874  }
875 
876  return;
877 }
878 
879 static void contra_convert_endian(void *const scur_p, void *const ccur_p,
880  const size_t n)
881 {
882  size_t i;
883 
884  for (i = 0; i < n; ++i) {
885  ((unsigned char *) ccur_p)[i] =
886  ((unsigned char *) scur_p)[n - 1 - i];
887  }
888 
889  return;
890 }
891 
907 enum HIPC_errno
908 hipcClientUnpack(struct HIPC_client *const cl_p,
909  const unsigned char struno, const size_t offset,
910  const size_t size, void *simg, void *cimg)
911 {
912  struct HIPC_cl_indp_mbr mbr;
913  void (*fnc_p) (void *const ccur_p, void *const scur_p, const size_t n);
914  enum HIPC_errno retval;
915 
916  retval = hipcClientCheckStrutpl(cl_p, struno, offset, size);
917  if (HIPC_SUCCESS != retval) {
918  return retval;
919  }
920 
921  if (NULL == cimg) {
922  if (NULL == cl_p->cimg_pp[struno]) {
923  return HIPC_SUCCESS;
924  } else {
925  cimg = cl_p->cimg_pp[struno];
926  }
927  }
928  if (NULL == simg) {
929  simg = cl_p->simg_pp[struno];
930  }
931 
932  mbr.type = HIPC_MBR_STRUCT;
933  mbr.struno = struno;
934 
935  if (0 == cl_p->endian_convert) {
936  fnc_p = contra_memcpy;
937  } else {
938  fnc_p = contra_convert_endian;
939  }
940  return hipcClientEachMbr(cl_p, &mbr,
941  (unsigned char *) simg + offset,
942  (unsigned char *) simg + offset + size,
943  simg, cimg, 0, 0, fnc_p);
944 }
945 
961 enum HIPC_errno
962 hipcClientPack(struct HIPC_client *const cl_p,
963  const unsigned char struno,
964  const size_t offset, const size_t size,
965  void *simg, void *cimg)
966 {
967  struct HIPC_cl_indp_mbr mbr;
968  void (*fnc_p) (void *const scur_p, void *const ccur_p, const size_t n);
969  enum HIPC_errno retval;
970 
971  retval = hipcClientCheckStrutpl(cl_p, struno, offset, size);
972  if (HIPC_SUCCESS != retval) {
973  return retval;
974  }
975 
976  if (NULL == cimg) {
977  if (NULL == cl_p->cimg_pp[struno]) {
978  return HIPC_SUCCESS;
979  } else {
980  cimg = cl_p->cimg_pp[struno];
981  }
982  }
983  if (NULL == simg) {
984  simg = cl_p->simg_pp[struno];
985  }
986 
987  mbr.type = HIPC_MBR_STRUCT;
988  mbr.struno = struno;
989 
990  if (0 == cl_p->endian_convert) {
991  fnc_p = memcpy_wrapper;
992  } else {
993  fnc_p = convert_endian;
994  }
995  return hipcClientEachMbr(cl_p, &mbr,
996  (unsigned char *) simg + offset,
997  (unsigned char *) simg + offset + size,
998  simg, cimg, 0, 0, fnc_p);
999 }
1000 
1010 enum HIPC_errno
1012  const hipc_msg msgR)
1013 {
1014  if (HIPC_UNSTRU != msgR[HIPC_MSGHDR_BYTE_STRUNO]) {
1015  return hipcClientSetError(cl_p,
1017  "INVALID_MSGBDY_TYPE: A message fed to hipcClientFeedUnstrumsgAsError() must have an unstructured body");
1018  }
1019 
1020  cl_p->hipc_errno = msgR[HIPC_MSGHDR_BYTE_OFFSET];
1021  assert(HIPC_IMG_ALLOCSIZE > msgR[HIPC_MSGHDR_SIZE]);
1022  memcpy(cl_p->err_detail_str, &msgR[HIPC_MSGHDR_SIZE],
1023  msgR[HIPC_MSGHDR_BYTE_BDYSZ]);
1024  cl_p->err_detail_str[msgR[HIPC_MSGHDR_BYTE_BDYSZ]] = '\0';
1025 
1026  return cl_p->hipc_errno;
1027 }
1028 
1037 static enum HIPC_errno
1039  const hipc_msg msg, unsigned char **const tgtadr)
1040 {
1041  void *tmp_p;
1042  const unsigned char struno = msg[HIPC_MSGHDR_BYTE_STRUNO];
1043  const unsigned char bdysz = msg[HIPC_MSGHDR_BYTE_BDYSZ];
1044 
1045  if (cl_p->indp_p->n_struct <= struno) {
1046 #ifdef DEBUG
1047  fprintf(stderr,
1048  "INV_STRUNO: (cl_p->indp_p->n_struct=)%d <= %d(=struno)\n",
1049  cl_p->indp_p->n_struct, struno);
1050 #endif
1052  "INV_STRUNO: The structure number in the system message is over cl_p->indp_p->n_struct");
1053  }
1054 
1055  if (cl_p->indp_p->struct_p[struno].n_member != bdysz) {
1056 #ifdef DEBUG
1057  fprintf(stderr,
1058  "INV_N_MEMBER: (cl_p->indp_p->struct_p[struno].n_member=)%d != %d(=bdysz)\n",
1059  cl_p->indp_p->struct_p[struno].n_member, bdysz);
1060 #endif
1062  "INV_N_MEMBER: The number of members in the system message is not same as the number in cl_p");
1063  }
1064 
1065  tmp_p = hipcClientMalloc(cl_p, bdysz);
1066  if (NULL == tmp_p) {
1067  return cl_p->hipc_errno;
1068  }
1069  memcpy(tmp_p, &msg[HIPC_MSGHDR_SIZE], bdysz);
1070  if (NULL != *tgtadr) {
1072  "INVALID_SYSMSG: The information has been already set in cl_p");
1073  }
1074  *tgtadr = tmp_p;
1075 
1076  return HIPC_SUCCESS;
1077 }
1078 
1086 enum HIPC_errno
1087 hipcClientFeedSysmsg(struct HIPC_client *const cl_p, const hipc_msg msgR)
1088 {
1089  unsigned int i;
1090  void *tmp_p;
1091  enum HIPC_errno retval;
1092  unsigned char **tgtadr;
1093  const unsigned char struno = msgR[HIPC_MSGHDR_BYTE_STRUNO];
1094  const unsigned char bdysz = msgR[HIPC_MSGHDR_BYTE_BDYSZ];
1095 
1097  return hipcClientSetError(cl_p,
1099  "INVALID_MSG_TYPE: Type must be SYS or QUIT");
1100  }
1101 
1102  switch (msgR[HIPC_MSGHDR_BYTE_OFFSET]) {
1104  cl_p->smdp_p->endian = struno;
1105  if ((0x42 /* 'B' */ != cl_p->smdp_p->endian) &&
1106  (0x6c /* 'l' */ != cl_p->smdp_p->endian)) {
1108  "cl_p->smdp_p->endian is not 'B' nor 'l'");
1109  }
1110 
1111  if (cl_p->smdp_p->endian == cl_p->cmdp_p->endian) {
1112  cl_p->endian_convert = 0;
1113  } else {
1114  cl_p->endian_convert = 1;
1115  }
1116  if (cl_p->indp_p->n_struct != bdysz) {
1117 #ifdef DEBUG
1118  fprintf(stderr,
1119  "UNMATCHED_SYSMSG: (cl_p->indp_p->n_struct=)%d != %d(=bdysz)\n",
1120  cl_p->indp_p->n_struct, bdysz);
1121 #endif
1123  "UNMATCHED_SYSMSG: cl_p->indp_p->n_struct is not the same as the number in the system message");
1124  }
1125  tmp_p =
1126  hipcClientMalloc(cl_p,
1127  sizeof(unsigned char) *
1128  (cl_p->indp_p->n_struct));
1129  if (NULL == tmp_p) {
1130  return cl_p->hipc_errno;
1131  }
1132  memcpy(tmp_p, &msgR[HIPC_MSGHDR_SIZE], bdysz);
1133  cl_p->smdp_p->struct_size_p = tmp_p;
1134  for (i = 0; i < cl_p->indp_p->n_struct; ++i) {
1135  tmp_p = hipcClientMalloc(cl_p, cl_p->smdp_p->struct_size_p[i]);
1136  if (NULL == tmp_p) {
1137  return cl_p->hipc_errno;
1138  }
1139  cl_p->simg_pp[i] = tmp_p;
1140  }
1141  break;
1143  tgtadr = &(cl_p->smdp_p->struct_p[struno].offset_p);
1144  retval = FeedSysmsg_OFFSET_SIZE(cl_p, msgR, tgtadr);
1145  if (HIPC_SUCCESS != retval) {
1146  return retval;
1147  }
1148  break;
1149  case HIPC_SYSMSG_TYPE_SIZE:
1150  tgtadr = &(cl_p->smdp_p->struct_p[struno].size_p);
1151  retval = FeedSysmsg_OFFSET_SIZE(cl_p, msgR, tgtadr);
1152  if (HIPC_SUCCESS != retval) {
1153  return retval;
1154  }
1155  break;
1156  default:
1158  "Invalid system message");
1159  break;
1160  }
1161 
1162  return HIPC_SUCCESS;
1163 }
1164 
1173 enum HIPC_errno
1174 hipcClientFeedStrumsg(struct HIPC_client *const cl_p, const hipc_msg msgR)
1175 {
1176  enum HIPC_errno retval;
1177 
1178  retval = hipcClientCheckStrutpl(cl_p,
1181  msgR[HIPC_MSGHDR_BYTE_BDYSZ]);
1182  if (HIPC_SUCCESS != retval) {
1183  return retval;
1184  }
1185  if (0 != msgR[HIPC_MSGHDR_BYTE_BDYSZ]) {
1186  memcpy(cl_p->simg_pp[msgR[HIPC_MSGHDR_BYTE_STRUNO]] +
1187  msgR[HIPC_MSGHDR_BYTE_OFFSET],
1188  &msgR[HIPC_MSGHDR_SIZE], msgR[HIPC_MSGHDR_BYTE_BDYSZ]);
1189  }
1190 
1191  return HIPC_SUCCESS;
1192 }
1193 
1201 void hipcGenmsgHello(hipc_msg msg, const struct HIPC_client *const cl_p)
1202 {
1204  msg[HIPC_MSGHDR_BYTE_OFFSET] = 0;
1207  memcpy(&msg[HIPC_MSGHDR_SIZE],
1208  cl_p->indp_p->cfgid, msg[HIPC_MSGHDR_BYTE_BDYSZ]);
1209  return;
1210 }
1211 
1222 enum HIPC_errno
1223 hipcGenmsgGet(hipc_msg msg, struct HIPC_client *const cl_p,
1224  const unsigned char struno,
1225  const size_t offset, const size_t size)
1226 {
1227  enum HIPC_errno retval;
1228 
1229  retval = hipcClientCheckStrutpl(cl_p, struno, offset, size);
1230  if (HIPC_SUCCESS != retval) {
1231  return retval;
1232  }
1233 
1235  msg[HIPC_MSGHDR_BYTE_OFFSET] = offset;
1237  msg[HIPC_MSGHDR_BYTE_BDYSZ] = size;
1238 
1239  return HIPC_SUCCESS;
1240 }
1241 
1252 enum HIPC_errno
1253 hipcGenmsgPut(hipc_msg msg, struct HIPC_client *const cl_p,
1254  const unsigned char struno,
1255  const size_t offset, const size_t size)
1256 {
1257  enum HIPC_errno retval;
1258 
1259  retval = hipcClientCheckStrutpl(cl_p, struno, offset, size);
1260  if (HIPC_SUCCESS != retval) {
1261  return retval;
1262  }
1263 
1265  msg[HIPC_MSGHDR_BYTE_OFFSET] = offset;
1267  msg[HIPC_MSGHDR_BYTE_BDYSZ] = size;
1268 
1269  memcpy(&msg[HIPC_MSGHDR_SIZE], cl_p->simg_pp[struno] + offset, size);
1270 
1271  return HIPC_SUCCESS;
1272 }
1273 
1280 {
1282  msg[HIPC_MSGHDR_BYTE_OFFSET] = 0;
1284  msg[HIPC_MSGHDR_BYTE_BDYSZ] = 0;
1285 
1286  return;
1287 }
enum HIPC_errno hipcClientFeedStrumsg(struct HIPC_client *const cl_p, const hipc_msg msgR)
Feeds a message and incorporates it to the internal data of a client.
Definition: client.c:1174
static void contra_convert_endian(void *const scur_p, void *const ccur_p, const size_t n)
Definition: client.c:879
Machine-dependent information of a structure used in a client.
Definition: client.h:55
unsigned char hipc_msg[HIPC_MSG_ALLOCSIZE]
Definition: msg.h:8
Machine-independent information of a member of a structure used in a client.
Definition: client.h:18
enum HIPC_errno hipcClientPack(struct HIPC_client *const cl_p, const unsigned char struno, const size_t offset, const size_t size, void *simg, void *cimg)
Packs a range of contents of cimg into simg.
Definition: client.c:962
void ** hdarg_pp
Handler's arguments.
Definition: client.h:83
int std_errno
Definition: client.h:84
enum HIPC_errno hipcClientFeedUnstrumsgAsError(struct HIPC_client *const cl_p, const hipc_msg msgR)
Feeds a message and sets an error specified by the message.
Definition: client.c:1011
enum HIPC_errno hipcClientFeedSysmsg(struct HIPC_client *const cl_p, const hipc_msg msgR)
Feeds a system message and incorporates it to the internal data of the client.
Definition: client.c:1087
#define HIPC_IMG_ALLOCSIZE
Definition: hipc.h:46
static const char * hipc_errstr[HIPC_N_ERR]
Definition: client.c:10
enum HIPC_errno hipcClientCallHandler(struct HIPC_client *const cl_p, const unsigned char struno, const hipc_msg msgR)
Calls a handler that corresponds to struno.
Definition: client.c:303
struct HIPC_cl_dp * cmdp_p
Client Machine DePendent data.
Definition: client.h:77
enum HIPC_errno hipcClientEachMbr(struct HIPC_client *const cl_p, struct HIPC_cl_indp_mbr const *const mbr_p, unsigned char *const begin, unsigned char *const end, unsigned char *const scur_p, unsigned char *const ccur_p, const size_t ssize, const size_t csize, void(*fnc_p)(void *const ccur_p, void *const scur_p, const size_t n))
Calls the function specified by fnc_p with each member between begin and end.
Definition: client.c:756
char err_detail_str[HIPC_IMG_ALLOCSIZE]
Definition: client.h:86
char const * name
Definition: client.h:37
enum HIPC_errno hipcClientGetHipcErrno(const struct HIPC_client *const cl_p)
Gets a HIPC error number that has been set.
Definition: client.c:143
const char * hipcClientGetErrStr(const struct HIPC_client *const cl_p)
Gets a string describing a HIPC error number that has been set to a HIPC client.
Definition: client.c:155
unsigned int n_member
Definition: client.h:36
static enum HIPC_errno GetStrutpl_mbr(struct HIPC_client *const cl_p, char const *const str, struct HIPC_cl_indp_mbr const *const mbr_p, size_t *offset_p, size_t *size_p)
Gets offset, and size from member structure and a string that specify further.
Definition: client.c:565
void hipcClientTerminate(struct HIPC_client *const cl_p)
Terminates a HIPC client with releasing the memory space that the client has.
Definition: client.c:438
const char * hipcClientGetErrDtlStr(const struct HIPC_client *const cl_p)
Gets a string describing details of an error that has been set to a HIPC client.
Definition: client.c:171
unsigned char hipcClientGetNsysmsg(struct HIPC_client const *const cl_p)
Gets the number of system messages.
Definition: client.c:326
int endian_convert
Definition: client.h:75
HIPC_errno
Definition: hipc.h:4
int hipcClientGetStdErrno(const struct HIPC_client *const cl_p)
Gets an errno value saved by hipcClientSetStdErrno().
Definition: client.c:131
static void * hipcClientCalloc(struct HIPC_client *const cl_p, size_t nmemb, size_t size)
Allocates memory by using calloc.
Definition: client.c:84
size_t const * ary_max_idxs
Definition: client.h:27
unsigned char struno
Definition: client.h:23
enum HIPC_errno hipcClientCheckMbrSize(struct HIPC_client *const cl_p)
Checks whether sizes of members in structures in a server are the same as sizes in a client...
Definition: client.c:458
static void * hipcClientMalloc(struct HIPC_client *const cl_p, size_t size)
Allocates memory by using malloc.
Definition: client.c:49
Machine-independent information of a structure used in a client.
Definition: client.h:35
void hipcGenmsgBye(hipc_msg msg)
Initializes a HIPC message as a BYE message.
Definition: client.c:1279
void hipcGenmsgHello(hipc_msg msg, const struct HIPC_client *const cl_p)
Generates HELLO message.
Definition: client.c:1201
struct HIPC_ptr_link_list * pllist_p
Definition: client.h:87
struct HIPC_cl_indp_mbr const * mbr_p
Definition: client.h:38
static void hipcClientSetErrDtlStr(struct HIPC_client *const cl_p, char const *const str0, char const *const str1, size_t ls1)
Sets a string describing details of an error, which will be a concatenation of str0 and str1...
Definition: client.c:196
static void memcpy_wrapper(void *const scur_p, void *const ccur_p, const size_t n)
Definition: client.c:852
enum HIPC_errno hipcClientSetError(struct HIPC_client *const cl_p, enum HIPC_errno hipc_errno, char const *const str)
Sets an error to a client with error detail.
Definition: client.c:240
enum HIPC_errno(** hndlr_pp)(struct HIPC_client *, const hipc_msg, void *, void *)
Definition: client.h:81
unsigned int n_struct
Definition: client.h:48
enum HIPC_member_type elm_type
Definition: client.h:28
char const * name
Definition: client.h:20
enum HIPC_errno hipcClientGetStrutpl(struct HIPC_client *const cl_p, char const *const str, unsigned char *struno_p, size_t *offset_p, size_t *size_p)
Gets structure number, offset, and size from ID string.
Definition: client.c:698
enum HIPC_member_type type
Definition: client.h:19
size_t ary_dim
Definition: client.h:26
unsigned char const * struct_size_p
Definition: client.h:65
struct HIPC_cl_indp_stru const * struct_p
Definition: client.h:49
void hipcClientSetHandler(struct HIPC_client *const cl_p, const unsigned char struno, enum HIPC_errno(*hndlr_p)(struct HIPC_client *, const hipc_msg, void *, void *), void *const arg)
Sets an handler hndlr_p to a structure number struno.
Definition: client.c:279
unsigned char elm_struno
Definition: client.h:29
enum HIPC_errno hipc_errno
Definition: client.h:85
unsigned int n_sysmsg
Definition: client.h:47
static enum HIPC_errno FeedSysmsg_OFFSET_SIZE(struct HIPC_client *const cl_p, const hipc_msg msg, unsigned char **const tgtadr)
Feeds a system message whose type is HIPC_SYSMSG_TYPE_OFFSET or HIPC_SYSMSG_TYPE_SIZE.
Definition: client.c:1038
unsigned char endian
Definition: client.h:64
void hipcClientSetCimg(struct HIPC_client *const cl_p, const unsigned char struno, void *cimg_p)
Sets a client-side image that is a structure instance of a structure.
Definition: client.c:260
static void contra_memcpy(void *const scur_p, void *const ccur_p, const size_t n)
Definition: client.c:859
const unsigned char * cfgid
Definition: client.h:45
enum HIPC_errno hipcClientInit(struct HIPC_client *const cl_p, struct HIPC_client const *const clbase_p)
Initializes a HIPC client with allocating memory space if necessary.
Definition: client.c:339
unsigned char ** simg_pp
Server-side images of structures.
Definition: client.h:79
unsigned int cfgid_size
Definition: client.h:46
struct HIPC_cl_indp const * indp_p
Definition: client.h:76
Machine-dependent information of a client.
Definition: client.h:63
enum HIPC_errno hipcGenmsgPut(hipc_msg msg, struct HIPC_client *const cl_p, const unsigned char struno, const size_t offset, const size_t size)
Generates PUT message.
Definition: client.c:1253
unsigned char hipcEndian(void)
Returns endian of the system.
Definition: hipc.c:25
struct HIPC_cl_dp_stru * struct_p
Definition: client.h:66
struct HIPC_cl_dp * smdp_p
Server Machine DePendent data.
Definition: client.h:78
enum HIPC_errno hipcClientUnpack(struct HIPC_client *const cl_p, const unsigned char struno, const size_t offset, const size_t size, void *simg, void *cimg)
Unpacks a range of contents of simg into cimg.
Definition: client.c:908
#define HIPC_UNSTRU
Definition: hipc.h:44
unsigned char * size_p
Definition: client.h:57
unsigned char * offset_p
Definition: client.h:56
unsigned char ** cimg_pp
Client-side images of structures.
Definition: client.h:80
static void convert_endian(void *const scur_p, void *const ccur_p, const size_t n)
Definition: client.c:866
enum HIPC_errno hipcClientCheckStrutpl(struct HIPC_client *const cl_p, const unsigned char struno, const size_t offset, const size_t rngsize)
Checks a combination of a structure number, an offset, and a size for a HIPC message.
Definition: client.c:509
enum HIPC_errno hipcGenmsgGet(hipc_msg msg, struct HIPC_client *const cl_p, const unsigned char struno, const size_t offset, const size_t size)
Generates GET message.
Definition: client.c:1223
void hipcClientSetStdErrno(struct HIPC_client *const cl_p)
Sets errno value to a HIPC client.
Definition: client.c:119