📄 mlock.c
字号:
/* $Id: mlock.c,v 1.10 2005/02/17 15:06:35 alan Exp $ *//* * * multi-clients NFS lock test code * * Copyright (C) 2004 Guochun Shi<gshi@ncsa.uiuc.edu> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/stat.h>#include <fcntl.h>#include <glib.h>#include <signal.h>#define MYPORT 5000#define PASS 0#define WARNING 1#define FATAL 2#define END 0#define output printfstruct test_task{ int num; int sec; int func; off_t offset; off_t length; int pass; int fail; };#define MAX_FN_LEN 32struct global_info{ char filename[MAX_FN_LEN]; int clientID; int sockfd; int fd; int fd_save; int testpass; int testwarn; int testfail; pid_t forkpid; };enum{ OPEN, MANOPEN, CLOSE, CLOSE_SAVEFD, WAIT, SEND, RUN, READ, WRITE, SLEEP, PUSHFD, POPFD, TRUNC, FORK, KILL, OUTPUT};struct run_param{ int num; int sec; int func; off_t offset; off_t length; int pass; int fail;};struct io_param{ int num; int sec; int start; int whichmsg;};struct sleep_param{ int time;};struct task{ int op; struct run_param run_param; struct io_param io_param; struct sleep_param sleep_param; }; struct global_info gi;static void pushfd(void){ if ((gi.fd_save = dup(gi.fd)) == -1 ){ perror("dup"); exit(1); } return; }static voidpopfd(void){ if (dup2(gi.fd_save, gi.fd) == -1){ perror("dup2"); exit(1); } return; }static voidclose_savefd(void){ if (close(gi.fd_save) == -1){ perror("close"); exit(1); } return;}static voidhb_trunc(void ){ if (ftruncate(gi.fd, 0) == -1){ perror("ftruncate"); exit(1); } return; }static intreport (int result, struct test_task *tt){ if (tt->pass == result){ output("PASSED.\n"); gi.testpass++; } else if ((tt->pass == EAGAIN && result == EACCES) || (tt->pass == EACCES && result == EAGAIN) || tt->fail == WARNING){ output("warning\n"); gi.testwarn++; } else { output("test failed, result =%d\n", result); gi.testfail++; exit(1); } return 0;}static void test_exit(void ){ if( gi.testwarn == 0 && gi.testfail == 0 ){ output("All tests finished successfully!\n"); exit(1); } else { output(" ********There are %d warnings, %d errors******", gi.testwarn, gi.testfail); exit(1); }}static voidmanopen_testfile(void){ if ((gi.fd = open(gi.filename,O_RDWR|O_CREAT, 02666)) == -1){ perror("open"); exit(1); } return ;}static voidopen_testfile(void){ if ((gi.fd = open(gi.filename,O_RDWR|O_CREAT, 0666)) == -1){ perror("open"); exit(1); } return ;}static void close_testfile(void){ if( close(gi.fd) == -1){ perror("close"); exit(1); } /* unlink(gi.filename); */ return;}#define MSGONE 1#define MSGTWO 2 #define MSGA "abcde"#define MSGB "edcba"#define WR_START 4*1024 - 4#define LOCKLEN 6 static void write_testfile(struct task* task){ const char* msg; int result; output("%d-%d:\t", task->io_param.num, task->io_param.sec); if (task->io_param.whichmsg == 1){ msg = MSGA; } else { msg = MSGB; } if (lseek(gi.fd, task->io_param.start, SEEK_SET) == -1){ perror("lseek"); exit(1); } if ((result = write(gi.fd, msg, LOCKLEN)) == -1){ perror("write"); exit(1); } output("PASSED.\n");}static void read_testfile( struct task* task){ const char* msg; char buf[LOCKLEN]; output("%d-%d:\t", task->io_param.num, task->io_param.sec); if (task->io_param.whichmsg == 1){ msg = MSGA; } else { msg = MSGB; } if (lseek(gi.fd, task->io_param.start, SEEK_SET) == -1){ perror("lseek"); exit(1); } if (read(gi.fd, buf, LOCKLEN) == -1){ perror("read"); exit(1); } if(memcmp(buf, msg, LOCKLEN) != 0){ output("\nread content is not matched\n"); output("conent in file is =%s,\n" "the msg compared with is %s\n", buf, msg); exit(1); } output("PASSED.\n");}static intdo_test( struct test_task* tt){ int result = PASS; struct flock flock; int cmd; flock.l_whence = SEEK_SET; flock.l_start = tt->offset; flock.l_len = tt->length; flock.l_type = F_WRLCK; switch(tt->func){ case F_TEST: cmd = F_GETLK; break; case F_TLOCK: cmd = F_SETLK; break; case F_LOCK: cmd = F_SETLKW; break; case F_ULOCK: flock.l_type = F_UNLCK; cmd = F_SETLK; break; default: output("wrong func in task! \n"); exit(1); } output("%d-%d:\t", tt->num, tt->sec); if(lseek(gi.fd, tt->offset, 0) < 0) { result = errno; } if (result == 0) { /* if (result = lockf(gi.fd, tt->func, tt->length) != 0){ */ if ((result = fcntl(gi.fd, cmd, &flock)) != 0 ){ result = errno; }else if ( cmd == F_GETLK && flock.l_type != F_UNLCK){ result = EACCES; } } return report(result, tt);}static inttest(int num, int sec, int func, off_t offset, off_t length, int pass, int fail){ struct test_task tt ; tt.num = num; tt.sec = sec; tt.func = func; tt.offset = offset; tt.length = length; tt.pass = pass; tt.fail = fail; return do_test(&tt); }static int waitnotice(void) { int numbytes; char buf; if ((numbytes = recv(gi.sockfd, &buf, 1, 0)) == -1){ perror("recv"); close(gi.sockfd); exit(1); } else if (numbytes == 0){ output("socket broken\n"); exit(1); } return 0;}static intsendnotice(void){ int numbytes; char buf; if ((numbytes = send(gi.sockfd, &buf, 1, 0)) == -1){ perror("send"); close(gi.sockfd); exit(1); } return 0; }#if 0static int send_msg(void* msg, int len){ if (send(gi.sockfd, msg, len, 0) != len){ perror("send"); close(gi.sockfd); exit(1); } return 0;}static intrecv_msg(void* buf, int len){ int numbytes = 0; while (len > 0 ){ if (( numbytes = recv(gi.sockfd, buf, len, 0)) == -1){ perror("recv"); close(gi.sockfd); exit(1); } len -= numbytes; } return 0;}#endifstatic voidinit_comm(const char* servername){ struct sockaddr_in their_addr; int sin_size; if (gi.clientID == 0 ){ int sockfd; struct sockaddr_in my_addr; int yes = 1; if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ perror("socket"); exit(1); } my_addr.sin_family = AF_INET; my_addr.sin_port = htons(MYPORT); my_addr.sin_addr.s_addr = INADDR_ANY; memset(&(my_addr.sin_zero), '\0', 8); if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) { perror("setsockopt"); exit(1); } if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1){ perror("bind"); exit(1); } if (listen(sockfd, 10) == -1){ perror("listen"); exit(1); } sin_size = sizeof(their_addr); if(( gi.sockfd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) { perror("accept"); exit(1); } close(sockfd); } else{ struct hostent *he; if (!servername){ printf("servername is NULL\n"); exit(1); } if ((he=gethostbyname(servername)) == NULL){ output("gethostbyname: Error, servername =%s \n", servername); exit(1); } if(( gi.sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ perror("socket"); exit(1); } their_addr.sin_family = AF_INET; their_addr.sin_port = htons(MYPORT); memcpy(&their_addr.sin_addr, he->h_addr, sizeof(struct in_addr)); memset(&(their_addr.sin_zero), '\0', 8); if(connect(gi.sockfd, (struct sockaddr *) &their_addr, sizeof(struct sockaddr)) == -1){ perror("connect"); exit(1); } }}static GSList * generate_task_list(void){ GSList* task_list = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -