Advertisement
Guest User

Untitled

a guest
Apr 28th, 2015
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.03 KB | None | 0 0
  1. /*
  2. * randline.c - shows N lines with random number from choosen file
  3. *
  4. * COMPILE: gcc -lm -Wall -Werror -Wextra randline.c -o randline
  5. *
  6. * Copyright 2014 Edward V. Emelianoff <eddy@sao.ru>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  21. * MA 02110-1301, USA.
  22. */
  23.  
  24. #include <sys/stat.h>
  25. #include <fcntl.h>
  26. #include <sys/mman.h>
  27. #include <unistd.h>
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <sys/time.h>
  32. #include <limits.h>
  33. #include <math.h>
  34. #include <stddef.h>
  35.  
  36. #define ERR(...) do{fprintf(stderr, __VA_ARGS__); return NULL;}while(0)
  37. #define _(s) s
  38. #define MALLOC(type, size) ((type *)my_alloc(size, sizeof(type)))
  39.  
  40. // mmap file
  41. typedef struct{
  42. char *data;
  43. size_t len;
  44. } mmapbuf;
  45.  
  46. /**
  47. * function for different purposes that need to know time intervals
  48. * @return double value: time in seconds
  49. */
  50. double dtime(){
  51. double t;
  52. struct timeval tv;
  53. gettimeofday(&tv, NULL);
  54. t = tv.tv_sec + ((double)tv.tv_usec)/1e6;
  55. return t;
  56. }
  57. /*
  58. * Generate a quasy-random number to initialize PRNG
  59. * name: throw_random_seed
  60. * @return value for srand48
  61. */
  62. long throw_random_seed(){
  63. long r_ini;
  64. int fail = 0;
  65. int fd = open("/dev/random", O_RDONLY);
  66. do{
  67. if(-1 == fd){
  68. perror(_("Can't open /dev/random"));
  69. fail = 1; break;
  70. }
  71. if(sizeof(long) != read(fd, &r_ini, sizeof(long))){
  72. perror(_("Can't read /dev/random"));
  73. fail = 1;
  74. }
  75. close(fd);
  76. }while(0);
  77. if(fail){
  78. double tt = dtime() * 1e6;
  79. double mx = (double)LONG_MAX;
  80. r_ini = (long)(tt - mx * floor(tt/mx));
  81. }
  82. return (r_ini);
  83. }
  84.  
  85.  
  86. void* my_alloc(size_t N, size_t S){
  87. void *p = calloc(N, S);
  88. if(!p){
  89. perror(_("can't allocate memory"));
  90. exit(-1);
  91. }
  92. return p;
  93. }
  94. /**
  95. * Mmap file to a memory area
  96. *
  97. * @param filename (i) - name of file to mmap
  98. * @return stuct with mmap'ed file or die
  99. */
  100. mmapbuf *My_mmap(char *filename){
  101. int fd;
  102. char *ptr;
  103. size_t Mlen;
  104. struct stat statbuf;
  105. if(!filename) ERR(_("No filename given!"));
  106. if((fd = open(filename, O_RDONLY)) < 0)
  107. ERR(_("Can't open %s for reading"), filename);
  108. if(fstat (fd, &statbuf) < 0)
  109. ERR(_("Can't stat %s"), filename);
  110. Mlen = statbuf.st_size;
  111. if((ptr = mmap (0, Mlen, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
  112. ERR(_("Mmap error for input"));
  113. if(close(fd)) ERR(_("Can't close mmap'ed file"));
  114. mmapbuf *ret = MALLOC(mmapbuf, 1);
  115. ret->data = ptr;
  116. ret->len = Mlen;
  117. return ret;
  118. }
  119.  
  120. void My_munmap(mmapbuf *b){
  121. if(munmap(b->data, b->len))
  122. fprintf(stderr, _("Can't munmap"));
  123. free(b);
  124. b = NULL;
  125. }
  126.  
  127. int main(int argc, char **argv){
  128. char *endptr, *buf, *startptr;
  129. mmapbuf *mbuf;
  130. ptrdiff_t MAX;
  131. size_t N_strings;
  132. void usage(){
  133. fprintf(stderr, _("USAGE: %s filename Nlines\n"), argv[0]);
  134. }
  135. if(argc != 3){
  136. usage();
  137. return -1;
  138. }
  139. if(!(mbuf = My_mmap(argv[1]))) return -2;
  140. MAX = mbuf->len;
  141. buf = mbuf->data;
  142. N_strings = strtol(argv[2], &endptr, 0);
  143. if(endptr == argv[2] || *endptr != '\0'){
  144. usage();
  145. return -3;
  146. }
  147. srand48(throw_random_seed());
  148. while(N_strings--){
  149. size_t R = lrand48() % MAX;
  150. startptr = strchr(buf+R, '\n');
  151. if(!startptr || ((++startptr-buf) >= MAX)){
  152. N_strings++;
  153. continue;
  154. }
  155. endptr = strchr(startptr, '\n');
  156. if(!endptr || endptr <= startptr){
  157. N_strings++;
  158. continue;
  159. }
  160. write(1, startptr, endptr-startptr);
  161. write(1, "\n", 1);
  162. }
  163. My_munmap(mbuf);
  164. return 0;
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement