/* * 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); }
/*! * 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; }
/* 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; } } }
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); }
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; }
/** @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(¤t_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); } } }
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); }
void PrefAgent::lock_toggle (WCallback *wcb) { XmToggleButtonCallbackStruct &cbs = *(XmToggleButtonCallbackStruct*) wcb->CallData(); set_lock (cbs.set); }
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); }
/* 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); } }
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); } }
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; }
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 ... */ }
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; }
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); }
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); }
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; }
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; }
void lock_stats() { set_lock(LOCK_STATS); }
bool _gmp_set_shared_lock(GumpDB db, int position) { return set_lock(fileno(db->file), F_SETLKW, F_RDLCK, 0, SEEK_SET, 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; }
/* * _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); }
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; }