Ejemplo n.º 1
0
void set_callback (STREAM *h, STREAM_FN call)
{
	int i;

	for (i = 0; i < nfds; i++) {
		if (readfd(callback_handles [i]) == readfd(h)) {
			if (call == NULL) {
				if (nfds > 1) {
					callback_handles [i] = callback_handles [nfds-1];
					callback_array [i] = callback_array [nfds-1];
				} else {
					callback_handles [i] = NULL;
					callback_array [i] = NULL;
				}
				nfds --;
			} else {
				callback_array [i] = call;
			}
			return;
		}
	}
	callback_array [nfds] = call;
	callback_handles [nfds] = h;
	nfds ++;
}
Ejemplo n.º 2
0
Archivo: lab8C.c Proyecto: 0xBADCA7/MBE
struct fileComp* comparefds(int fd1, int fd2)
{
	struct fileComp* fc = malloc(sizeof(struct fileComp));
	if(!fc)
	{
		printf("Could not allocate space for file contents\n");
		exit(EXIT_FAILURE);
	}

	strcpy(fc->fileContents1, readfd(fd1));
	strcpy(fc->fileContents2, readfd(fd2));
	fc->cmp = strcmp(fc->fileContents1, fc->fileContents2);
	return fc;
}
Ejemplo n.º 3
0
int main(int argc, char *argv[])
{
	int opt;

	while((opt = getopt_long(argc, argv, short_options, long_options, NULL)) >= 0)
	{
		switch(opt)
		{
		case 'r':
			sort_reverse = 1;
			break;
		case 'h':
		default:
			usage(basename(argv[0]));
			exit(EXIT_FAILURE);
		}
	}

	readfd(0); //stdin

	makeindex();

	qsort(ver_index, index_nmemb, sizeof(char *), vercmpp);

	printindex();

	free(ver_index);
	free(buffer);

	exit(EXIT_SUCCESS);
}
Ejemplo n.º 4
0
rt_public void app_tpipe(STREAM *stream)
{
	/* Initialize the file descriptor to be used in data exchanges with the
	 * remote process. This enables us to omit this parameter whenever an I/O
	 * with the remote process has to be made.
	 */

	if (app_sp != NULL) { 
		unregister_packet_functions (app_sp); 
		close_stream (app_sp);
	}
	if (stream != NULL) {
		app_sp = stream;
		register_packet_functions (app_sp, &app_send_packet, &app_recv_packet);
	} else {
		app_sp = (STREAM *) 0;
	};

#ifdef DEBUG
#ifdef USE_ADD_LOG
	add_log(20, "stream set up as (rd = #%d, wr = #%d)",
		readfd(app_sp), writefd(app_sp));
#endif
#endif
}
Ejemplo n.º 5
0
Pipe::Pipe(const CloseOnExec& close_on_exec)
{
#ifdef HAVE_PIPE2

	if(0 != pipe2(fd_, O_CLOEXEC))
	{
		this->close(); // not sure if call to close matters here
		throw std::runtime_error("could not create pipe");
	}

#else

	if(0 != pipe(fd_))
	{
		this->close(); // not sure if call to close matters here
		throw std::runtime_error("could not create pipe");
	}

	if(CLOSE_ON_EXEC == close_on_exec)
	{
		if(-1 == fcntl(readfd(), F_SETFD, FD_CLOEXEC) ||
		   -1 == fcntl(writefd(), F_SETFD, FD_CLOEXEC))
		{
			this->close();
			throw std::runtime_error("could not set FD_CLOEXEC on pipe");
		}
	}

#endif
}
Ejemplo n.º 6
0
int
main (int argc, char **argv)
{
  setprogname (argv[0]);

  if (!isunixsocket (0))
    fatal << "stdin must be a unix domain socket\n";
  if (argc < 2)
    fatal << "usage: " << progname << " command [arg1 arg2 ... ]\n";

  char **cmdargv = argv + 1;
  str path = find_program_plus_libsfs (cmdargv[0]);
  if (!path)
    fatal << "Could not locate program: " << cmdargv[0] << "\n";

  make_sync (0);

  char buf[1024];
  int fd;
  while (readfd (0, buf, 1024, &fd) > 0)
    if (fd >= 0) {
      aspawn (path, cmdargv, fd, fd, errfd);
      close (fd);
    }
  
  return 0;
}
Ejemplo n.º 7
0
static int
recvfd (int fd)
{
  int nfd = -1;
  char c;
  readfd (fd, &c, 1, &nfd);
  return nfd;
}
Ejemplo n.º 8
0
int mcpRead(int fd, void *ptr, unsigned int nbytes)
{
  char *buf = (char *) ptr;

  int nread = readfd(fd, buf, nbytes);
  
  return nread;
}
Ejemplo n.º 9
0
int
my_receivefd(int fd)
{
    int		passed_fd = -42;

    if (readfd(fd, &passed_fd) < 0) {
	return -1;
    } else {
	return passed_fd;
    }
}
Ejemplo n.º 10
0
u16 getblk(u16 blk, char buf[ ])
{
	int cyl, head, sector;

	// convert blk to CHS; 
	cyl = blk / 18;
	head = blk / 9;
	head = head % 2;
	sector = blk % 9;
	sector = sector * 2;

	readfd(cyl, head, sector, buf);
}
Ejemplo n.º 11
0
int main(int argc, char **argv)
{
	int bufsz = 1024 * 1024;
	void *buf;

	HC_ALLOC(buf, bufsz);

	fprintf(stderr, "total bytes read: %i\n", readfd(0 /* STDIN */, buf, bufsz, doit));

	HC_FREE(buf);

	return 0;
}
Ejemplo n.º 12
0
void 
unixfd::rcb ()
{
  if (reof) {
    fdcb (localfd_in, selread, NULL);
    return;
  }

  char buf[16*1024];
  int fdrecved = -1;
  ssize_t n;
  if (unixsock)
    n = readfd (localfd_in, buf, sizeof (buf), &fdrecved);
  else
    n = read (localfd_in, buf, sizeof (buf));

  if (n < 0) {
    if (errno != EAGAIN)
      abort ();
    return;
  }

  if (!n) {
    readeof ();
    return;
  }
  else {
    rex_payload arg;
    arg.channel = channo;
    arg.fd = fd;
    arg.data.set (buf, n);

    if (fdrecved >= 0) {
      close_on_exec (fdrecved);
      rex_newfd_arg arg;
      arg.channel = channo;
      arg.fd = fd;
      ref<rex_newfd_res> resp (New refcounted<rex_newfd_res> (false));
      proxy->call (REX_NEWFD, &arg, resp,
		   wrap (mkref (this), &unixfd::newfdcb, fdrecved, resp));
    }

    ref<bool> pres (New refcounted<bool> (false));
    rsize += n;
    proxy->call (REX_DATA, &arg, pres,
		 wrap (mkref (this), &unixfd::datacb, n, pres));
  }

  if (rsize >= hiwat)
    fdcb (localfd_in, selread, NULL);
}
Ejemplo n.º 13
0
bool
EnableRDS(uint32_t aMask)
{
  if (!sRadioEnabled || !sRDSSupported)
    return false;

  if (sMsmFMMode)
    setControl(V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_MASK, aMask);

  if (sRDSEnabled)
    return true;

  int pipefd[2];
  int rc = pipe2(pipefd, O_NONBLOCK);
  if (rc < 0) {
    HAL_LOG("Could not create RDS thread signaling pipes (%d)", rc);
    return false;
  }

  ScopedClose writefd(pipefd[1]);
  ScopedClose readfd(pipefd[0]);

  rc = setControl(V4L2_CID_RDS_RECEPTION, true);
  if (rc < 0) {
    HAL_LOG("Could not enable RDS reception (%d)", rc);
    return false;
  }

  sRDSPipeFD = writefd;

  sRDSEnabled = true;

  rc = pthread_create(&sRDSThread, nullptr,
                      readRDSDataThread, (void*)pipefd[0]);
  if (rc) {
    HAL_LOG("Could not start RDS reception thread (%d)", rc);
    setControl(V4L2_CID_RDS_RECEPTION, false);
    sRDSEnabled = false;
    return false;
  }

  readfd.forget();
  writefd.forget();
  return true;
}
Ejemplo n.º 14
0
Archivo: chan.C Proyecto: bougyman/sfs
void
chanfd::rcb (int fdn)
{
  rex_payload data;
  data.channel = channo;
  data.fd = fdn;

  char buf[16*1024];
  bool fdrecved = false;
  size_t numbytes = 0;
  ssize_t n = fdi[fdn].isunixsocket ?
    readfd (fdn, buf, sizeof (buf), fdrecved):
    readmore (fdi[fdn].fd, buf, sizeof (buf), numbytes);

  if (fdi[fdn].isunixsocket && n >= 0)
    numbytes = n;

//   warn << "isunixsocket = " << (fdi[fdn].isunixsocket ? "YES" : "NO") 
//        << "; numbytes = " << numbytes << "\n";

  if (numbytes > 0) {
    data.data.set (buf, numbytes);
    fdi[fdn].rsize += numbytes;
    if (fdi[fdn].rsize >= hiwat)
      disablercb (fdn);
    ref<bool> okp (New refcounted<bool> (false));
    c->call (REXCB_DATA, &data, okp,
	     wrap (this, &chanfd::ccb, fdn, numbytes, destroyed, okp));
  }

  if (n < 0 && errno == EAGAIN)
    return;

  if (n <= 0) {
    if (fdrecved)
      return;
    if (n < 0)
      warn ("chanfd::rcb:read(%d), rexfd:%d: %m\n", fdi[fdn].fd, fdn);
    data.data.clear ();
    fdi[fdn].reof = true;
    disablercb (fdn);
    c->call (REXCB_DATA, &data, &garbage_bool, aclnt_cb_null);
  }
}
Ejemplo n.º 15
0
rt_public int has_input(EIF_PSTREAM sp)
{
	/* Returns 1 if the associated 'fd' has an input callback recorded, 0 if
	 * the file is not selected, and -1 in case of error.
	 */

#ifdef EIF_WINDOWS
	if (callback(sp) != NULL)
		return 1;
#else
	int fd = readfd(sp);
	if (fd < 0 || fd >= NOFILE) {			/* File descriptor out of range */
		s_errno = S_FDESC;					/* Invalid file descriptor */
		return -1;
	}

	if (callback[fd] != NULL) {
		return 1;
	}
#endif

	return 0;			/* This file is not selected any more */
}
Ejemplo n.º 16
0
Archivo: io.c Proyecto: arinn1204/MyOS
///@brief This function is responsible for receiving the block information from the disk
///@param blk This should be an integer (u16) that denotes the block number that is being received
///@param buf This is a string that the block information will be stored into
///@returns This will return a 0 for success and readfd will print if error
u16 getBlock(u16 blk, char *buf) {
	readfd( blk / 18, ( blk % 18 ) / 9,  ( ( blk % 18 ) % 9 ) << 1, buf); //this function is defined in bs.s, it will get the block info and put it into buf
	return 0; //signify succesful completion
}
Ejemplo n.º 17
0
Archivo: app.cpp Proyecto: jj4jj/dcpots
//return 0: continue, 
//return -1(<0): error
//return 1(>0): exit success
static inline int init_command(App & app, const char * pidfile){
    int ret = 0;
	if (app.cmdopt().hasopt("stop")){
		if (!pidfile){
			fprintf(stderr, "lacking command line option pid-file ...\n");
			return -1;
		}
		int killpid = lockpidfile(pidfile, SIGTERM, true);
		fprintf(stderr, "stoped process with normal stop mode [%d]\n", killpid);
        return 1;
	}
	if (app.cmdopt().hasopt("restart")){
		if (!pidfile){
			fprintf(stderr, "lacking command line option pid-file ...\n");
			return -1;
		}
		int killpid = lockpidfile(pidfile, SIGUSR1, true);
		fprintf(stderr, "stoped process with restart mode [%d]\n", killpid);
        return 1;
    }
	if (app.cmdopt().hasopt("reload")){
		if (!pidfile){
			fprintf(stderr, "lacking command line option pid-file ...\n");
			return -1;
		}
		int killpid = lockpidfile(pidfile, SIGUSR2, true, nullptr, true);
		fprintf(stderr, "reloaded process [%d]\n", killpid);
        return 1;
    }
	if (app.cmdopt().hasopt("console-shell")){
		const char * console = app.cmdopt().getoptstr("console-listen");
		if (!console){
			fprintf(stderr, "has no console-listen option open console shell error !\n");
			return -1;
		}
		string console_server = "tcp://";
		console_server += console;
		printf("connecting to %s ...\n", console_server.c_str());
		int confd = openfd(console_server.c_str(), "w", 3000);
		if (!confd){			
			fprintf(stderr, "connect error %s!\n", strerror(errno));
			return -1;
		}
		enum { CONSOLE_BUFFER_SIZE = 1024*1024};
		char * console_buffer = new char[CONSOLE_BUFFER_SIZE];
		printf("console server connected ! command <quit> will exit shell\n");
		while (true){
			int n = readfd(confd, console_buffer, CONSOLE_BUFFER_SIZE,
				"token:\r\n\r\n", 1000 * 3600);
			if (n < 0){
				fprintf(stderr, "console server closed [ret=%d]!\n", n);
				break;
			}
			printf("%s\n%s$", console_buffer, console);
			const char * command = fgets(console_buffer, CONSOLE_BUFFER_SIZE, stdin);
			if (strcasecmp(command, "quit") == 0){
				break;
			}
			dcs::writefd(confd, command, 0, "token:\r\n\r\n");
		}
		closefd(confd);
		delete console_buffer;
        return 1;
    }
    ///////////////////////////////////////////////////////////////////
    ret = _shm_command(app);
    if (ret < 0){
        GLOG_ERR("shm command check error:%d !", ret);
        return -1;
    }
    if (ret > 0){
        return 1;
    }
	return app.on_cmd_opt();
}
Ejemplo n.º 18
0
rt_public int add_input(EIF_PSTREAM sp, STREAM_FN call)
		/* `sp': Stream on which select must be done */
		/* `call': Function to be called when input is available */
{
	/* Add an input condition on file descriptor 'fd', with associated call
	 * back procedure and update internal informations.
	 * The function returns 0 if ok, -1 otherwise (call back pointer void or
	 * file descriptor invalid) and sets 's_errno'
	 */
#ifdef EIF_WINDOWS
	if (nfds >= NOFILE) {					/* File descriptor out of range */
#else
	int fd = readfd(sp);
	if (fd < 0 || fd >= NOFILE) {			/* File descriptor out of range */
#endif
		s_errno = S_FDESC;					/* Invalid file descriptor */
		return -1;
	}

	if (call == NULL) {						/* Null pointer for callback */
		s_errno = S_CALBAK;					/* Invalid callback pointer */
		return -1;
	}

#ifdef EIF_WINDOWS
	if (callback(sp) != NULL) {				/* Callback already set */
#else
	if (callback[fd] != NULL) {				/* Callback already set */
#endif
		s_errno = S_CALSET;					/* Cannot override old callback */
		return -1;
	}

#ifdef EIF_WINDOWS
	set_callback(sp, call);				/* Record callback */
	set_multiple_mask(sp, rd_mask);		/* Select will monitor this fd */
	set_multiple_mask(sp, rd_tmask);	/* Also set temporary mask */
#else
	if ((fd + 1) > nfds) {				/* Keep number of fd up-to-date */
		nfds = fd + 1;					/* Fd start at 0 */
	}
	callback[fd] = call;				/* Record callback */
	FD_SET(fd, &rd_mask);				/* Select will monitor this fd */
	FD_SET(fd, &rd_tmask);				/* Also set temporary mask */
#endif
	return 0;			/* Ok status */
}

rt_public STREAM_FN new_callback(EIF_PSTREAM sp, STREAM_FN call)
		/* `sp': STREAM on which select must be done */
		/* `call': New function to be called when input is available */
{
	/* Change the call back associated with the file descriptor and return the
	 * old call back. If no input was associated with that file descriptor,
	 * it is an error and a null pointer is returned.
	 */

	STREAM_FN old_call;					/* The old call back set for that fd */

#ifdef EIF_WINDOWS
	if (call == NULL) {					/* Null pointer for callback */
		s_errno = S_CALBAK;				/* Invalid callback pointer */
		return NULL;
	}

	old_call = callback(sp);			/* Previously stored callback address */
	set_callback(sp, NULL);				/* Otherwise add_input() will fail */

	if (-1 == add_input(sp, call)) {	/* Failed, restore old status */
		set_callback(sp,old_call);		/* Reset old callback value */
		return NULL;					/* No change occurred */
	}
#else
	int fd = readfd(sp);

	if (fd < 0 || fd >= NOFILE) {		/* File descriptor out of range */
		s_errno = S_FDESC;				/* Invalid file descriptor */
		return NULL;
	}
	if (call == NULL) {						/* Null pointer for callback */
		s_errno = S_CALBAK;				/* Invalid callback pointer */
		return NULL;
	}
	old_call = callback[fd];			/* Previously stored callback address */
	callback[fd] = NULL;				/* Otherwise add_input() will fail */

	if (-1 == add_input(sp, call)) {	/* Failed, restore old status */
		callback[fd] = old_call;		/* Reset old callback value */
		return NULL;					/* No change occurred */
	}
#endif

	return old_call;	/* Success: return old value (cannot be null) */
}
Ejemplo n.º 19
0
Archivo: bc.c Proyecto: zapat0s/CptS460
// Gets block from disk and writes it to ES + buf
u16 getblk(u16 blk, char *buf)
{
	readfd( blk/18, ((blk*2)%36)/18, ((blk*2)%36)%18, buf);
}
Ejemplo n.º 20
0
static char *authenticate(struct conninfo *ci)
{
	char buf[1024];
	int n;
	int noauth=0;
	int uidpw=0;

	D(DEBUG_CONNECT)
		{
			fprintf(stderr, "DEBUG: Connection from ");
			printaddr(stderr, &ci->clientaddr);
			fprintf(stderr, "\n");
			fflush(stderr);
		}

	readfd(ci, buf, 2);

	if (buf[0] != 5)
	{
		fprintf(stderr, "ERR: ");
		printaddr(stderr, &ci->clientaddr);
		fprintf(stderr, " - received unknown protocol version: %d\n",
			(int)(unsigned char)buf[0]);
		fflush(stderr);
		exit(0);
	}

	readfd(ci, buf+2, (int)(unsigned char)buf[1]);

	for (n=0; n<(int)(unsigned char)buf[1]; n++)
		switch (buf[2+n]) {
		case 0:
			noauth=1;
			break;
		case 2:
			uidpw=1;
			break;
		}

	if (uidpw)
	{
		int uidl;
		int pwdl;
		char *pw;

		buf[0]=5;
		buf[1]=2;
		writefd(ci, buf, 2);

		readfd(ci, buf, 2);
		if (buf[0] != 1)
		{
			fprintf(stderr, "ERR: ");
			printaddr(stderr, &ci->clientaddr);
			fprintf(stderr, " - received unknown userid/password authentication version: %d\n",
				(int)(unsigned char)buf[0]);
			fflush(stderr);
			exit(0);
		}
		uidl=(int)(unsigned char)buf[1];

		readfd(ci, buf, uidl+1);

		pw=buf+uidl;
		pwdl=(int)(unsigned char)*pw;
		*pw++=0;
		readfd(ci, pw, pwdl);
		pw[pwdl]=0;

		if (buf[0] == 0)
		{
			/* Empty userid - no authentication */

			buf[0]=5;
			buf[1]=0;
			writefd(ci, buf, 2);

			D(DEBUG_CONNECT)
				{
					fprintf(stderr,"DEBUG: Empty userid - unauthenticated connection from ");
					printaddr(stderr, &ci->clientaddr);
					fprintf(stderr, "\n");
					fflush(stderr);
				}
			return NULL;
		}

		if (validateuseridpw(buf, pw))
		{
			buf[0]=5;
			buf[1]=1;
			writefd(ci, buf, 2);
			fprintf(stderr, "ERR: ");
			printaddr(stderr, &ci->clientaddr);
			fprintf(stderr, " - userid/password invalid.\n");
			fflush(stderr);
			fcntl(ci->clientfd, F_SETFL, 0);
			close(ci->clientfd);
			exit(0);
		}

		pw=strdup(buf);

		buf[0]=5;
		buf[1]=0;
		writefd(ci, buf, 2);

		D(DEBUG_CONNECT)
			{
				fprintf(stderr, "DEBUG: Connection from ");
				printaddr(stderr, &ci->clientaddr);
				fprintf(stderr, " authenticated as %s\n",
					buf);
				fflush(stderr);
			}

		if (!pw)
		{
			perror("ERR: malloc");
			exit(0);
		}
		return pw;
	}
Ejemplo n.º 21
0
int main(int argc, char **argv, char **environ) {
#else
int main(int argc, char **argv) {
#endif
 int i, ret = EXIT_SUCCESS;
 pid_t pid = getpid(), wpid = 0;
 char **ipccommands = NULL;
 int pthread_errno;
 FILE *commandpipe_in, *commandpipe_out;
 int commandpipe[2];
 int debugsocket[2];
 char need_recovery = 0;
 char debug = 0;
 int debugme_pipe = 0;
 char crash_threshold = 5;
 char *einit_crash_data = NULL;

 boottime = time(NULL);

 uname (&osinfo);
 config_configure();

// initialise subsystems
 ipc_configure(NULL);

// is this the system's init-process?
 isinit = getpid() == 1;

 event_listen (einit_event_subsystem_core, core_einit_event_handler);
 event_listen (einit_event_subsystem_timer, core_timer_event_handler);

 if (argv) einit_argv = (char **)setdup ((const void **)argv, SET_TYPE_STRING);

/* check command line arguments */
 for (i = 1; i < argc; i++) {
  if (argv[i][0] == '-')
   switch (argv[i][1]) {
    case 'c':
     if ((++i) < argc)
      einit_default_startup_configuration_files[0] = argv[i];
     else
      return print_usage_info ();
     break;
    case 'h':
     return print_usage_info ();
     break;
    case 'v':
     eputs("eINIT " EINIT_VERSION_LITERAL "\n", stdout);
     return 0;
    case 'L':
     eputs("eINIT " EINIT_VERSION_LITERAL
          "\nThis Program is Free Software, released under the terms of this (BSD) License:\n"
          "--------------------------------------------------------------------------------\n"
          "Copyright (c) 2006, 2007, Magnus Deininger\n"
          BSDLICENSE "\n", stdout);
     return 0;
    case '-':
     if (strmatch(argv[i], "--check-configuration") || strmatch(argv[i], "--checkup") || strmatch(argv[i], "--wtf")) {
      ipccommands = (char **)setadd ((void **)ipccommands, "examine configuration", SET_TYPE_STRING);
     } else if (strmatch(argv[i], "--help"))
      return print_usage_info ();
     else if (strmatch(argv[i], "--ipc-command") && argv[i+1])
      ipccommands = (char **)setadd ((void **)ipccommands, (void *)argv[i+1], SET_TYPE_STRING);
     else if (strmatch(argv[i], "--override-init-check"))
      initoverride = 1;
     else if (strmatch(argv[i], "--sandbox")) {
      einit_default_startup_configuration_files[0] = "lib/einit/einit.xml";
      coremode = einit_mode_sandbox;
      need_recovery = 1;
     } else if (strmatch(argv[i], "--metadaemon")) {
      coremode = einit_mode_metadaemon;
     } else if (strmatch(argv[i], "--bootstrap-modules")) {
      bootstrapmodulepath = argv[i+1];
     } else if (strmatch(argv[i], "--debugme")) {
      debugme_pipe = parse_integer (argv[i+1]);
      i++;
      initoverride = 1;
     } else if (strmatch(argv[i], "--debug")) {
      debug = 1;
     }

     break;
   }
 }

/* check environment */
 if (environ) {
  uint32_t e = 0;
  for (e = 0; environ[e]; e++) {
   char *ed = estrdup (environ[e]);
   char *lp = strchr (ed, '=');

   *lp = 0;
   lp++;

   if (strmatch (ed, "softlevel")) {
    einit_startup_mode_switches = str2set (':', lp);
   } if (strmatch (ed, "mode")) {
/* override default mode-switches with the ones in the environment variable mode= */
    einit_startup_mode_switches = str2set (':', lp);
   } else if (strmatch (ed, "einit")) {
/* override default configuration files and/or mode-switches with the ones in the variable einit= */
    char **tmpstrset = str2set (',', lp);
    uint32_t rx = 0;

    for (rx = 0; tmpstrset[rx]; rx++) {
     char **atom = str2set (':', tmpstrset[rx]);

     if (strmatch (atom[0], "file")) {
/* specify configuration files */
      einit_startup_configuration_files = (char **)setdup ((const void **)atom, SET_TYPE_STRING);
      einit_startup_configuration_files = (char **)strsetdel (einit_startup_configuration_files, (void *)"file");
     } else if (strmatch (atom[0], "mode")) {
/* specify mode-switches */
      einit_startup_mode_switches = (char **)setdup ((const void **)atom, SET_TYPE_STRING);
      einit_startup_mode_switches = (char **)strsetdel (einit_startup_mode_switches, (void *)"mode");
     } else if (strmatch (atom[0], "stfu")) {
      einit_quietness = 3;
     } else if (strmatch (atom[0], "silent")) {
      einit_quietness = 2;
     } else if (strmatch (atom[0], "quiet")) {
      einit_quietness = 1;
     }

     free (atom);
    }

    free (tmpstrset);
   }

   free (ed);
  }

  einit_initial_environment = (char **)setdup ((const void **)environ, SET_TYPE_STRING);
 }

 if (!einit_startup_mode_switches) einit_startup_mode_switches = einit_default_startup_mode_switches;
 if (!einit_startup_configuration_files) einit_startup_configuration_files = einit_default_startup_configuration_files;

 respawn:

 pipe (commandpipe);

 fcntl (commandpipe[1], F_SETFD, FD_CLOEXEC);

 socketpair (AF_UNIX, SOCK_STREAM, 0, debugsocket);
 fcntl (debugsocket[0], F_SETFD, FD_CLOEXEC);
 fcntl (debugsocket[1], F_SETFD, FD_CLOEXEC);

 if (!debug) {
  fcntl (commandpipe[0], F_SETFD, FD_CLOEXEC);
  commandpipe_in = fdopen (commandpipe[0], "r");
 }
 commandpipe_out = fdopen (commandpipe[1], "w");

 if (!initoverride && ((pid == 1) || ((coremode & einit_mode_sandbox) && !ipccommands))) {
// if (pid == 1) {
  initoverride = 1;
#if 0
#ifdef LINUX
  if ((einit_sub = syscall(__NR_clone, CLONE_PTRACE | SIGCHLD, 0, NULL, NULL, NULL)) < 0) {
   bitch (bitch_stdio, errno, "Could not fork()");
   eputs (" !! Haven't been able to fork a secondary worker process. This is VERY bad, you will get a lot of zombie processes! (provided that things work at all)\n", stderr);
  }
#else
#endif
#endif
  if ((einit_sub = fork()) < 0) {
   bitch (bitch_stdio, errno, "Could not fork()");
   eputs (" !! Haven't been able to fork a secondary worker process. This is VERY bad, you will get a lot of zombie processes! (provided that things work at all)\n", stderr);
  }
 }

 if (einit_sub) {
/* PID==1 part */
  int rstatus;
  struct sigaction action;

/* signal handlers */
  action.sa_sigaction = einit_sigint;
  sigemptyset(&(action.sa_mask));
  action.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
  if ( sigaction (SIGINT, &action, NULL) ) bitch (bitch_stdio, 0, "calling sigaction() failed.");

/* ignore sigpipe */
  action.sa_sigaction = (void (*)(int, siginfo_t *, void *))SIG_IGN;

  if ( sigaction (SIGPIPE, &action, NULL) ) bitch (bitch_stdio, 0, "calling sigaction() failed.");

  close (debugsocket[1]);
  if (einit_crash_data) {
   free (einit_crash_data);
   einit_crash_data = NULL;
  }

  while (1) {
   wpid = waitpid(-1, &rstatus, 0); /* this ought to wait for ANY process */

   if (wpid == einit_sub) {
//    goto respawn; /* try to recover by re-booting */
    if (!debug) if (commandpipe_in) fclose (commandpipe_in);
    if (commandpipe_out) fclose (commandpipe_out);

    if (WIFEXITED(rstatus) && (WEXITSTATUS(rstatus) != einit_exit_status_die_respawn)) {
     fprintf (stderr, "eINIT has quit properly.\n");

     if (!(coremode & einit_mode_sandbox)) {
      if (WEXITSTATUS(rstatus) == einit_exit_status_last_rites_halt) {
       execl (EINIT_LIB_BASE "/bin/last-rites", EINIT_LIB_BASE "/bin/last-rites", "h", NULL);
      } else if (WEXITSTATUS(rstatus) == einit_exit_status_last_rites_reboot) {
       execl (EINIT_LIB_BASE "/bin/last-rites", EINIT_LIB_BASE "/bin/last-rites", "r", NULL);
      } else if (WEXITSTATUS(rstatus) == einit_exit_status_last_rites_kexec) {
       execl (EINIT_LIB_BASE "/bin/last-rites", EINIT_LIB_BASE "/bin/last-rites", "k", NULL);
      }
     }

     exit (EXIT_SUCCESS);
    }

    int n = 5;
    fprintf (stderr, "The secondary eINIT process has died, waiting a while before respawning.\n");
    if ((einit_crash_data = readfd (debugsocket[0]))) {
     fprintf (stderr, " > neat, received crash data\n");
    }
    while ((n = sleep (n)));
    fprintf (stderr, "Respawning secondary eINIT process.\n");

    if (crash_threshold) crash_threshold--;
    else debug = 1;
    need_recovery = 1;
    initoverride = 0;

    close (debugsocket[0]);

    goto respawn;
   } else {
    if (commandpipe_out) {
     if (WIFEXITED(rstatus)) {
      fprintf (commandpipe_out, "pid %i terminated\n\n", wpid);
     } else {
      fprintf (commandpipe_out, "pid %i died\n\n", wpid);
     }
     fflush (commandpipe_out);
    }
   }
  }
 } else {
  enable_core_dumps ();

  close (debugsocket[0]);
  sched_trace_target = debugsocket[1];

  if (debug) {
   char **xargv = (char **)setdup ((const void **)argv, SET_TYPE_STRING);
   char tbuffer[BUFFERSIZE];
   struct stat st;
   char have_valgrind = 0;
   char have_gdb = 0;

   fputs ("eINIT needs to be debugged, starting in debugger mode\n.", stderr);

   xargv = (char **)setadd ((void **)xargv, (void *)"--debugme", SET_TYPE_STRING);
   snprintf (tbuffer, BUFFERSIZE, "%i", commandpipe[0]);
   xargv = (char **)setadd ((void **)xargv, (void *)tbuffer, SET_TYPE_STRING);

   xargv = strsetdel (xargv, "--debug"); // don't keep the --debug flag

   if (!stat ("/usr/bin/valgrind", &st)) have_valgrind = 1;
   if (!stat ("/usr/bin/gdb", &st)) have_gdb = 1;

   if (have_valgrind) {
    char **nargv = NULL;
    uint32_t i = 1;

#ifdef LINUX
    if (!(coremode & einit_mode_sandbox)) {
     mount ("proc", "/proc", "proc", 0, NULL);
     mount ("sys", "/sys", "sysfs", 0, NULL);

     system ("mount / -o remount,rw");
    }
#endif

    nargv = (char **)setadd ((void **)nargv, "/usr/bin/valgrind", SET_TYPE_STRING);
    nargv = (char **)setadd ((void **)nargv, "--log-file=/einit.valgrind", SET_TYPE_STRING);
    nargv = (char **)setadd ((void **)nargv, (coremode & einit_mode_sandbox) ? "sbin/einit" : "/sbin/einit", SET_TYPE_STRING);

    for (; xargv[i]; i++) {
     nargv = (char **)setadd ((void **)nargv, xargv[i], SET_TYPE_STRING);
    }

    execv ("/usr/bin/valgrind", nargv);
   } else {
    execv ((coremode & einit_mode_sandbox) ? "sbin/einit" : "/sbin/einit", xargv);
   }
  }

  if (debugme_pipe) { // commandpipe[0]
   fcntl (commandpipe[0], F_SETFD, FD_CLOEXEC);
   commandpipe_in = fdopen (debugme_pipe, "r");
  }

/* actual system initialisation */
  struct einit_event cev = evstaticinit(einit_core_update_configuration);

  if (ipccommands && (coremode != einit_mode_sandbox)) {
   coremode = einit_mode_ipconly;
  }

  eprintf (stderr, "eINIT " EINIT_VERSION_LITERAL ": Initialising: %s\n", osinfo.sysname);

  if ((pthread_errno = pthread_attr_init (&thread_attribute_detached))) {
   bitch(bitch_epthreads, pthread_errno, "pthread_attr_init() failed.");

   if (einit_initial_environment) free (einit_initial_environment);
   return -1;
  } else {
   if ((pthread_errno = pthread_attr_setdetachstate (&thread_attribute_detached, PTHREAD_CREATE_DETACHED))) {
    bitch(bitch_epthreads, pthread_errno, "pthread_attr_setdetachstate() failed.");
   }
  }

  if ((pthread_errno = pthread_key_create(&einit_function_macro_key, NULL))) {
   bitch(bitch_epthreads, pthread_errno, "pthread_key_create(einit_function_macro_key) failed.");

   if (einit_initial_environment) free (einit_initial_environment);
   return -1;
  }

/* this should be a good place to initialise internal modules */
   if (coremodules) {
    uint32_t cp = 0;

    eputs (" >> initialising in-core modules:", stderr);

    for (; coremodules[cp]; cp++) {
     struct lmodule *lmm;
     eprintf (stderr, " [%s]", (*coremodules[cp])->rid);
     lmm = mod_add(NULL, (*coremodules[cp]));

     lmm->source = estrdup("core");
    }

    eputs (" OK\n", stderr);
   }

/* emit events to read configuration files */
  if (einit_startup_configuration_files) {
   uint32_t rx = 0;
   for (; einit_startup_configuration_files[rx]; rx++) {
    cev.string = einit_startup_configuration_files[rx];
    event_emit (&cev, einit_event_flag_broadcast);
   }

   if (einit_startup_configuration_files != einit_default_startup_configuration_files) {
    free (einit_startup_configuration_files);
   }
  }

  cev.string = NULL;
  cev.type = einit_core_configuration_update;

// make sure we keep updating until everything is sorted out
  while (cev.type == einit_core_configuration_update) {
//   notice (2, "stuff changed, updating configuration.");

   cev.type = einit_core_update_configuration;
   event_emit (&cev, einit_event_flag_broadcast);
  }
  evstaticdestroy(cev);

  if (ipccommands) {
   uint32_t rx = 0;
   for (; ipccommands[rx]; rx++) {
    ret = ipc_process (ipccommands[rx], stdout);
   }

//   if (gmode == EINIT_GMODE_SANDBOX)
//    cleanup ();

   free (ipccommands);
   if (einit_initial_environment) free (einit_initial_environment);
   return ret;
  } else if ((coremode == einit_mode_init) && !isinit && !initoverride) {
   eputs ("WARNING: eINIT is configured to run as init, but is not the init-process (pid=1) and the --override-init-check flag was not specified.\nexiting...\n\n", stderr);
   exit (EXIT_FAILURE);
  } else {
/* actual init code */
   uint32_t e = 0;

   nice (einit_core_niceness_increment);

   if (need_recovery) {
    notice (1, "need to recover from something...");

    struct einit_event eml = evstaticinit(einit_core_recover);
    event_emit (&eml, einit_event_flag_broadcast);
    evstaticdestroy(eml);
   }

   if (einit_crash_data) {
    notice (1, "submitting crash data...");

    struct einit_event eml = evstaticinit(einit_core_crash_data);
    eml.string = einit_crash_data;
    event_emit (&eml, einit_event_flag_broadcast);
    evstaticdestroy(eml);

    free (einit_crash_data);
    einit_crash_data = NULL;
   }

   {
    notice (3, "running early bootup code...");

    struct einit_event eml = evstaticinit(einit_boot_early);
    event_emit (&eml, einit_event_flag_broadcast | einit_event_flag_spawn_thread_multi_wait);
    evstaticdestroy(eml);
   }

   notice (2, "scheduling startup switches.\n");

   for (e = 0; einit_startup_mode_switches[e]; e++) {
    struct einit_event ee = evstaticinit(einit_core_switch_mode);

    ee.string = einit_startup_mode_switches[e];
    event_emit (&ee, einit_event_flag_broadcast | einit_event_flag_spawn_thread | einit_event_flag_duplicate);
    evstaticdestroy(ee);
   }

   struct einit_event eml = evstaticinit(einit_core_main_loop_reached);
   eml.file = commandpipe_in;
   event_emit (&eml, einit_event_flag_broadcast);
   evstaticdestroy(eml);
  }

  if (einit_initial_environment) free (einit_initial_environment);
  return ret;
 }

/* this should never be reached... */
 if (einit_initial_environment) free (einit_initial_environment);
 return 0;
}
Ejemplo n.º 22
0
rt_public int net_recv(EIF_PSTREAM cs, char *buf, size_t size
#ifdef EIF_WINDOWS
                       ,BOOL reset
#endif
                      )
/* The connected socket descriptor */
/* Where data are to be stored */
/* Amount of data to be read */
/* Reset event associated with cs reader? */
/* The connected socket descriptor */
/* Where data are to be stored */
/* Amount of data to be read */
{
    /* Read from network */

    volatile size_t len = 0;		/* Total amount of bytes read */

#ifdef EIF_WINDOWS
    DWORD length;			/* Amount read by last system call */
    UINT_PTR timer = 0;
    BOOL fSuccess;
#ifdef USE_ADD_LOG
    add_log(2, "in net_recv");
#endif
#else
    Signal_t (*oldalrm)(int);
    int length;
#endif

    REQUIRE("Valid size", size <= INT32_MAX);

#ifdef EIF_WINDOWS
    if (0 != setjmp(env)) {
        KillTimer (NULL, timer);        /* Stop alarm clock */
        errno = EPIPE;                          /* Signal timeout on read */
        return -1;
    }

    while (len < size) {
        timer = SetTimer(NULL, timer, TIMEOUT*1000, (TIMERPROC) timeout);   /* Give read only TIMEOUT seconds to succeed */
        fSuccess = ReadFile(readfd(cs), buf + len, (DWORD) (size - len), &length, NULL);
        KillTimer (NULL, timer);

        if (fSuccess)
            if (length == 0)        /* connection closed */
                goto closed;
            else
                ;
        else
            return -1;              /* failed */

        len += length;
    }

    if (reset) {
        /* There is a problem when there are 0 bytes t send
         * Literally 0 bytes are sent and the Semaphore is set
         * We need to release the semaphore in this case
         */
        if (size == 0) {
            /* Wait to get back in sync. */
            if (WaitForSingleObject (readev(cs), INFINITE) != WAIT_OBJECT_0) {
#ifdef USE_ADD_LOG
                add_log (8, "network:97 Bad wait");
#endif
            }
        } else {
            if (WaitForSingleObject (readev(cs), 0) != WAIT_OBJECT_0) {
#ifdef USE_ADD_LOG
                add_log (8, "network:101 Wait on %d failed", size);
#endif
            }
        }
    }

    return 0;

closed:

    /* Unlike recv(), we return an error condition with a suitable errno code
     * if possible when and end of file is detected... because we never expect
     * one. Before closing the connection, the remote application should be
     * polite enough to send a 'bye' request and wait for us to receive it.
     */

    errno = EPIPE;				/* connection is broken */
    KillTimer (NULL, timer);	/* stop alarm clock */

    return -1;

#else
    oldalrm = signal(SIGALRM, timeout);	/* Trap SIGALRM within this function */

    if (0 != setjmp(env)) {
        alarm(0);					/* Stop alarm clock */
        signal(SIGPIPE, oldalrm);
        errno = NET_TIMEOUT;		/* Signal timeout on read */
        return -1;
    }


    while (len < size) {

        alarm(TIMEOUT);			/* Give read only TIMEOUT seconds to succeed */
        length = read(readfd(cs), buf + len, size - len);
        alarm(0);

        if (length == 0)	/* connection closed */
            goto closed;

        if (length == -1) {
            if (errno != EINTR) {
                return -1;		/* failed */
            } else {
                length = 0;
            }
        }

        len += length;
    }

    signal(SIGALRM, oldalrm);	/* restore default handler */

    return 0;

closed:

    /* Unlike recv(), we return an error condition with a suitable errno code
     * if possible when and end of file is detected... because we never expect
     * one. Before closing the connection, the remote application should be
     * polite enough to send a 'bye' request and wait for us to receive it.
     */

    errno = NET_BROKEN;			/* conntection is broken */
    alarm(0);					/* stop alarm clock */
    signal(SIGALRM, oldalrm);	/* restore default handler */

    return -1;
#endif
}
Ejemplo n.º 23
0
int getsector(__u16 sector) {
    readfd(sector/36, ((sector)%36)/18, (((sector)%36)%18));
}
Ejemplo n.º 24
0
rt_public STREAM_FN rem_input(EIF_PSTREAM sp)
		/* `sp': Stream on which no select is to be done */
{
	/* This function removes the input and associated callback for 'sp' and
	 * returns the old callback value.
	 */

	STREAM_FN old_call;					/* The old call back set for that fd */

#ifdef EIF_WINDOWS
	old_call = callback(sp);		/* Save previous callback value */
	set_callback(sp, NULL);			/* And clear entry anyway */
	if (old_call == NULL) {			/* No callback was set */
		s_errno = S_NOCALBAK;		/* This error does not really matter */
		return NULL;			/* As we cleared the entry already */
	}

	/* Update the reading mask and the nfds value. This is important, because
	 * it is the only way do_select() can tell whether there is at least one
  	 * input file descriptor. Otherwise, with a null timout, we could block
  	 * forever.
  	 */

	unset_multiple_mask(sp, rd_mask);				/* We no longer need to monitor it */
	unset_multiple_mask(sp, rd_tmask);				/* Remove it also from temporary mask */

#else
	int i;								/* To eventually update nfds */
	int fd = readfd(sp);

	if (fd < 0 || fd >= NOFILE) {		/* File descriptor out of range */
		s_errno = S_FDESC;
		return NULL;
	}

	old_call = callback[fd];			/* Save previous callback value */
	callback[fd] = NULL;				/* And clear entry anyway */

	if (old_call == NULL) {				/* No callback was set */
		s_errno = S_NOCALBAK;			/* This error does not really matter */
		return NULL;					/* As we cleared the entry already */
	}

	/* Update the reading mask and the nfds value. This is important, because
	 * it is the only way do_select() can tell whether there is at least one
	 * input file descriptor. Otherwise, with a null timout, we could block
	 * forever.
	 */
	FD_CLR(fd, &rd_mask);				/* We no longer need to monitor it */
	FD_CLR(fd, &rd_tmask);				/* Remove it also from temporary mask */
	if (nfds == (fd + 1)) {				/* This file was the maximum fd */
		nfds = 0;						/* Assume no more file */
		for (i = fd - 1; i >= 0; i--)
			if (callback[i] != NULL) {
				nfds = i + 1;			/* Number of fd still monitored */
				break;					/* Found it, break loop */
			}
	}
#endif

	return old_call;	/* Success: return old value (cannot be null) */
}
Ejemplo n.º 25
0
rt_public int do_select(struct timeval *timeout)
#endif
{
	/* Finally, this runs the select call with the computed read mask, with the
	 * specified timeout. The return value is simply the propagated status we
	 * got from select() itself. If some input is available, we handle it by
	 * calling the specified callback routine. If more than one file descriptor
	 * was ready, we handle them all before returning.
	 * Note that when the select call is interrupted by a signal, it is
	 * restarted automatically.
	 */

	STREAM* sp;						/* To loop over STREAM* */
#ifdef EIF_WINDOWS
	DWORD first_timeout;			/* Timeout used for first select */
	DWORD nfd;						/* Status reported by select */
	int isfirst = 1;				/* Mark first select */
#else
	struct timeval first_timeout;	/* Timeout used for first select */
	int nfd;						/* Status reported by select */
	int fd;							/* To loop over file descriptors */
	int isfirst = 1;				/* Mark first select */
#endif

	/* If no more file are to be selected, return immediately with a proper
	 * error status in 's_errno'. This should be a convenient way to detect
	 * that all the input sources have been removed, if this is only a
	 * meta-knowledge.
	 */

	if (nfds == 0) {
		s_errno = S_NOFILE;			/* No more input file */
		return -1;
	}

#ifdef DEBUG
#ifdef USE_ADD_LOG
	add_log(20, "selecting with mask 0x%lx", rd_mask);
#endif
#endif

	/* Loop until select() succeeds or fails for any reason but a signal */
	for (;;) {

#ifdef USE_ADD_LOG
	add_log(20, "selecting");
#endif

		/* The first select is done with TMP_TIMEOUT time unless a timeout is
		 * given. The temporary mask is used for this first selection. That
		 * way, we do not select for the temporary "out" files, which increases
		 * the chance of having the remote end of a stream clear to send the
		 * next time those files are selected.
		 */
#ifdef EIF_WINDOWS
#ifdef USE_ADD_LOG
	add_log(20, "Selecting on count %d", nfds);
	{
	int i;
	for (i = 0; i < nfds; i++)
		add_log (20, "   semaphore %d", rd_tmask [i]);
	}
#endif
#endif

#ifdef EIF_WINDOWS
		if (isfirst) {
			if (timeout == 0) {
				first_timeout = TMP_TIMEOUT;
				nfd = WaitForMultipleObjects (nfds, rd_tmask, FALSE, first_timeout / 1000);
			} else {
				first_timeout = timeout;
				nfd = WaitForMultipleObjects (nfds, rd_tmask, FALSE, first_timeout * 1000);
			}
		} else {
			nfd = WaitForMultipleObjects (nfds, rd_mask, FALSE, timeout * 1000);
		}

		if (nfd == WAIT_FAILED) {
#ifdef USE_ADD_LOG
	add_log(20, "Select failure %d count %d", GetLastError(), nfds);
#endif
			s_errno = S_SELECT;		/* Signals: select failed */
			return -1;				/* Propagate error status */
		}

		if (isfirst) {
			isfirst = 0;
			if (nfd == WAIT_TIMEOUT && timeout == 0) {
				continue;				/* First select timed out */
			}
		}
		break;							/* Exit from loop */
#else
		if (isfirst) {
			if (timeout == (struct timeval *) 0) {
				first_timeout.tv_sec = 0;
				first_timeout.tv_usec = TMP_TIMEOUT;
			} else {
				memcpy (&first_timeout, timeout, sizeof(struct timeval));
			}
			memcpy (&read_mask, &rd_tmask, sizeof(fd_set));
			nfd = select(nfds, &read_mask, (Select_fd_set_t) 0, (Select_fd_set_t) 0, &first_timeout);
		} else {
			memcpy (&read_mask, &rd_mask, sizeof(fd_set));
			nfd = select(nfds, &read_mask, (Select_fd_set_t) 0, (Select_fd_set_t) 0, timeout);
		}

		if (nfd == -1) {
			if (errno != EINTR) {		/* Not interrupted by a signal */
				s_errno = S_SELECT;		/* Signals: select failed */
				return -1;				/* Propagate error status */
			} else {
				continue;				/* Re-issue the system call */
			}
		}

		if (isfirst) {
			isfirst = 0;
			if (nfd == 0 && timeout == (struct timeval *) 0) {
				continue;				/* First select timed out */
			}
		}
		break;							/* Exit from loop */
#endif
	} /* end of for(;;) */

	/* If we come here, then the select call must have succeded. If the timeout
	 * value was reached, nfd is set to 0. Otherwise, it is set to the number
	 * of ready file descriptors.
	 */

#ifdef EIF_WINDOWS
	if (nfd == WAIT_TIMEOUT) {			/* Select timed out */
#else
	if (nfd == 0) {						/* Select timed out */
#endif
		return 0;						/* Propagate status */
	}

#ifdef EIF_WINDOWS
	sp = callback_handles [nfd - WAIT_OBJECT_0];
#endif

#ifdef DEBUG
#ifdef EIF_WINDOWS
#ifdef USE_ADD_LOG
			add_log(20, "file descriptor #%d is ready", sp->sr);
#endif
#else /* if not EIF_WINDOWS */
#ifdef USE_ADD_LOG
	for (fd = 0; fd < nfds; fd++)
		if (FD_ISSET(fd, &read_mask))	/* Something is present */
			add_log(20, "file descriptor #%d is ready", fd);
#endif
#endif
#endif

	/* Loop over the file descriptors and process any of them which is marked
	 * as ready for reading.
	 */

#ifdef EIF_WINDOWS
	callback_array [nfd - WAIT_OBJECT_0](sp);	/* Wake up associated callback */
#else
	for (fd = 0; fd < nfds; fd++) {
		if (FD_ISSET(fd, &read_mask)) {	/* Something is present */
			sp = stream_by_fd[fd];
			(callback[fd])(sp);			/* Wake up associated callback */
		};
	}
#endif

#ifdef DEBUG
#ifdef USE_ADD_LOG
	add_log(20, "select call returning %d", nfd);
#endif
#endif


#ifdef EIF_WINDOWS
	return 1;				/* Number of files processed */
#else
	return nfd;				/* Number of files processed */
#endif
}

#ifdef EIF_WINDOWS
STREAM_FN callback(STREAM *h)
{
	int i;

	for (i = 0; i < nfds; i++)
		if (readfd(callback_handles[i]) == readfd(h))
			return callback_array [i];

	return NULL;
}