Beispiel #1
0
/*
 * Send a 2-bit frame by settings Num Lock to bit 0 and Caps Lock to bit 1.
 * Toggling Scroll Lock acts as a clock signal.
 */
void send_frame(const uint8_t frame) {
	set_lock(NUM,  (frame & 0x01) == 0x01);
	set_lock(CAPS, (frame & 0x02) == 0x02);
	set_lock(SCROLL, 1);
	printf("sending frame 0x%02x...", frame);
	printf("got 0x%02x from getchar\n", getchar());
	toggle_key(SCROLL);
}
Beispiel #2
0
/*!
 * Test a lock
 *
 * (1) Test against our own locks array
 * (2) Test fcntl lock, locks from other processes
 *
 * @param adf     (r) handle
 * @param off     (r) offset
 * @param len     (r) lenght
 *
 * @returns           1 if there's an existing lock, 0 if there's no lock,
 *                    -1 in case any error occured
 */
static int testlock(const struct ad_fd *adf, off_t off, off_t len)
{
    struct flock lock;
    adf_lock_t *plock;
    int i;

    lock.l_start = off;

    plock = adf->adf_lock;
    lock.l_whence = SEEK_SET;
    lock.l_len = len;

    /* (1) Do we have a lock ? */
    for (i = 0; i < adf->adf_lockcount; i++) {
        if (OVERLAP(lock.l_start, 1, plock[i].lock.l_start, plock[i].lock.l_len))
            return 1;
    }

    /* (2) Does another process have a lock? */
    lock.l_type = (adf->adf_flags & O_RDWR) ? F_WRLCK : F_RDLCK;

    if (set_lock(adf->adf_fd, F_GETLK, &lock) < 0) {
        /* is that kind of error possible ?*/
        return (errno == EACCES || errno == EAGAIN) ? 1 : -1;
    }

    if (lock.l_type == F_UNLCK) {
        return 0;
    }
    return 1;
}
Beispiel #3
0
/* remove a lock and compact space if necessary */
static void adf_freelock(struct ad_fd *ad, const int i)
{
    adf_lock_t *lock = ad->adf_lock + i;

    if (--(*lock->refcount) < 1) {
        free(lock->refcount);
        lock->lock.l_type = F_UNLCK;
        set_lock(ad->adf_fd, F_SETLK, &lock->lock); /* unlock */
    }

    ad->adf_lockcount--;

    /* move another lock into the empty space */
    if (i < ad->adf_lockcount) {
        memcpy(lock, lock + ad->adf_lockcount - i, sizeof(adf_lock_t));
    }

    /* free extra cruft if we go past a boundary. we always want to
     * keep at least some stuff around for allocations. this wastes
     * a bit of space to save time on reallocations. */
    if ((ad->adf_lockmax > ARRAY_FREE_DELTA) &&
            (ad->adf_lockcount + ARRAY_FREE_DELTA < ad->adf_lockmax)) {
        struct adf_lock_t *tmp;

        tmp = (struct adf_lock_t *)
              realloc(ad->adf_lock, sizeof(adf_lock_t)*
                      (ad->adf_lockcount + ARRAY_FREE_DELTA));
        if (tmp) {
            ad->adf_lock = tmp;
            ad->adf_lockmax = ad->adf_lockcount + ARRAY_FREE_DELTA;
        }
    }
}
Beispiel #4
0
void aldl_add_command(byte *command, byte length, int delay) {
  if(command == NULL) return;

  /* build new command */
  aldl_comq_t *n; /* new command */
  n = smalloc(sizeof(aldl_comq_t));
  n->length = length;
  n->delay = delay;
  n->command = smalloc(sizeof(char) * length);
  int x; for(x=0;x<length;x++) { /* copy command */
    n->command[x] = command[x];
  }
  n->next = NULL;

  /* link in new command */
  set_lock(LOCK_COMQ);
  if(comq == NULL) { /* no other commands exist */
    comq = n;
  } else {
    aldl_comq_t *e = comq; /* end of linked list */
    while(e->next != NULL) e = e->next; /* seek end */
    e->next = n; 
  } 
  unset_lock(LOCK_COMQ);
}
Beispiel #5
0
aldl_record_t *newest_record(aldl_conf_t *aldl) {
  aldl_record_t *rec = NULL;
  set_lock(LOCK_RECORDPTR);
  rec = aldl->r; 
  unset_lock(LOCK_RECORDPTR);
  return rec;
}
Beispiel #6
0
/** @brief Works like printf and puts message into log  */
void logprint(int verb, const char *format, ...)
{
   static char filebuf[8192];
   int erret;
   int towrite;
   char *localtime,*temp,*bufs;
   time_t current_time;
   
   if(verb > verbosity) return;   
   if(format)
     {
	va_list args;
	va_start(args, format);
	
	if (logusesyslog){
		vsyslog(verb,format, args);
		va_end(args);
		return;
	}

	current_time = time(NULL);
	if (current_time != -1){
		localtime = (char *)ctime(&current_time);
		temp = strchr(localtime,' ')+1;
		bufs = strrchr(localtime,' ');
		if (temp && bufs) strncpy(filebuf,temp, bufs-temp+1);
		vsnprintf(filebuf+(bufs-temp+1),8190-(bufs-temp), format, args);
		va_end(args);
		towrite=strlen(filebuf);
		if (filebuf[towrite-1]!='\n') {
			filebuf[towrite]='\n';
			filebuf[towrite+1]='\0';
		}
		if (!debug) if(set_lock(loggerhandle, F_WRLCK) == 0) return;
		towrite=strlen(filebuf);
		bufs=filebuf;
		while ( (erret=write(loggerhandle,bufs,towrite))!=towrite ){
			if (erret>=0) {
				towrite-=erret;
				bufs+=erret;
			}
		}

		if (!debug) set_lock(loggerhandle, F_UNLCK);
	}
     }
}
Beispiel #7
0
void link_record(aldl_record_t *rec, aldl_conf_t *aldl) {
  rec->next = NULL; /* terminate linked list */
  rec->prev = aldl->r; /* previous link */
  set_lock(LOCK_RECORDPTR);
  aldl->r->next = rec; /* attach to linked list */
  aldl->r = rec; /* fix master link */
  unset_lock(LOCK_RECORDPTR);
}
Beispiel #8
0
void
PrefAgent::lock_toggle (WCallback *wcb)
{
  XmToggleButtonCallbackStruct &cbs =
    *(XmToggleButtonCallbackStruct*) wcb->CallData();

  set_lock (cbs.set);
}
Beispiel #9
0
void set_connstate(aldl_state_t s, aldl_conf_t *aldl) {
  set_lock(LOCK_CONNSTATE);
  #ifdef DEBUGSTRUCT
  printf("set connection state to %i (%s)\n",s,get_state_string(s));
  #endif
  aldl->state = s;
  unset_lock(LOCK_CONNSTATE);
}
Beispiel #10
0
/* relock any byte lock that overlaps off/len. unlock everything
 * else. */
static void adf_relockrange(struct ad_fd *ad, int fd, off_t off, off_t len)
{
    adf_lock_t *lock = ad->adf_lock;
    int i;

    for (i = 0; i < ad->adf_lockcount; i++) {
        if (OVERLAP(off, len, lock[i].lock.l_start, lock[i].lock.l_len))
            set_lock(fd, F_SETLK, &lock[i].lock);
    }
}
Beispiel #11
0
void aldl_data_init(aldl_conf_t *aldl) {
  aldl_alloc_pool(aldl);
  aldl_record_t *rec = aldl_create_record(aldl);
  set_lock(LOCK_RECORDPTR);
  rec->next = NULL;
  rec->prev = NULL;
  aldl->r = rec;
  unset_lock(LOCK_RECORDPTR);
  firstrecordtime = get_time();
  comq = NULL; /* no records yet */
}
void dlthread_exclude(
    dlthread_comm_t const comm_idx)
{
  comm_t * gcomm;

  if (comm_idx != DLTHREAD_COMM_SINGLE) {
    gcomm = my_comms+comm_idx;

    set_lock(&gcomm->loc);
  }
}
Beispiel #13
0
Query&
Query::operator=(const Query& rhs)
{
	set_exceptions(rhs.throw_exceptions());
	set_lock(rhs.locked());
	def = rhs.def;
	conn_ = rhs.conn_;
	success_ = rhs.success_;

	return *this;
}
Beispiel #14
0
aldl_comq_t *aldl_get_command() {
  set_lock(LOCK_COMQ);
  if(comq == NULL) {
    unset_lock(LOCK_COMQ);
    return NULL; /* no command available */
  }
  aldl_comq_t *c = comq;
  comq = c->next; /* advance to next command */
  unset_lock(LOCK_COMQ);
  return c;
  /* WARNING you need to free this after you're done with it ... */
}
Beispiel #15
0
aldl_record_t *next_record(aldl_record_t *rec) {
  #ifdef DEBUGSTRUCT
  /* check for underrun ... */
  if(rec->prev == NULL) {
     error(1,ERROR_BUFFER,"underrun in record retrieve %p",rec);
  }
  #endif
  aldl_record_t *next;
  set_lock(LOCK_RECORDPTR);
  next = rec->next;
  unset_lock(LOCK_RECORDPTR);
  return next;
}
void dlthread_comm_finalize(
    dlthread_comm_t const comm_idx)
{
  size_t i, myid;
  comm_t * comm;

  if (comm_idx != DLTHREAD_COMM_SINGLE) {
    myid = dlthread_get_id(comm_idx);

    dlthread_barrier(comm_idx);

    comm = my_comms+comm_idx;

    if (comm->larray) {
      /* destroy locks if they exist */
      for (i=0;i<comm->nlarray;++i) {
        free_lock(comm->larray[myid]+i);
      }
      dl_free(comm->larray[myid]);

      dlthread_barrier(comm_idx);

      if (myid == 0) {
        dl_free(comm->larray);
      }
    }

    if (myid == 0) {
      dl_free(comm->buffer);
      free_barrier(&(comm->bar));
      free_lock(&(comm->loc));

      comm->in_use = 0;

      set_lock(ncomms_lock);
      if (comm_idx < last_free_comm) {
        last_free_comm = comm_idx;
      }
      unset_lock(ncomms_lock);
    }
  } else {
    /* clear this threads local buffer if it exists */
    if (__local_buffer) {
      dl_free(__local_buffer);
      __local_buffer = NULL;
      __local_buffer_size = 0;
    }
  }
}
void dlthread_lock_index(
    size_t const tid,
    size_t const idx,
    dlthread_comm_t const comm_idx)
{
  size_t i;
  comm_t * gcomm;

  if (comm_idx != DLTHREAD_COMM_SINGLE) {
    gcomm = my_comms+comm_idx;

    i = idx % gcomm->nlarray;

    set_lock(gcomm->larray[tid]+i);
  }
}
static dbe_t *dbx_init(bfpath *bfp)
{
    u_int32_t flags = 0;
    dbe_t *env = xcalloc(1, sizeof(dbe_t));

    env->magic = MAGIC_DBE;	    /* poor man's type checking */
    env->directory = xstrdup(bfp->dirname);

    /* open lock file, needed to detect previous crashes */
    if (init_dbl(bfp->dirname))
	exit(EX_ERROR);

    /* run recovery if needed */
    if (needs_recovery()) {
	dbx_recover(bfp, false, false); /* DO NOT set force flag here, may cause
						 multiple recovery! */

	/* reinitialize */
	if (init_dbl(bfp->dirname))
	    exit(EX_ERROR);
    }

    /* set (or demote to) shared/read lock for regular operation */
    db_try_glock(bfp, F_RDLCK, F_SETLKW);

    /* set our cell lock in the crash detector */
    if (set_lock()) {
	exit(EX_ERROR);
    }

    /* initialize */
#ifdef	FUTURE_DB_OPTIONS
#ifdef	DB_BF_TXN_NOT_DURABLE
    if (db_txn_durable)
	flags ^= DB_BF_TXN_NOT_DURABLE;
#endif
#endif

    dbe_xinit(env, bfp, flags);

    return env;
}
Beispiel #19
0
void
PrefAgent::reset()
{
  // Reset browse preferences.
  if (IS_CHANGED (f_browse_geo))
    set_geometry (f_browse_geo, ORIGINAL_VALUE (f_browse_geo, WindowGeometry));
  if (IS_CHANGED (f_fs_field))
    set_integer (f_fs_field, ORIGINAL_VALUE (f_fs_field, Integer));
  if (IS_CHANGED (f_lock_toggle)) {
    set_lock (ORIGINAL_VALUE (f_lock_toggle, Boolean));
    f_lock_toggle.Unmap();
    f_lock_toggle.Map();
  }

  // Reset map preferences.
  if (IS_CHANGED (f_map_geo))
    set_geometry (f_map_geo, ORIGINAL_VALUE (f_map_geo, WindowGeometry));
  if (IS_CHANGED (f_update_toggle))
    set_update (ORIGINAL_VALUE (f_update_toggle, Boolean));

  // Reset history preferences.
  if (IS_CHANGED (f_nh_field))
    set_integer (f_nh_field, ORIGINAL_VALUE (f_nh_field, Integer));
  if (IS_CHANGED (f_sh_field))
    set_integer (f_sh_field, ORIGINAL_VALUE (f_sh_field, Integer));

  // Reset Search preferences. 
  if (IS_CHANGED (f_max_hits_field))
    set_integer (f_max_hits_field, ORIGINAL_VALUE (f_max_hits_field, Integer));
  if (IS_CHANGED (f_adisplay_toggle))
    set_auto_display (ORIGINAL_VALUE (f_adisplay_toggle, Boolean));

  // Desensitize appropriate controls. 
  f_ok.SetSensitive (False);
  f_apply.SetSensitive (False);
  f_reset.SetSensitive (False);
}
Beispiel #20
0
bool _gmp_set_exclusive_lock(GumpDB db, int position) {
  return set_lock(fileno(db->file), F_SETLKW, F_WRLCK, 0, SEEK_SET, 0);
}
dlthread_comm_t dlthread_comm_split(
    size_t group,
    size_t ngroups,
    dlthread_comm_t const comm_idx)
{
  size_t i, lid, cidx, myid, nthreads;
  size_t volatile * tid;
  comm_t * lcomm;
  dlthread_comm_t volatile * gcom;
  dlthread_comm_t cid;

  if (comm_idx != DLTHREAD_COMM_SINGLE) {
    myid = dlthread_get_id(comm_idx);
    nthreads = dlthread_get_nthreads(comm_idx);

    DL_ASSERT(group < ngroups,"Invalid group %zu/%zu for thread %zu/%zu\n", \
        group,ngroups,myid,nthreads);

    gcom = dlthread_get_buffer((sizeof(dlthread_comm_t)*ngroups) + \
        (sizeof(size_t)*nthreads),comm_idx);
    tid = (size_t*)(gcom+ngroups);

    if (myid == 0) {
      /* number the new communicators */
      set_lock(ncomms_lock);
      for (i=0;i<ngroups;++i) {
        /* find the next free communicator */
        while (my_comms[last_free_comm].in_use == 1) {
          ++last_free_comm;
        }
        gcom[i] = last_free_comm++;
        /* initialize my comm */
        my_comms[gcom[i]].nthreads = 0;
        my_comms[gcom[i]].in_use = 1;
      }
      unset_lock(ncomms_lock);
    }

    /* I use an alarming number of barriers here -- someday reduce this */

    dlthread_barrier(comm_idx);

    cid = gcom[group];

    DL_ASSERT(cid < __MAX_NCOMMS,"Exceeded maximum number of communicators\n");

    lcomm = my_comms+cid;
    tid[myid] = group;

    dlthread_barrier(comm_idx);

    if (myid == 0) {
      /* number the threads per communicator */
      for (i=0;i<nthreads;++i) {
        cidx = gcom[tid[i]];
        tid[i] = my_comms[cidx].nthreads++;
      }
    }

    dlthread_barrier(comm_idx);

    lid = tid[myid];

    if (lid == 0) {
      /* root for each comm */
      __config_comm(lcomm,lcomm->nthreads);
    }

    my_ids[cid] = lid;

    dlthread_barrier(comm_idx);

    dprintf("[%zu:%zu] new communicator %zu with %zu threads\n",myid,lid, \
        (size_t)cid,lcomm->nthreads);
  } else {
    cid = DLTHREAD_COMM_SINGLE;
  } 

  return cid;
}
void dlthread_set_lock(
    dlthread_lock_t * const lock)
{
  set_lock(lock);
}
Beispiel #23
0
int ad_tmplock(struct adouble *ad, uint32_t eid, int locktype, off_t off, off_t len, int fork)
{
    struct flock lock;
    struct ad_fd *adf;
    int err;
    int type;

    LOG(log_debug, logtype_default, "ad_tmplock(%s, %s, off: %jd (%s), len: %jd): BEGIN",
        eid == ADEID_DFORK ? "data" : "reso",
        locktypetostr(locktype),
        (intmax_t)off,
        shmdstrfromoff(off),
        (intmax_t)len);

    lock.l_start = off;
    type = locktype;

    if (eid == ADEID_DFORK) {
        adf = &ad->ad_data_fork;
    } else {
        adf = &ad->ad_resource_fork;
        if (adf->adf_fd == -1) {
            /* there's no resource fork. return success */
            err = 0;
            goto exit;
        }
        /* if ADLOCK_FILELOCK we want a lock from offset 0
         * it's used when deleting a file:
         * in open we put read locks on meta datas
         * in delete a write locks on the whole file
         * so if the file is open by somebody else it fails
         */
        if (!(type & ADLOCK_FILELOCK))
            lock.l_start += ad_getentryoff(ad, eid);
    }

    if (!(adf->adf_flags & O_RDWR) && (type & ADLOCK_WR)) {
        type = (type & ~ADLOCK_WR) | ADLOCK_RD;
    }

    lock.l_type = XLATE_FCNTL_LOCK(type & ADLOCK_MASK);
    lock.l_whence = SEEK_SET;
    lock.l_len = len;

    /* see if it's locked by another fork. */
    if (fork && adf_findxlock(adf, fork,
                              ADLOCK_WR | ((type & ADLOCK_WR) ? ADLOCK_RD : 0),
                              lock.l_start, lock.l_len) > -1) {
        errno = EACCES;
        err = -1;
        goto exit;
    }

    /* okay, we might have ranges byte-locked. we need to make sure that
     * we restore the appropriate ranges once we're done. so, we check
     * for overlap on an unlock and relock.
     * XXX: in the future, all the byte locks will be sorted and contiguous.
     *      we just want to upgrade all the locks and then downgrade them
     *      here. */
    err = set_lock(adf->adf_fd, F_SETLK, &lock);
    if (!err && (lock.l_type == F_UNLCK))
        adf_relockrange(adf, adf->adf_fd, lock.l_start, len);

exit:
    LOG(log_debug, logtype_default, "ad_tmplock: END: %d", err);
    return err;
}
Beispiel #24
0
aldl_state_t get_connstate(aldl_conf_t *aldl) {
  set_lock(LOCK_CONNSTATE);
  aldl_state_t st = aldl->state;
  unset_lock(LOCK_CONNSTATE);
  return st;
}
Beispiel #25
0
void lock_stats() {
  set_lock(LOCK_STATS);
}
Beispiel #26
0
bool _gmp_set_shared_lock(GumpDB db, int position) {
  return set_lock(fileno(db->file), F_SETLKW, F_RDLCK, 0, SEEK_SET, 0);
}
Beispiel #27
0
int ad_lock(struct adouble *ad, uint32_t eid, int locktype, off_t off, off_t len, int fork)
{
    struct flock lock;
    struct ad_fd *adf;
    adf_lock_t *adflock;
    int oldlock;
    int i;
    int type;
    int ret = 0, fcntl_lock_err = 0;

    LOG(log_debug, logtype_default, "ad_lock(%s, %s, off: %jd (%s), len: %jd): BEGIN",
        eid == ADEID_DFORK ? "data" : "reso",
        locktypetostr(locktype),
        (intmax_t)off,
        shmdstrfromoff(off),
        (intmax_t)len);

    if ((locktype & ADLOCK_FILELOCK) && (len != 1))
        AFP_PANIC("lock API error");

    type = locktype;

    if (eid == ADEID_DFORK) {
        adf = &ad->ad_data_fork;
        lock.l_start = off;
    } else { /* rfork */
        if (type & ADLOCK_FILELOCK) {
            adf = &ad->ad_data_fork;
            lock.l_start = rf2off(off);
        } else {
            adf = ad->ad_rfp;
            lock.l_start = off + ad_getentryoff(ad, ADEID_RFORK);
        }
    }

    /* NOTE: we can't write lock a read-only file. on those, we just
     * make sure that we have a read lock set. that way, we at least prevent
     * someone else from really setting a deny read/write on the file.
     */
    if (!(adf->adf_flags & O_RDWR) && (type & ADLOCK_WR)) {
        type = (type & ~ADLOCK_WR) | ADLOCK_RD;
    }

    lock.l_type = XLATE_FCNTL_LOCK(type & ADLOCK_MASK);
    lock.l_whence = SEEK_SET;
    lock.l_len = len;

    /* byte_lock(len=-1) lock whole file */
    if (len == BYTELOCK_MAX) {
        lock.l_len -= lock.l_start; /* otherwise  EOVERFLOW error */
    }

    /* see if it's locked by another fork.
     * NOTE: this guarantees that any existing locks must be at most
     * read locks. we use ADLOCK_WR/RD because F_RD/WRLCK aren't
     * guaranteed to be ORable. */
    if (adf_findxlock(adf, fork, ADLOCK_WR |
                      ((type & ADLOCK_WR) ? ADLOCK_RD : 0),
                      lock.l_start, lock.l_len) > -1) {
        errno = EACCES;
        ret = -1;
        goto exit;
    }

    /* look for any existing lock that we may have */
    i = adf_findlock(adf, fork, ADLOCK_RD | ADLOCK_WR, lock.l_start, lock.l_len);
    adflock = (i < 0) ? NULL : adf->adf_lock + i;

    /* here's what we check for:
       1) we're trying to re-lock a lock, but we didn't specify an update.
       2) we're trying to free only part of a lock.
       3) we're trying to free a non-existent lock. */
    if ( (!adflock && (lock.l_type == F_UNLCK))
            ||
            (adflock
             && !(type & ADLOCK_UPGRADE)
             && ((lock.l_type != F_UNLCK)
                 || (adflock->lock.l_start != lock.l_start)
                 || (adflock->lock.l_len != lock.l_len) ))
       ) {
        errno = EINVAL;
        ret = -1;
        goto exit;
    }


    /* now, update our list of locks */
    /* clear the lock */
    if (lock.l_type == F_UNLCK) {
        adf_freelock(adf, i);
        goto exit;
    }

    /* attempt to lock the file. */
    if (set_lock(adf->adf_fd, F_SETLK, &lock) < 0) {
        ret = -1;
        goto exit;
    }

    /* we upgraded this lock. */
    if (adflock && (type & ADLOCK_UPGRADE)) {
        memcpy(&adflock->lock, &lock, sizeof(lock));
        goto exit;
    }

    /* it wasn't an upgrade */
    oldlock = -1;
    if (lock.l_type == F_RDLCK) {
        oldlock = adf_findxlock(adf, fork, ADLOCK_RD, lock.l_start, lock.l_len);
    }

    /* no more space. this will also happen if lockmax == lockcount == 0 */
    if (adf->adf_lockmax == adf->adf_lockcount) {
        adf_lock_t *tmp = (adf_lock_t *)
                          realloc(adf->adf_lock, sizeof(adf_lock_t)*
                                  (adf->adf_lockmax + ARRAY_BLOCK_SIZE));
        if (!tmp) {
            ret = fcntl_lock_err = -1;
            goto exit;
        }
        adf->adf_lock = tmp;
        adf->adf_lockmax += ARRAY_BLOCK_SIZE;
    }
    adflock = adf->adf_lock + adf->adf_lockcount;

    /* fill in fields */
    memcpy(&adflock->lock, &lock, sizeof(lock));
    adflock->user = fork;
    if (oldlock > -1) {
        adflock->refcount = (adf->adf_lock + oldlock)->refcount;
    } else if ((adflock->refcount = calloc(1, sizeof(int))) == NULL) {
        ret = fcntl_lock_err = 1;
        goto exit;
    }

    (*adflock->refcount)++;
    adf->adf_lockcount++;

exit:
    if (ret != 0) {
        if (fcntl_lock_err != 0) {
            lock.l_type = F_UNLCK;
            set_lock(adf->adf_fd, F_SETLK, &lock);
        }
    }
    LOG(log_debug, logtype_default, "ad_lock: END: %d", ret);
    return ret;
}
Beispiel #28
0
/*
 * _dyld_init() is the start off point for the dynamic link editor.  It is
 * called before any part of an executable program runs.  This is done either
 * in the executable runtime startoff or by the kernel as a result of an exec(2)
 * system call (which goes through __dyld_start to get here).
 *
 * This routine causes the dynamic shared libraries an executable uses to be
 * mapped, sets up the executable and the libraries to call the dynamic link
 * editor when a lazy reference to a symbol is first used, resolves all non-lazy
 * symbol references needed to start running the program and then returns to
 * the executable program to start up the program.
 */
