63 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			63 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * 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);
 | |
| }
 |