File: file_locking_wait6.c

package info (click to toggle)
valgrind 1%3A3.24.0-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 176,332 kB
  • sloc: ansic: 795,029; exp: 26,134; xml: 23,472; asm: 14,393; cpp: 9,397; makefile: 7,464; sh: 6,122; perl: 5,446; python: 1,498; javascript: 981; awk: 166; csh: 1
file content (130 lines) | stat: -rw-r--r-- 2,403 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
 * Version of same in parent directory using wait6
 */


#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include "tests/sys_mman.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/signal.h>
#include <unistd.h>


/** Lock an entire file exclusively.
 *
 *  @return 1 upon success, 0 upon failure.
 */
static int lock_file(const int fd)
{
  struct flock fl;

  fl.l_type   = F_WRLCK;  /* exclusive lock */
  fl.l_whence = SEEK_SET;
  fl.l_start  = 0;
  fl.l_len    = 0;        /* lock entire file */
  fl.l_pid    = 0;
  return fcntl(fd, F_SETLK, &fl) >= 0;
}

static int open_lock_and_map(const char* const process_name,
                             const char* const filename)
{
  int fd;
  int flags;

  fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  if (fd < 0)
  {
    perror("open");
    goto err1;
  }

  flags = fcntl(fd, F_GETFD);
  assert(flags >= 0);
  if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
    assert(0);

  fprintf(stderr, "%s: about to lock file for writing.\n", process_name);
  if (! lock_file(fd))
  {
    perror("fcntl");
    goto err2;
  }

  fprintf(stderr, "%s: file locking attempt succeeded.\n", process_name);
  if (mmap(NULL, 1, PROT_WRITE, MAP_SHARED, fd, 0) == 0)
  {
    perror("mmap");
    goto err2;
  }

  goto out;

err2:
  close(fd);
err1:
out:
  return fd;
}

int main(int argc, char *argv[])
{
  int fd1;
  int fd2;
  int exitcode = 1;
  char filename[256];

  snprintf(filename, sizeof(filename), "/tmp/valgrind-file-locking-test.%ld",
           (long) getpid());

  unlink(filename);

  if ((fd1 = open_lock_and_map("parent", filename)) >= 0)
  {
    pid_t fork_result;

    fork_result = fork();
    switch (fork_result)
    {
    case -1:
      perror("fork");
      break;

    case 0:
      /* child */
      fd2 = open_lock_and_map("child", filename);
      if (fd2 >= 0)
      {
        close(fd2);
      }
      exit(0);
      break;

    default:
      /* parent */
      {
        int child_status;
        int wait_result;
        struct __wrusage wrusage;
        siginfo_t info;
        wait_result = wait6(P_PID, fork_result, &child_status, WEXITED, &wrusage, &info);
        assert(wait_result >= 0);
      }
    }
  }

  close(fd1);

  unlink(filename);

  fprintf(stderr, "Test finished.\n");

  return exitcode;
}