⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gnbdd.c

📁 openGFS , a kind of file system.
💻 C
📖 第 1 页 / 共 2 页
字号:
	return setsockopt(sk, SOL_SOCKET, SO_KEEPALIVE, &iopt, sizeof(int));}/****************************************************************************** * loop() * the actual main loop of this thing * * Try using select this time. */void *loop(void *args){	int *t = (int *) args;	int listenfd = *t;	int i, maxi, clifd, maxfd, nread;	int err = 0;	theader_t ioHdr;	struct sockaddr_in theiraddr;	fd_set rset, allset;	pid_t mypid;	mypid = getpid();	/* mostly for debugging */	FD_ZERO(&allset);	FD_SET(listenfd, &allset);	maxfd = listenfd;	maxi = -1;	while (Server_Runs) {		rset = allset;		if ((nread = select(maxfd + 1, &rset, NULL, NULL, NULL)) < 0) {			perror("loop: select error");			exit(1);		}		/* If someone else is doing an accept, just skip over it. */		if (pthread_mutex_trylock(&AcceptMux) == 0) {			if (FD_ISSET(listenfd, &rset)) {				int len;				len = sizeof(struct sockaddr_in);				if ((clifd = accept(listenfd,						    (struct sockaddr *)						    &theiraddr, &len)) < 0) {					perror("loop: error in accept");					exit(1);				}				if (setkeepalive(clifd) < 0) {					perror					    ("loop: setkeepalive failed (ignoring)");				}				i = client_add(clifd);				FD_SET(clifd, &allset);				if (clifd > maxfd)					maxfd = clifd;				if (i > maxi)					maxi = i;				printf("Added new client[%d] fd=%d\n", i,				       clifd);				{	/*send login info */					tio_info_t serv_stat;					serv_stat.devsize = htonll(datasize);					serv_stat.readonly = readonly;					nread =					    cpt_send(clifd, &serv_stat,						     sizeof(tio_info_t), 0);				}			}			pthread_mutex_unlock(&AcceptMux);		}		for (i = 1; i <= maxi; i++) {			if ((clifd = Clients[i].fd) < 0)				continue;			if (FD_ISSET(clifd, &rset)) {				if (pthread_mutex_trylock(&Clients[i].mux) == 0) {#if 0					printf					    ("thread %d: got Clients[%d].mux\n",					     mypid, i);#endif					if ((nread =					     cpt_recv(clifd, &ioHdr,						      sizeof(theader_t),						      0)) < 0)						perror("loop: Read error");					if (nread <= 0) {						goto hungup;					} else {						if (handleRequest						    (&Clients[i], &ioHdr) < 0) {						      hungup:							printf							    ("loop: closed fd %d\n",							     clifd);							client_del(clifd);							FD_CLR(clifd, &allset);							close(clifd);						}					}					pthread_mutex_unlock(&Clients[i].mux);#if 0					printf					    ("thread %d: unlocked Clients[%d].mux\n",					     mypid, i);				} else {					printf					    ("thread %d: missed Clients[%d].mux\n",					     mypid, i);#endif				}			}		}	}	pthread_exit(&err);}/****************************************************************************** * signal handler. * Send a SIGUSR1 to stop threads. */voidmysigact(int sig){	if (sig == SIGUSR1)		Server_Runs = 0;}intsend_to_server(unsigned int val, uint16_t port){	char addr[4] = { 127, 0, 0, 1 };	uint32_t *addr_32 = (uint32_t *) & addr[0];	struct in_addr host;	int sock_fd;	struct sockaddr_in server;	/*create the socket and fill the sockaddr with the inputs */	host.s_addr = *addr_32;  /* FIXME: IPv6 */	sock_fd = socket(AF_INET, SOCK_DGRAM, 0); 	if (sock_fd < 0) {		fprintf(stderr, "error creating socket: %s\n", strerror(errno));		return -1;	}	server.sin_family = AF_INET;	server.sin_addr = host;	server.sin_port = htons(port);	if (sendto(sock_fd, &val, sizeof(unsigned int), 0,		   (struct sockaddr *) &server, sizeof(server)) < 0) {		perror("main: couldn't send the port number");		close(sock_fd);		return -1;	}	fprintf(stderr, "time to close\n");	close(sock_fd);	return 0;}/****************************************************************************** * main() * Parse some options, checkout the world, listen to sockets, spawn * threads. You know, same old, same old. */intmain(int argc, char **argv){	int listenfd;	struct sockaddr_in myaddr;	pthread_t tmpTid;	unsigned int port;	int c;	int length = sizeof(struct sockaddr_in);	extern char *optarg;	extern int optind;	int threads = 1;	/* get options. */	if (argc < 2) {		printf("Usage: %s "	/* [-p port] [-s size ] */		       "<device or file>\n",	/*[-t max thread cnt ] */		       argv[0]);		return (1);	}	while ((c = getopt(argc, argv, "s:t:rh?")) != -1) {		switch (c) {		case 's':			datasize = atoi(optarg);			/*			   case 'p':			   port=atoi(optarg);			   break;			 */		case 'r':			readonly = 1;			break;		case 't':			threads = atoi(optarg);			break;		case '?':		case 'h':			printf("Usage: %s [-p port] "	/*[-s size] */			       "<device or file>\n",	/*[-t max thread cnt ] */			       argv[0]);			return (1);			break;		}	}#if 0	printf(" sizeof theader_t %u\n", sizeof(theader_t));	printf(" sizeof tio_info_t %u\n", sizeof(tio_info_t));#endif	/* setup signal handlers */	signal(SIGUSR1, mysigact);	signal(SIGPIPE, SIG_IGN);	/*open the device. */	data_fd = open(argv[optind], (readonly ? O_RDONLY : O_RDWR) | O_SYNC);	if (data_fd < 0) {		perror("main: Failed to open data file");		return 1;	}	if (datasize == 0) {		struct stat st;		if (fstat(data_fd, &st)) {			perror("Could not fstat exported file");			return 1;		}		if (S_ISBLK(st.st_mode)) {			if (ioctl(data_fd, BLKGETSIZE, (long *) &datasize) < 0) {				perror				    ("Couldn't get sector count on block device");				return 1;			}			datasize *= 512;	/*sector size is hardcoded. */		} else {			datasize = (uint64_t) st.st_size;		}		if (datasize == 0) {			fprintf(stderr,				"Could not determin size of exported data\n");			return 1;		}	}	printf("Device size = %llx\n", datasize);	/*attempt to mmap it. */	/*datamap = mmap( NULL, datasize,	   readonly?PROT_READ:(PROT_READ|PROT_WRITE),	   MAP_SHARED,	   data_fd, 0);	   if(datamap==(caddr_t)-1 || datamap==NULL) {	   printf("mmap() failed.  Will use lseek/read/write instead.\n");	   datamap=NULL;	   } */	datamap = NULL;	pthread_mutex_init(&AcceptMux, NULL);	/* setup socket */	if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		perror("loop: Socket biffed");		exit(1);	}	/* Set myself up to listen to the world. */	myaddr.sin_family = AF_INET;	myaddr.sin_addr.s_addr = INADDR_ANY;	myaddr.sin_port = 0;	if (bind(listenfd, (struct sockaddr *) &myaddr,		 sizeof(struct sockaddr_in)) < 0) {		perror("loop: Bind Biffed");		exit(1);	}	if (listen(listenfd, 5) < 0) {		perror("loop: Listen Biffed");		exit(1);	}	if (getsockname(listenfd, (struct sockaddr *) &myaddr, &length) < 0) {		perror("error geting the port number");		exit(1);	}	client_add(listenfd);	/* Start Accept loops */	for (threads--; threads > 0; threads--) {		if (pthread_create(&tmpTid, NULL, loop, (void *) &listenfd) < 0)			perror("main: thread_create biffed");		if (pthread_detach(tmpTid) < 0)			perror("main: thread_detach biffed");	}	/* Link the main thread to the last thread we create. This is kinda bad.	 * really should build a counting semaphore here, and have each worker	 * thread dec that, and when it hits the end, then the main thread can	 * exit. 	 * As it is now, when this attached thread dies, the app dies. Even if	 * there is activity on the other threads.	 *	 * But this will work for proof of concept just fine,	 */	if (pthread_create(&tmpTid, NULL, loop, (void *) &listenfd) < 0)		perror("main: thread_create biffed");	fprintf(stderr, "all threads created\n");	port = (unsigned int) ntohs(myaddr.sin_port);	if (send_to_server(port, 24314) < 0)		exit(1);	if (pthread_join(tmpTid, (void *) &c) < 0) {		perror("main: thread_join biffed");		exit(1);	}	if (datamap)		munmap(datamap, datasize);	close(data_fd);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -