summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/sdl/sdlptty_unix.c
blob: 6b618314d72665b2b8439ac65496ce2b1123a5fa (plain) (blame)
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert, R. Belmont
//============================================================
//
//  sdlptty_unix.c - SDL pseudo tty access functions
//
//  SDLMAME by Olivier Galibert and R. Belmont
//
//============================================================

#if (!defined(SDLMAME_SOLARIS) && !(defined(SDLMAME_OS2)))

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#if defined(SDLMAME_FREEBSD) || defined(SDLMAME_DRAGONFLY)
# include <termios.h>
# include <libutil.h>
#elif defined(SDLMAME_NETBSD) || defined(SDLMAME_MACOSX)
# include <util.h>
#elif defined(SDLMAME_OPENBSD)
# include <termios.h>
# include <util.h>
#elif defined(SDLMAME_LINUX) || defined(SDLMAME_EMSCRIPTEN)
# include <pty.h>
#elif defined(SDLMAME_HAIKU)
# include <bsd/pty.h>
#endif
#include <stdlib.h>

#include "sdlfile.h"

#if defined(SDLMAME_MACOSX)
const char *sdlfile_ptty_identifier  = "/dev/pty";
#else
const char *sdlfile_ptty_identifier  = "/dev/pts";
#endif

file_error sdl_open_ptty(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize)
{
        int master;
        int aslave;
        struct termios tios;
        int oldflags;

        memset(&tios , 0 , sizeof(tios));
        cfmakeraw(&tios);

        if (openpty(&master, &aslave, NULL, &tios, NULL) >= 0)
        {
                oldflags = fcntl(master, F_GETFL, 0);
                if (oldflags == -1) {
                        close(master);
                        return FILERR_FAILURE;
                }

                fcntl(master, F_SETFL, oldflags | O_NONBLOCK);
                close(aslave);
                (*file)->handle = master;
                *filesize = 0;
        }
        else
        {
                return FILERR_ACCESS_DENIED;
        }

        return FILERR_NONE;
}

file_error sdl_read_ptty(osd_file *file, void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
{
        ssize_t result;

        result = read(file->handle, buffer, count);

        if (result < 0)
        {
                return error_to_file_error(errno);
        }

        if (actual != NULL )
        {
                *actual = result;
        }

        return FILERR_NONE;
}

file_error sdl_write_ptty(osd_file *file, const void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
{
        ssize_t result;
        result = write(file->handle, buffer, count);

        if (result < 0)
        {
                return error_to_file_error(errno);
        }

        if (actual != NULL )
        {
                *actual = result;
        }

        return FILERR_NONE;
}

file_error sdl_close_ptty(osd_file *file)
{
        close(file->handle);
        osd_free(file);

        return FILERR_NONE;
}

file_error sdl_slave_name_ptty(osd_file *file , char *name , size_t name_len)
{
        const char *slave_name = ptsname(file->handle);

        if (slave_name == NULL || strlen(slave_name) >= name_len) {
                return FILERR_INVALID_ACCESS;
        }

        strcpy(name , slave_name);

        return FILERR_NONE;
}

#else
#include "sdlfile.h"

const char *sdlfile_ptty_identifier  = "";

file_error sdl_open_ptty(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize)
{
        return FILERR_ACCESS_DENIED;
}

file_error sdl_read_ptty(osd_file *file, void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
{
        return FILERR_ACCESS_DENIED;
}

file_error sdl_write_ptty(osd_file *file, const void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
{
        return FILERR_ACCESS_DENIED;
}

file_error sdl_close_ptty(osd_file *file)
{
        return FILERR_ACCESS_DENIED;
}

file_error sdl_slave_name_ptty(osd_file *file)
{
        return FILERR_ACCESS_DENIED;
}

#endif