Welcome to mirror list, hosted at ThFree Co, Russian Federation.

semihost-sys_open.c « riscv « libgloss - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 22f1d8206f4fe716d5be37006b8894e93d0f81e3 (plain)
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
/*
 * Copyright (C) 2020 Embecosm Limited
 * SPDX-License-Identifier: BSD-2-Clause
 */
#include <machine/syscall.h>
#include "semihost_syscall.h"
#include "semihost_fdtable.h"
#include <errno.h>
#include <string.h>
#include <fcntl.h>

extern int errno;

#define SEMIHOST_MODE_R 0
#define SEMIHOST_MODE_RPLUS 2
#define SEMIHOST_MODE_W 4
#define SEMIHOST_MODE_WPLUS 6
#define SEMIHOST_MODE_A 8
#define SEMIHOST_MODE_APLUS 10

/* Open a file.  */
int
_open (const char *name, int flags, ...)
{
  int fh;
  int mode;
  long data_block[3];

  /* Work out mode from flags.  */
  if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY)
    mode = SEMIHOST_MODE_R;
  else if ((flags & (O_WRONLY | O_CREAT | O_TRUNC))
	   == (O_WRONLY | O_CREAT | O_TRUNC))
    mode = SEMIHOST_MODE_W;
  else if ((flags & (O_WRONLY | O_CREAT | O_APPEND))
	   == (O_WRONLY | O_CREAT | O_APPEND))
    mode = SEMIHOST_MODE_A;
  else if ((flags & (O_RDWR | O_CREAT | O_TRUNC))
	   == (O_RDWR | O_CREAT | O_TRUNC))
    mode = SEMIHOST_MODE_WPLUS;
  else if ((flags & (O_RDWR | O_CREAT | O_APPEND))
	   == (O_RDWR | O_CREAT | O_APPEND))
    mode = SEMIHOST_MODE_APLUS;
  else if (flags & O_RDWR)
    mode = SEMIHOST_MODE_RPLUS;
  else
    {
      errno = EINVAL;
      return -1;
    }

  data_block[0] = (long) name;
  data_block[1] = mode;
  data_block[2] = strlen (name);
  fh = syscall_errno (SEMIHOST_open, data_block);
  /* Failed to open file.  */
  if (fh == -1)
    return -1;

  /* Register the file in the fdtable.  */
  return __add_fdentry (fh);
}