Example #1
0
int free_x11display(x11display_t * x11disp)
{
   int err;

   if (x11disp->idmap) {
      memblock_t mblock = memblock_INIT(sizeof(x11windowmap_t), (uint8_t*)x11disp->idmap);
      err = FREE_MM(&mblock);

      if (  x11disp->sys_display
            && XCloseDisplay(x11disp->sys_display)) {
         err = ECOMM;
         TRACESYSCALL_ERRLOG("XCloseDisplay", err);
      }

      x11disp->idmap = 0;
      x11disp->sys_display = 0;

      if (err) goto ONERR;
   }

   return 0 ;
ONERR:
   TRACEEXITFREE_ERRLOG(err);
   return err;
}
Example #2
0
int initfiltered_eglconfig(/*out*/eglconfig_t * eglconf, struct opengl_display_t * egldisp, const int32_t config_attributes[], eglconfig_filter_f filter, void * user)
{
   int err;
   EGLint      egl_attrib_list[2*gconfig__NROF];
   EGLConfig * eglconfig = 0;
   memblock_t  mblock;

   err = convertConfigListToEGL_eglconfig(&egl_attrib_list, config_attributes);
   if (err) goto ONERR;

   EGLint      num_config;
   EGLBoolean  isOK = eglChooseConfig( egldisp, egl_attrib_list, 0, 0, &num_config);
   if (!isOK) {
      err = EINVAL;
      goto ONERR;
   }

   // TODO: implement tempstack_memory_allocator
   //       allocate memory from tempstack instead of real stack
   err = ALLOC_ERR_MM(&s_eglconfig_errtimer, sizeof(EGLConfig) * (unsigned)num_config, &mblock);
   if (err) goto ONERR;

   eglconfig = (EGLConfig *) mblock.addr;
   isOK = eglChooseConfig( egldisp, egl_attrib_list, eglconfig, num_config, &num_config);
   if (!isOK) {
      err = EINVAL;
      goto ONERR;
   }

   EGLint i;
   for (i = 0; i < num_config; ++i) {
      EGLint visualid;
      isOK = eglGetConfigAttrib( egldisp, eglconfig[i], EGL_NATIVE_VISUAL_ID, &visualid);
      if (filter(eglconfig[i], visualid, user)) {
         // set out param
         *eglconf = eglconfig[i];
         break;
      }
   }

   (void) FREE_ERR_MM(&s_eglconfig_errtimer, &mblock);

   if (i == num_config) return ESRCH;

   return 0;
ONERR:
   if (eglconfig) (void) FREE_MM(&mblock);
   TRACEEXIT_ERRLOG(err);
   return err;
}
Example #3
0
int delete_syslogininfo(syslogin_info_t** info)
{
   int err;
   syslogin_info_t* delobj = *info;

   if (delobj) {
      *info = 0;

      memblock_t mblock = memblock_INIT(delobj->size, (uint8_t*)delobj);
      err = FREE_MM(&mblock);

      if (err) goto ONERR;
   }

   return 0;
ONERR:
   TRACEEXITFREE_ERRLOG(err);
   return err;
}
Example #4
0
int new_syslogininfo(/*out*/syslogin_info_t** info, sys_userid_t uid)
{
   int err;
   memblock_t mblock = memblock_FREE;

   slock_mutex(&s_syslogininfo_lock);

   errno = 0;
   struct passwd* pwd = getpwuid(uid);
   if (!pwd) {
      if (errno) {
         err = errno;
         TRACESYSCALL_ERRLOG("getpwuid(uid)", err);
         PRINTUINT32_ERRLOG(uid);
      } else {
         err = ENOENT;
      }
      goto UNLOCK;
   }

   size_t namesize = strlen(pwd->pw_name) + 1; // size username
   size_t nrofgrp = 0;

   #define GELEMSIZE (sizeof(sys_groupid_t) + sizeof(char*))

   setgrent();

   for (;;) {
      errno = 0;
      struct group* grp = getgrent();
      if (!grp) {
         if (errno) {
            err = errno;
            TRACESYSCALL_ERRLOG("getgrent", err);
            goto UNLOCK;
         }
         break;
      }

      bool ismatch = (grp->gr_gid == pwd->pw_gid);
      for (int i = 0; !ismatch && grp->gr_mem[i]; ++i) {
         ismatch = (0 == strcmp(grp->gr_mem[i], pwd->pw_name));
      }

      if (ismatch) {
         size_t len = strlen(grp->gr_name);
         if (nrofgrp == (SIZE_MAX/GELEMSIZE) || namesize >= SIZE_MAX/2 || len >= SIZE_MAX/2) {
            err = ENOMEM;
            goto UNLOCK;
         }
         nrofgrp ++;
         namesize += len + 1;
      }
   }

   size_t size = sizeof(syslogin_info_t) + namesize;
   size_t arrsize = nrofgrp * GELEMSIZE;
   if (size <= namesize) size = 0;
   size += arrsize;
   if (size <= arrsize) {
      err = ENOMEM;
      goto UNLOCK;
   }

   err = ALLOC_MM(size, &mblock);
   if (err) goto UNLOCK;

   syslogin_info_t* newobj = (syslogin_info_t*) mblock.addr;
   uint8_t* data = mblock.addr + sizeof(syslogin_info_t);
   size_t datasize = size - sizeof(syslogin_info_t);
   size_t dataoff;

   newobj->size  = size;
   newobj->uid   = uid;
   newobj->nrgroups = nrofgrp;
   newobj->gmain = 0;
   newobj->gname = (const char**) data;
   dataoff = nrofgrp * sizeof(char*);
   newobj->gid   = (sys_groupid_t*) (data + dataoff);
   dataoff += nrofgrp * sizeof(sys_groupid_t);
   size_t fieldsize = strlen(pwd->pw_name) + 1;
   if (fieldsize > (datasize - dataoff)) {
      err = EAGAIN;
      goto UNLOCK;
   }
   memcpy(data + dataoff, pwd->pw_name, fieldsize);
   newobj->uname = (char*) (data + dataoff);
   dataoff += fieldsize;

   setgrent();
   for (size_t gi = 0; gi < nrofgrp; ) {
      errno = 0;
      struct group* grp = getgrent();
      if (!grp) {
         err = errno ? errno : ENOENT;
         TRACESYSCALL_ERRLOG("getgrent", err);
         goto UNLOCK;
      }

      bool ismatch = (grp->gr_gid == pwd->pw_gid);
      for (int i = 0; !ismatch && grp->gr_mem[i]; ++i) {
         ismatch = (0 == strcmp(grp->gr_mem[i], pwd->pw_name));
      }

      if (ismatch) {
         fieldsize = strlen(grp->gr_name) + 1;
         if (fieldsize > (datasize - dataoff)) {
            err = EAGAIN;
            goto UNLOCK;
         }

         char* gname = (char*) (data + dataoff);
         dataoff += fieldsize;
         memcpy(gname, grp->gr_name, fieldsize);

         if (grp->gr_gid == pwd->pw_gid) {
            newobj->gmain = gi;
         }

         newobj->gid[gi]   = grp->gr_gid;
         newobj->gname[gi] = gname;
         ++gi;
      }
   }

   *info = newobj;

UNLOCK:
   endgrent();
   endpwent();
   sunlock_mutex(&s_syslogininfo_lock);

   if (err) goto ONERR;

   return 0;
ONERR:
   FREE_MM(&mblock);
   if (ENOENT != err) {
      TRACEEXIT_ERRLOG(err);
   }
   return err;
}
Example #5
0
static int test_read(directory_t * tempdir)
{
   filereader_t   frd = filereader_FREE;
   const size_t   B   = sizebuffer_filereader();
   memblock_t     mem = memblock_FREE;
   memstream_ro_t buffer = memstream_FREE;

   // prepare
   TEST(0 == RESIZE_MM(2*B+1, &mem));
   for (size_t i = 0; i < 2*B+1; ++i) {
      addr_memblock(&mem)[i] = (uint8_t)(13*i);
   }
   TEST(0 == save_file("single", B, addr_memblock(&mem), tempdir));
   TEST(0 == save_file("double", 2*B+1, addr_memblock(&mem), tempdir));

   // prepare: single buffer
   TEST(0 == init_filereader(&frd, "single", tempdir));

   // TEST release_filereader: changes nothing if frd.nrfreebuffer == 2
   release_filereader(&frd);
   TEST(0 == frd.unreadsize);
   TEST(0 == frd.nextindex);
   TEST(2 == frd.nrfreebuffer);
   TEST(0 == frd.fileoffset);

   for (int ti = 0; ti < 2; ++ti) {

      // TEST unread_filereader
      unread_filereader(&frd);
      if (0 == ti) {
         // call ignored if frd.nrfreebuffer == 2
         TEST(0 == frd.unreadsize);
      } else {
         // next call to readnext_filereader returns same buffer
         TEST(B == frd.unreadsize);
      }
      TEST(0 == frd.nextindex);
      TEST(2 == frd.nrfreebuffer);
      TEST(0 == frd.fileoffset);

      // TEST readnext_filereader: reads one buffer
      TEST(0 == readnext_filereader(&frd, &buffer));
      // check buffer
      TEST(B == size_memstream(&buffer));
      TEST(buffer.next == frd.page[0].addr);
      TEST(buffer.end  == frd.page[0].addr + frd.page[0].size);
      // check frd
      TEST(0 == frd.unreadsize); // all read
      TEST(1 == frd.nextindex); // nextindex incremented
      TEST(1 == frd.nrfreebuffer); // acquired 1 buffer
      TEST(B == castPoff_size(frd.fileoffset));
      // check content
      for (size_t i = 0; isnext_memstream(&buffer); ++i) {
         uint8_t byte = nextbyte_memstream(&buffer);
         TEST(byte == (uint8_t)(13*i));
      }

   }

   // TEST readnext_filereader: ENODATA
   TEST(ENODATA == readnext_filereader(&frd, &buffer));

   // TEST release_filereader: releases single buffer
   release_filereader(&frd);
   TEST(0 == frd.unreadsize);
   TEST(1 == frd.nextindex);
   TEST(2 == frd.nrfreebuffer);
   TEST(B == castPoff_size(frd.fileoffset));

   // TEST readnext_filereader: ENODATA
   TEST(ENODATA == readnext_filereader(&frd, &buffer));

   // unprepare
   TEST(0 == free_filereader(&frd));

   // prepare: double buffer
   TEST(0 == init_filereader(&frd, "double", tempdir));

   for (size_t i = 0, offset = 0; i < 3; ++i) {

      // TEST release_filereader: frd.nrfreebuffer == 2 ==> does nothing
      release_filereader(&frd);
      TEST( 0 == frd.unreadsize);
      TEST( 0 == frd.nextindex);
      TEST( 2 == frd.nrfreebuffer);
      TEST( offset == castPoff_size(frd.fileoffset));

      // TEST unread_filereader: frd.nrfreebuffer == 2 ==> does nothing
      unread_filereader(&frd);
      TEST( 0 == frd.unreadsize);
      TEST( 0 == frd.nextindex);
      TEST( 2 == frd.nrfreebuffer);
      TEST( offset == castPoff_size(frd.fileoffset));

      const size_t S = (i != 2 ? B/2 : 1);

      for (unsigned U = 1; U <= 1; --U) {   // test unread

         for (size_t n = 0, u = (U == 1 || S == 1)?0:S; n <= 1; ++n, u -= u?S:0) {
            // TEST readnext_filereader: reads one buffer
            TEST( 0 == readnext_filereader(&frd, &buffer));
            // check buffer
            TEST( buffer.next == frd.page[n].addr);
            TEST( buffer.end  == frd.page[n].addr + S);
            // check frd
            TEST( u == frd.unreadsize);
            TEST( (!n) == frd.nextindex);
            TEST( (!n) == frd.nrfreebuffer);
            TEST( (offset + S) == castPoff_size(frd.fileoffset));
            // check content
            for (; isnext_memstream(&buffer); ++offset) {
               uint8_t byte = nextbyte_memstream(&buffer);
               TEST(byte == (uint8_t)(13*offset));
            }
            if (S == 1) break;
         }

         // TEST readnext_filereader: more than 2 buffers or ENODATA
         const uint8_t N = frd.nextindex;
         buffer = (memstream_ro_t) memstream_FREE;
         TEST( (N?ENODATA:ENOBUFS) == readnext_filereader(&frd, &buffer));
         TEST( N == iseof_filereader(&frd));
         // check buffer
         TEST( 0 == buffer.next);
         TEST( 0 == buffer.end);
         // check frd
         TEST( 0 == frd.unreadsize);
         TEST( N == frd.nextindex);
         TEST( N == frd.nrfreebuffer);
         TEST( offset == castPoff_size(frd.fileoffset));

         if (U) {
            for (size_t n = N+1u, u = S; n <= 2; ++n, u += S) {
               // TEST unread_filereader: unreads second buffer
               unread_filereader(&frd);
               // check frd
               TEST( u == frd.unreadsize);
               TEST( (n==1) == frd.nextindex);
               TEST( n == frd.nrfreebuffer);
               offset -= S;
               TEST( offset == castPoff_size(frd.fileoffset));
            }
         }
      }

      const int N = frd.nextindex;
      for (int n = N+1; n <= 2; ++n) {
         // TEST release_filereader: mark last buffer as unused
         release_filereader(&frd);
         TEST( 0 == frd.unreadsize);
         TEST( (N==1) == frd.nextindex);
         TEST( n == frd.nrfreebuffer);
         TEST( offset == castPoff_size(frd.fileoffset));
      }
   }

   // unprepare
   TEST(0 == free_filereader(&frd));

   // TEST readnext_filereader: ioerror is returned
   TEST(0 == init_filereader(&frd, "double", tempdir));
   TEST( 0 == readnext_filereader(&frd, &buffer));
   for (unsigned i = 1; i < 15; ++i) {
      setioerror_filereader(&frd, (int) i);
      const unsigned err = (unsigned) readnext_filereader(&frd, &buffer);
      TEST( err == i);
   }
   TEST(0 == free_filereader(&frd));

   // unprepare
   TEST(0 == FREE_MM(&mem));
   TEST(0 == removefile_directory(tempdir, "single"));
   TEST(0 == removefile_directory(tempdir, "double"));

   return 0;
ONERR:
   FREE_MM(&mem);
   removefile_directory(tempdir, "single");
   removefile_directory(tempdir, "double");
   return EINVAL;
}