unsigned long
_dyld_init(
struct mach_header *mh,
unsigned long argc,
char **argv,
char **envp)
{
    unsigned int count;
    kern_return_t r;
    unsigned long entry_point;
    mach_port_t my_mach_host_self;
#ifndef __MACH30__
    struct section *s;
#endif
#ifdef MALLOC_DEBUG
    extern void cthread_init(void);

	cthread_init();
#endif
	
	/* set lock for dyld data structures */
	set_lock();

	/*
	 * Get the cputype and cpusubtype of the machine we're running on.
	 */
	count = HOST_BASIC_INFO_COUNT;
	my_mach_host_self = mach_host_self();
	if((r = host_info(my_mach_host_self, HOST_BASIC_INFO, (host_info_t)
			  (&host_basic_info), &count)) != KERN_SUCCESS){
	    mach_port_deallocate(mach_task_self(), my_mach_host_self);
	    mach_error(r, "can't get host basic info");
	}
	mach_port_deallocate(mach_task_self(), my_mach_host_self);
#if defined(__GONZO_BUNSEN_BEAKER__) && defined(__ppc__)
	if(host_basic_info.cpu_type == CPU_TYPE_POWERPC &&
	   (host_basic_info.cpu_subtype == CPU_SUBTYPE_POWERPC_7400 ||
	    host_basic_info.cpu_subtype == CPU_SUBTYPE_POWERPC_7450 ||
	    host_basic_info.cpu_subtype == CPU_SUBTYPE_POWERPC_970))
	    processor_has_vec = TRUE;
#endif

	/*
	 * Pickup the environment variables for the dynamic link editor.
	 */
	pickup_environment_variables(envp);
	
	/*
	 * Make initial trace entry if requested.
	 */
	DYLD_TRACE_INIT_START(0);

	/*
	 * Create the executable's path from the exec_path and the current
	 * working directory (if needed).  If we did not pick up the exec_path
	 * (we are running with an old kernel) use argv[0] if has a slash in it
	 * as it is a path relative to the current working directory.  Of course
	 * argv[0] may not have anything to do with the filename being executed
	 * in all cases but it is likely to be right.
	 */
	if(exec_path != NULL)
	    create_executables_path(exec_path);
	else if(strchr(argv[0], '/') != NULL)
	    create_executables_path(argv[0]);
	if(dyld_executable_path_debug == TRUE)
	    printf("executables_path = %s\n",
		   executables_path == NULL ? "NULL" : executables_path);

#ifdef DYLD_PROFILING
	s = (struct section *) getsectbynamefromheader(
	    &_mh_dylinker_header, SEG_TEXT, SECT_TEXT);
	monstartup((char *)(s->addr + dyld_image_vmaddr_slide),
		   (char *)(s->addr + dyld_image_vmaddr_slide + s->size));
#endif

#ifndef __MACH30__
	/*
	 * See if the profile server for shared pcsample buffers exists.
	 * Then if so try to setup a pcsample buffer for dyld itself.
	 */
	profile_server = profile_server_exists();
	if(profile_server == TRUE){
	    s = (struct section *) getsectbynamefromheader(
		&_mh_dylinker_header, SEG_TEXT, SECT_TEXT);
	    shared_pcsample_buffer("/usr/lib/dyld", s, dyld_image_vmaddr_slide);
	}
#endif /* __MACH30__ */

	/*
	 * Start off by loading the executable image as the first object image
	 * that make up the program.  This in turn will load the dynamic shared
	 * libraries the executable uses and the libraries those libraries use
	 * to the list of library images that make up the program.
	 */
	if((mh->flags & MH_FORCE_FLAT) != 0 ||
	   dyld_force_flat_namespace == TRUE)
	    force_flat_namespace = TRUE;
	if((mh->flags & MH_NOFIXPREBINDING) == MH_NOFIXPREBINDING)
	    dyld_no_fix_prebinding = TRUE;
	executable_prebound = (mh->flags & MH_PREBOUND) == MH_PREBOUND;
	load_executable_image(argv[0], mh, &entry_point);

	/*
	 * If the prebinding set is still set then try to setup this program to
	 * use the prebound state in it's images.  If any of these fail then
	 * undo any prebinding and bind as usual.
	 */
	if((mh->flags & MH_PREBOUND) != MH_PREBOUND){
	    /*
	     * The executable is not prebound but if the libraries are setup
	     * for prebinding and the executable when built had no undefined
	     * symbols then try to use the prebound libraries.  This is for
	     * the flat namespace case (and only some sub cases, see the
	     * comments in try_to_use_prebound_libraries()).  If this fails
	     * then the two-level namespace cases are handled by the routine
	     * find_twolevel_prebound_lib_subtrees() which is called below.
	     */
	    if(prebinding == TRUE){
		if((mh->flags & MH_NOUNDEFS) == MH_NOUNDEFS){
		    try_to_use_prebound_libraries();
		}
		else{
		    if(dyld_prebind_debug != 0)
			print("dyld: %s: prebinding disabled because "
			       "executable not marked with MH_NOUNDEFS\n",
				argv[0]);
		    prebinding = FALSE;
		}
	    }
	}
	else if(prebinding == TRUE){
	    set_images_to_prebound();
	}
	if(prebinding == FALSE){
	    /*
	     * The program was not fully prebound but if we are not forcing
	     * flat namespace semantics we can still use any sub trees of
	     * libraries that are all two-level namespace and prebound.
	     */
	    if(force_flat_namespace == FALSE)
		find_twolevel_prebound_lib_subtrees();

	    /*
	     * First undo any images that were prebound.
	     */
	    undo_prebound_images(FALSE);

	    /*
	     * Build the initial list of non-lazy symbol references based on the
	     * executable.
	     */
	    if((mh->flags & MH_BINDATLOAD) != 0 || dyld_bind_at_launch == TRUE)
		executable_bind_at_load = TRUE;
	    setup_initial_undefined_list(FALSE);

	    /*
	     * With the undefined list set up link in the needed modules.
	     */
	    link_in_need_modules(FALSE, FALSE, NULL);
	}
	else{
	    if(dyld_prebind_debug != 0){
		if((mh->flags & MH_PREBOUND) != MH_PREBOUND)
		    print("dyld: %s: prebinding enabled using only prebound "
			   "libraries\n", argv[0]);
		else
		    print("dyld: %s: prebinding enabled\n", argv[0]);
	    }
	}
	/*
	 * Now with the program about to be launched set
	 * all_twolevel_modules_prebound to TRUE if all libraries are two-level,
	 * prebound and all modules in them are linked.
	 */
	set_all_twolevel_modules_prebound();
	launched = TRUE;

	/*
	 * If DYLD_EBADEXEC_ONLY is set then print a message as the program
	 * will launch.
	 */
	if(dyld_ebadexec_only == TRUE){
	    error("executable: %s will be launched (DYLD_EBADEXEC_ONLY set, "
		"program not started)", argv[0]);
	    link_edit_error(DYLD_FILE_ACCESS, EBADEXEC, argv[0]);
	}
	
	if(dyld_print_libraries_post_launch == TRUE)
	    dyld_print_libraries = TRUE;

	/* release lock for dyld data structures */
	release_lock();
	
	DYLD_TRACE_INIT_END(0);

	/*
	 * Return the address of the executable's entry point which is used if
	 * this routine was called from __dyld_start.  Otherwise this was called
	 * from the runtime startoff of the executable and this return value is
	 * ignored.
	 */
	return(entry_point);
}
Beispiel #29
0
int main(int argc, char **argv) {

    int server_fd, port_number, max_fd, file_descriptors[MAX_NUMBER_USERS], i;
    int temp_fd, select_result, timer_is_active = FALSE, status_code;

    char *validation;

    fd_set file_descriptor_set;

    check_incorrect_usage(argc, argv);
    set_log_method(argv);
    set_lock();

    port_number = extract_port_number(argv);
    server_fd = create_server(port_number, MAX_NUMBER_USERS);
    log_message("Streams server created", LOG_INFO);

    register_signal_handlers();

    for (i = 0; i < MAX_NUMBER_USERS; i++) {
        file_descriptors[i] = 0;
    }

    // -- SHARED MEMORY AND SEMAPHORES --

    shmid = create_shared_memory();
    shared_mem_ptr = attach_memory(shmid);
    init_semaphores();

    log_message("Shared memory and semaphores created", LOG_DEBUG);

    // -- SERVER LOOP --

    while (TRUE) {

        FD_ZERO(&file_descriptor_set);
        FD_SET(server_fd, &file_descriptor_set);
        max_fd = server_fd;

        for (i = 0; i < MAX_NUMBER_USERS; i++) {
            temp_fd = file_descriptors[i];

            if (temp_fd > 0) {
                FD_SET(temp_fd, &file_descriptor_set);
            }

            if (temp_fd > max_fd) {
                max_fd = temp_fd;
            }
        }

        select_result = select(max_fd + 1, &file_descriptor_set, NULL, NULL, NULL);

        if (select_result < 0 && errno != EINTR) {
            log_error("Select call error", LOG_WARNING, errno);
            continue;
        }

        if (FD_ISSET(server_fd, &file_descriptor_set)) {

            if ((temp_fd = accept(server_fd, NULL, 0)) < 0) {
                log_error("Could not accept incoming connection", LOG_ALERT, errno);
                exit(EXIT_FAILURE);
            }

            log_client_connection(temp_fd);

            for (i = 0; i < MAX_NUMBER_USERS; i++) {
                if (file_descriptors[i] != 0)
                    continue;

                file_descriptors[i] = temp_fd;
                break;
            }
        }

        for (i = 0; i < MAX_NUMBER_USERS; i++) {

            temp_fd = file_descriptors[i];

            if (!FD_ISSET(temp_fd, &file_descriptor_set))
                continue;

            char *message = NULL;
            if ((message = (char *) calloc(MESSAGE_LENGTH, sizeof(char))) == NULL) {
                log_error("Memory allocation error", LOG_ALERT, errno);
                exit(EXIT_FAILURE);
            }

            if (recv(temp_fd, message, MESSAGE_LENGTH, 0) <= 0)   // Disconnected
            {
                log_message("Client disconnected", LOG_INFO);

                close(temp_fd);
                file_descriptors[i] = 0;
            }
            else    // Message sent to server
            {
                struct message_t mess=decode(message);

                if( (status_code = mess.type) == ERROR_MESSAGE) {
                    continue;
                }

                if (get_game_phase() == REGISTER_PHASE) {

                    if (status_code != 1) {
                        // TODO Send message back to user?
                        log_message("Currently register phase. User can only register", LOG_DEBUG);
                        continue;
                    }

                    if (!timer_is_active) {
                        log_message("Starting register timer", LOG_DEBUG);
                        alarm(WAIT_TIME);
                        timer_is_active = TRUE;
                    }

                    char *new_user = (char *) malloc(MAX_ARRAY_SIZE * sizeof(char));
                    sprintf(new_user, "User '%s' asks for registration. Adding user in memory.", (char *) mess.payload);
                    log_message(new_user, LOG_INFO);

                    // Add a player to the shared memory
                    semaphore_down(SEMAPHORE_ACCESS);
                    strncpy(shared_mem_ptr->players->name, (char *) mess.payload, strlen(mess.payload));
                    shared_mem_ptr->players[i].fd = temp_fd;
                    shared_mem_ptr->players[i].score = 15; // TODO A supprimer
                    semaphore_up(SEMAPHORE_ACCESS);

                    validation = encode(VALID_REGISTRATION, "1");
                    send(temp_fd, validation, strlen(validation), 0);
                }
                else    // GAME PHASE
                {
                    log_message("Game phase. Not yet implemented.", LOG_INFO);
                }

            }
        }
    }

    return 0;
}