···2424extern int sprintf(char *str, const char *format, ...);
2525long sys_readlink(const char* path, char* buf, unsigned long bsize);
26262727+static short int flock_type_linux_to_bsd(short int linux) {
2828+ switch (linux) {
2929+ case LINUX_F_RDLCK: return F_RDLCK;
3030+ case LINUX_F_WRLCK: return F_WRLCK;
3131+ case LINUX_F_UNLCK: return F_UNLCK;
3232+ default: return -1;
3333+ };
3434+};
3535+3636+static short int flock_type_bsd_to_linux(short int bsd) {
3737+ switch (bsd) {
3838+ case F_RDLCK: return LINUX_F_RDLCK;
3939+ case F_WRLCK: return LINUX_F_WRLCK;
4040+ case F_UNLCK: return LINUX_F_UNLCK;
4141+ default: return -1;
4242+ };
4343+};
4444+4545+static int cmd_bsd_to_linux(int bsd) {
4646+ switch (bsd) {
4747+ case F_DUPFD: return LINUX_F_DUPFD;
4848+ case F_GETFD: return LINUX_F_GETFD;
4949+ case F_SETFD: return LINUX_F_SETFD;
5050+ case F_GETFL: return LINUX_F_GETFL;
5151+ case F_SETFL: return LINUX_F_SETFL;
5252+ case F_GETOWN: return LINUX_F_GETOWN;
5353+ case F_SETOWN: return LINUX_F_SETOWN;
5454+ case F_SETLK: return LINUX_F_SETLK;
5555+ case F_SETLKW: return LINUX_F_SETLKW;
5656+ case F_GETLK: return LINUX_F_GETLK;
5757+ default: return -1;
5858+ };
5959+};
6060+2761long sys_fcntl(int fd, int cmd, long arg)
2862{
2963 CANCELATION_POINT();
···32663367long sys_fcntl_nocancel(int fd, int cmd, long arg)
3468{
3535- int ret, linux_cmd;
6969+ int ret, linux_cmd = cmd_bsd_to_linux(cmd);
7070+ long original_arg = arg;
36713772 switch (cmd)
3873 {
3974 case F_CHECK_LV:
4075 return 0;
4141- case F_DUPFD:
4242- linux_cmd = LINUX_F_DUPFD;
4343- break;
4444- case F_GETFD:
4545- linux_cmd = LINUX_F_GETFD;
4646- break;
4776 case F_SETFD:
4848- linux_cmd = LINUX_F_SETFD;
4949-5077 if (arg & ~FD_CLOEXEC)
5178 return -EINVAL;
5279 break;
5353- case F_GETFL:
5454- linux_cmd = LINUX_F_GETFL;
5555- break;
5680 case F_SETFL:
5757- linux_cmd = LINUX_F_SETFL;
5881 arg = oflags_bsd_to_linux(arg);
5982 break;
6060- case F_GETOWN:
6161- linux_cmd = LINUX_F_GETOWN;
6262- break;
6363- case F_SETOWN:
6464- linux_cmd = LINUX_F_SETOWN;
6565- break;
6683 case F_GETPATH:
6784 {
6885 ret = fdpath(fd, arg, MAXPATHLEN);
···7390 }
7491 case F_SETLK:
7592 case F_SETLKW:
7676- case F_GETLK:
7777- // TODO
7878- return 0;
9393+ case F_GETLK: {
9494+ struct bsd_flock* bsd_struct = arg;
9595+ struct linux_flock* linux_struct = __builtin_alloca(sizeof(struct linux_flock));
9696+ linux_struct->l_type = flock_type_bsd_to_linux(bsd_struct->l_type);
9797+ linux_struct->l_whence = bsd_struct->l_whence;
9898+ linux_struct->l_start = bsd_struct->l_start;
9999+ linux_struct->l_len = bsd_struct->l_len;
100100+ linux_struct->l_pid = bsd_struct->l_pid;
101101+ arg = linux_struct;
102102+ } break;
79103 case F_FULLFSYNC: {
80104 ret = LINUX_SYSCALL1(__NR_fsync, fd);
81105 if (ret < 0)
···84108 };
85109 // TODO: implement remaining commands
86110 default:
8787- return -EINVAL;
111111+ if (linux_cmd == -1)
112112+ return -EINVAL;
88113 }
8911490115#ifdef __NR_fcntl64
···103128 case F_GETFL:
104129 ret = oflags_linux_to_bsd(ret);
105130 break;
131131+ case F_SETLK:
132132+ case F_SETLKW:
133133+ case F_GETLK: {
134134+ struct bsd_flock* bsd_struct = original_arg;
135135+ struct linux_flock* linux_struct = arg;
136136+ bsd_struct->l_type = flock_type_linux_to_bsd(linux_struct->l_type);
137137+ bsd_struct->l_whence = linux_struct->l_whence;
138138+ bsd_struct->l_start = linux_struct->l_start;
139139+ bsd_struct->l_len = linux_struct->l_len;
140140+ bsd_struct->l_pid = linux_struct->l_pid;
141141+ } break;
106142 }
107143108144 return ret;
+16
src/kernel/emulation/linux/fcntl/fcntl.h
···6464# define FD_CLOEXEC 1
6565#endif
66666767+struct bsd_flock {
6868+ long long l_start;
6969+ long long l_len;
7070+ int l_pid;
7171+ short l_type;
7272+ short l_whence;
7373+};
7474+7575+struct linux_flock {
7676+ short int l_type;
7777+ short int l_whence;
7878+ long int l_start;
7979+ long int l_len;
8080+ int l_pid;
8181+};
8282+6783#endif
6884